myBatis-XML和註解
參考:
https://www.cnblogs.com/lyc-smile/p/9055856.html
https://ld246.com/article/1488810828678
Mybatis之XML、註解的使用
前言
上篇簡單介紹了Mybatis的簡單實用,本篇先對上次實驗環境的一些內容進行優化,然後驗證Mybatis的XML配置以及註解方式。
實驗環境優化
資料庫配置
在mybatis的配置檔案中,引入資料庫配置檔案db.properties,然後修改配置檔案
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/mybatis name=root password=admin
mybatis配置檔案mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 資料庫配置檔案 --> <properties resource="db.properties"/> <!-- development : 開發模式 work : 工作模式 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${name}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/lion/mapper/UserMapper.xml" /> </mappers> </configuration>
實體類定義別名
沒有為實體定義別名時,在sql對映xml中應用實體時,比如parameterType resultType 中就需要配置實體的全路徑名(全限定名)。
當為實體定義了別名後,對映檔案中可以直接配置實體的別名即可。因此為實體類定義別名,可以簡化Sql對映xml檔案中對實體的引用配置。
mybatis配置檔案中<typeAlises>定義實體別名有兩種方式:
- typeAlias 單個為每個實體定義別名 當實體類比較多是 配置增多 不方便
- package 指定實體的包 會自動為改包下的所有實體自動設定各自的類名為別名
優化後的Mybatis配置檔案mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 資料庫配置檔案 --> <properties resource="db.properties"/> <!-- 配置實體的別名 --> <typeAliases> <!-- 此種方式是分別為每一個實體設定別名 mapper xml 中resultType即為alias的值--> <!-- <typeAlias type="com.lion.pojo.User" alias="_User"/> --> <!-- package 設定別名的方式會自動為該包下的所有JavaBean設定別名為其類名稱 --> <package name="com.lion.pojo"/> </typeAliases> <!-- development : 開發模式 work : 工作模式 --> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${driver}" /> <property name="url" value="${url}" /> <property name="username" value="${name}" /> <property name="password" value="${password}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/lion/mapper/UserMapper.xml" /> </mappers> </configuration>
Mybatis實現方式
分別使用XML和註解的方式實現對User的CURD。
XML方式
sql中引數定義為 #{} 在Mybatis配置檔案中已經配置對實體類的自動設定別名,因此此處可以直接使用實體類的別名進行引用。
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.lion.mapper.UserMapper"> <select id="selectUser" parameterType="int" resultType="User"> select * from users where id = #{id} </select> <delete id="deleteUser" parameterType="int"> delete from users where id = #{id} </delete> <update id="updateUser" parameterType="User"> update users set name = #{name},age = #{age} where id = #{id} </update> <insert id="addUser" parameterType="User"> insert into users(name,age) values(#{name},#{age}) </insert> <select id="selectAll" resultType="User" > select * from users </select> </mapper>
1 package com.lion.test; 2 3 import java.io.IOException; 4 import java.util.List; 5 6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.junit.Test; 9 10 import com.lion.pojo.User; 11 import com.lion.util.MybatisUtils; 12 13 public class TestUserCURDByXML { 14 15 @Test 16 public void testAdd() { 17 try { 18 SqlSessionFactory factory = MybatisUtils.getFactory(); 19 SqlSession session = factory.openSession(); 20 21 String statement = "com.lion.mapper.UserMapper.addUser"; 22 // id mysql設定的自增長 此處設為 -1 23 User user = new User(-1, "Spring", 25); 24 session.insert(statement, user); 25 26 // 不提交的話 資料無法提交到資料庫 27 session.commit(); 28 session.close(); 29 } catch (IOException e) { 30 e.printStackTrace(); 31 } 32 } 33 34 @Test 35 public void testDelete() { 36 try { 37 SqlSessionFactory factory = MybatisUtils.getFactory(); 38 // 自動提交事務 39 SqlSession session = factory.openSession(true); 40 41 String statement = "com.lion.mapper.UserMapper.deleteUser"; 42 session.delete(statement, 4); 43 44 session.close(); 45 } catch (IOException e) { 46 e.printStackTrace(); 47 } 48 } 49 50 @Test 51 public void testUpdate() { 52 try { 53 SqlSessionFactory factory = MybatisUtils.getFactory(); 54 // 自動提交事務 55 SqlSession session = factory.openSession(true); 56 57 String statement = "com.lion.mapper.UserMapper.updateUser"; 58 User user = new User(1, "mali", 18); 59 session.update(statement, user); 60 61 session.close(); 62 } catch (IOException e) { 63 e.printStackTrace(); 64 } 65 } 66 67 @Test 68 public void testSelect() { 69 try { 70 SqlSessionFactory factory = MybatisUtils.getFactory(); 71 // 自動提交事務 72 SqlSession session = factory.openSession(true); 73 74 String statement = "com.lion.mapper.UserMapper.selectAll"; 75 List<User> users = session.selectList(statement); 76 for (User user : users) { 77 System.out.println(user); 78 } 79 80 session.close(); 81 } catch (IOException e) { 82 e.printStackTrace(); 83 } 84 } 85 86 }
註解方式
package com.lion.testAnnotation; import java.util.List; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import com.lion.pojo.User; public interface UserMapper { @Insert("insert into users(name,age) values(#{name},#{age})") int insertUser(User user); @Delete("delete from users where id = #{id}") int deleteUser(int id); @Update("update users set name = #{name},age = #{age} where id = #{id}") int updateUser(User user); @Select("select * from users where id = #{id}") User selectUser(int id); @Select("select * from users") List<User> selectAll(); }
Mybatis配置檔案中註冊對映介面 class
<mappers> <mapper resource="com/lion/mapper/UserMapper.xml" /> <mapper class="com.lion.testAnnotation.UserMapper"/> </mappers>
針對同一實體的對映檔案不能放到同一個包中。
1 package com.lion.testAnnotation; 2 3 import java.io.IOException; 4 import java.util.List; 5 6 import org.apache.ibatis.session.SqlSession; 7 import org.apache.ibatis.session.SqlSessionFactory; 8 import org.junit.Before; 9 import org.junit.Test; 10 11 import com.lion.pojo.User; 12 import com.lion.util.MybatisUtils; 13 14 public class TestUserCURDByAnnotaion2 { 15 16 private SqlSessionFactory factory; 17 18 @Before 19 public void loadFactory() { 20 try { 21 factory = MybatisUtils.getFactory(); 22 } catch (IOException e) { 23 e.printStackTrace(); 24 } 25 } 26 27 @Test 28 public void testAdd() { 29 SqlSession session = factory.openSession(true); 30 // 對映器 31 UserMapper mapper = session.getMapper(UserMapper.class); 32 33 int i = mapper.insertUser(new User(-1, "xiazis", 24)); 34 35 System.out.println(i); 36 37 session.close(); 38 39 } 40 41 @Test 42 public void testDelete() { 43 SqlSession session = factory.openSession(true); 44 // 對映器 45 UserMapper mapper = session.getMapper(UserMapper.class); 46 47 int i = mapper.deleteUser(1); 48 49 System.out.println(i); 50 51 session.close(); 52 53 } 54 55 @Test 56 public void testUpdate() { 57 SqlSession session = factory.openSession(true); 58 // 對映器 59 UserMapper mapper = session.getMapper(UserMapper.class); 60 61 int i = mapper.updateUser(new User()); 62 63 System.out.println(i); 64 65 session.close(); 66 67 } 68 69 @Test 70 public void testSelect() { 71 SqlSession session = factory.openSession(true); 72 // 對映器 73 UserMapper mapper = session.getMapper(UserMapper.class); 74 75 User user = mapper.selectUser(2); 76 77 System.out.println(user); 78 79 session.close(); 80 81 } 82 83 @Test 84 public void testSelectAll() { 85 SqlSession session = factory.openSession(true); 86 // 對映器 87 UserMapper mapper = session.getMapper(UserMapper.class); 88 89 List<User> users = mapper.selectAll(); 90 91 for (User user : users) { 92 System.out.println(user); 93 } 94 95 session.close(); 96 97 } 98 99 }
MyBatis 用註解好還是用 XML 好?
MyBatis 支援註解 SQL 語句,如:
package com.iandtop.jxy.mapper;
import com.iandtop.saas.smartpark.vo.UserVO;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author andyzhao
*/
@Mapper
public interface LoginMapper {
@Select("select count(*) from sm_user")
Integer retrieveAllCount() throws RuntimeException;
@Select("select * from sm_user WHERE user_password = #{password} and user_code = #{code}")
List<UserVO> retrieveByCodeAndPwd(@Param("code") String code, @Param("password") String password) throws RuntimeException;
@Select("select * from sm_user WHERE user_code = #{code}")
List<UserVO> retrieveByCode(@Param("code") String code) throws RuntimeException;
@Select("SELECT * FROM SM_USER WHERE pk_user = #{pk_user}")
UserVO findByPK(@Param("pk_user") String pk_user);
}
但是常用的還是 XML 方式,比如:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.iandtop.jxy.mapper.LoginMapper"> <select id="retrieveAllCount" resultType="java.lang.Integer"> select count(*) from sm_user </select> <select id="retrieveByCodeAndPwd" resultType="com.iandtop.saas.smartpark.vo.UserVO"> select * from sm_user WHERE user_password = #{password} and user_code = #{code} </select> <select id="retrieveByCode" resultType="com.iandtop.saas.smartpark.vo.UserVO"> select * from sm_user WHERE user_code = #{code} </select> </mapper> 作者:haihai 連結:https://ld246.com/article/1488810828678 來源:鏈滴 協議:CC BY-SA 4.0 https://creativecommons.org/licenses/by-sa/4.0/
到底選哪一種呢?我選 XML:
- 首先官方也是推薦使用 XML
- 註解方式拼接動態 SQL 功能有限
- Java 又和 SQL 搞到一起了感覺很不爽
網上有說“按需使用",大致意思就是說如果”複雜“就用 XML,剩下的就用註解。那為什麼這麼複雜,幹嘛不乾脆用 XML 就得了?
網上有說“註解和 xml 的一起使用”,大致就是一個工程一會用註解一會用 XML。那為什麼這麼複雜,幹嘛不乾脆用 XML 就得了?
總結:
- 註解也許有很多優點,但是哪位同胞可以好心告訴我下?
- Java 各個框架太多,能簡潔幹嘛要複雜?我就奇了怪了。如果整天只是滿腦子的各種框架的使用和配置方法那真是弱爆了。