一、註意規範 註意:(1).XXXmapper.xml 文件中的 namespace 等於mapper 介面地址 (2).XXXmapper.java 介面中的方法輸入參數和 mapper.xml 中statement的parameterType指定的 類型一致。 (3) .mapper.java ...
一、註意規範
註意:(1).XXXmapper.xml 文件中的 namespace 等於mapper 介面地址
(2).XXXmapper.java 介面中的方法輸入參數和 mapper.xml 中statement的parameterType指定的 類型一致。
(3) .mapper.java 介面中的方法的返回值類型和mapper.xml中statement的resultType指定的類型一致
二、配置文件及標簽介紹
1. properties 介紹
可以將數據連接單獨配置在 db.properties 中改善硬編碼,其他配置文件引用該文件。內容示例:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatis jdbc.username=root jdbc.password=root
2.核心配置 SqlMapConfig.xml 標簽介紹
標簽種類:
1. properties(屬性)
<!-- 載入資料庫文件db.properties -->
<properties resource="db.properties">
<!--
properties中還可以配置一些屬性名和屬性值,此處的優先載入
讀取完此標簽內再讀取其他文件。如果有同名屬性,則會被讀取文件中的覆蓋
-->
<!-- <property name="driver" value=""/> -->
</properties>
2. settings(全局配置參數): 可以調整一些運行參數:開啟二級緩存、開啟延遲載入等。會影響mybatis的運動行為
3. typeAiases(類型別名):指定輸入輸出類型較不方便,可以針對 parameterType、resourceType 指定的類型定義一些別名
3.1 預設支持的別名
別名 | _byte | _long | _short | _int | _integer | _double | _float | _boolean | string | byte |
類型 | byte | long | short | int | int | doouble | float | boolean | String | Byte |
別名 | long | short | int | integer | double | float | boolean | data | decimal | bigdecimal |
類型 | Long | Short | Integer | Integer | Double | Float | Boolean | Data | BigDecimal | BigDecimal |
3.2 自定義別名
<!-- 針對單個別名定義 type:類型的路徑; alias:別名 --> <typeAliases> <typeAlias type="com.mybatis.entity.User" alias="user"/> </typeAliases> <select id="findUserById" parameterType="int" resultType="user" > select * from t_user where id=#{id} </select> <!-- 批量別名的定義: package:指定包名,mybatis會自動掃描包中的pojo類,自動定義別名,別名就是類名(首字母大寫或小寫都可以) --> <typeAliases> <package name="com.mybatis.entity"/> <package name="其它包"/> </typeAliases>
4. typeHandlers(類型處理器):完成 jdbc 類型和 java 類型的轉換
5. objectFactory(對象工廠)
6. plugins(插件)
7. environments(環境集合屬性對象)mappers(映射器)
7.1 environment (環境子屬性對象)
7.2 transactionManager(事務管理)
7.3 datasource(數據源)
<!-- 和spring整合後 environments配置將廢除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理,事務控制由mybatis管理--> <transactionManager type="JDBC" /> <!-- 資料庫連接池,由mybatis管理--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments>
8.mapper(映射器)
<!-- 載入映射文件 --> <mappers> <!-- 通過resource方法一次載入一個映射文件 --> <mapper resource="sqlmap/User.xml"/> <mapper resource="mapper/UserMapper.xml"/> <!-- 通過mapper介面載入單個映射配置文件 需要將mapper介面類名和mapper.xml映射文件名稱保持一致,且在一個目錄中 --> <mapper class="com.mybatis.mapper.UserMapper"/> <!-- 批量載入映射配置文件,mybatis自動掃描包下麵的mapper介面進行載入 需要將mapper介面類名和mapper.xml映射文件名稱保持一致,且在一個目錄中; 上邊規範的前提是:使用的是mapper代理方法; --> <package name="com.mybatis.mapper"/> </mappers>
三、輸入、輸出 映射
1.輸入映射:通過 parameterType 指定輸入參數的類型,類型可以是簡單類型、hashmap、pojo的包裝類型
如需要查詢的條件較複雜,可以使用自定義的包裝類型 pojo ,將複雜的查詢條件包含進去
1.1 複雜的包裝類 UserQueryVo 示例
public class UserQueryVo { //這裡包裝其它的查詢條件 //用戶查詢條件 private UserCustom userCustom; public UserCustom getUserCustom() { return userCustom; } public void setUserCustom(UserCustom userCustom) { this.userCustom = userCustom; } }
1.2 再複雜一下 UserCustom.java 示例
public class UserCustom extends User{ //可以擴展用戶的信息 }
1.3 配置文件 UserMapper.xml 定義綜合查詢示例
<!-- 模擬包裝類型組合查詢 #{userCustom.sex}:取出pojo包裝對象中性別值 ${userCustom.username}:取出pojo對象中姓名值 --> <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" resultType="com.mybatis.entity.UserCustom"> where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%' </select>
1.4 UserMapper.java 示例
public interface UserMapper { // 用戶信息綜合查詢 public List<UserCustom> findUserList(UserQueryVo userQueryVo); }
1.5 Junit 測試代碼
1 ackage com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在執行findUserByIdTest之前執行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 創建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void testFindUserList() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 //創造查詢條件 36 UserQueryVo userQueryVo = new UserQueryVo(); 37 UserCustom userCustom = new UserCustom(); 38 userCustom.setSex("2"); 39 userCustom.setUsername("小"); 40 userQueryVo.setUserCustom(userCustom); 41 // 創建Usermapper對象,mybatis自動生成mapper代理對象 42 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 43 List<UserCustom>list=mapper.findUserList(userQueryVo); 44 System.out.println(list); 45 sqlSession.commit(); 46 sqlSession.close(); 47 } 48 }UserMapperTest
2.輸出映射:只有查詢出來的列名和pojo中的屬性名一致,該列才可以映射成功
(如果查詢出來的列名和 pojo 中屬性名只要有一個一致,就會創建 pojo 對象,只有全部不一樣才會不創建對象)
2.1 輸出簡單類型:只有輸出的結果只有一行一列才可以使用
2.1.1 UserMapper.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"> <!-- 用戶信息綜合查詢總數 parameterType:指定輸入類型,和findUserList一致。 resultType:輸出結果類型. --> <mapper namespace="com.mybatis.mapper.UserMapper"> <select id="findUserCount" parameterType="com.mybatis.entity.UserQueryVo" resultType="int"> select count(*) from t_user where sex=#{userCustom.sex} and username like '%${userCustom.username}%' </select> </mapper>
2.1.2 UserMapper.java
public interface UserMapper { //用戶信息綜合查詢總數 public int findUserCount(UserQueryVo userQueryVo); }
2.1.3 junit 測試
1 package com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在執行findUserByIdTest之前執行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 創建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void findUserCountTest() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 //創造查詢條件 36 UserQueryVo userQueryVo = new UserQueryVo(); 37 UserCustom userCustom = new UserCustom(); 38 userCustom.setSex("2"); 39 userCustom.setUsername("小"); 40 userQueryVo.setUserCustom(userCustom); 41 // 創建Usermapper對象,mybatis自動生成mapper代理對象 42 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 43 int count=mapper.findUserCount(userQueryVo); 44 System.out.println(count); 45 sqlSession.commit(); 46 sqlSession.close(); 47 } 48 }UserMapperTest
2.2 輸出 pojo 對象和 pojo 列表:單個或列表,在 mapperType 類型是一樣的,在 mapper.java 中返回值不一樣
2.2.1 方法返回值區別示例
public interface UserMapper { /** 根據ID查詢用戶信息 */ // 返回單個 public User findUserById(int id); /** 根據用戶名稱模糊查詢用戶信息 */ // 返回列表 public List<User> findUserByName(String username); }
2.2.2 使用 resoultMap 作為輸出映射類型
定義 resoultMap
<?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"> <!-- namespace命名空間,作用就是對sql進行分類化的管理,理解為sql隔離 註意:使用mapper代理開發時,namespace有特殊作用,namespace等於mapper介面地址 --> <!-- 用戶信息綜合查詢總數 parameterType:指定輸入類型,和findUserList一致。 resultType:輸出結果類型. --> <mapper namespace="com.mybatis.mapper.UserMapper"> <!-- 定義resultMap select id id_,username username_ from t_user和User類中的屬性作為一個映射關係 type:resultMap最終映射的java對象類型,可以使用別名; id:對resultMap的唯一標識 --> <resultMap type="user" id="userResultMap"> <!--id表示查詢結果中的唯一標識, column:查詢出來的列名 property:type指定的pojo類型中的屬性名 最終resultMap對column和property作一個映射關係(對應關係) --> <id column="id_" property="id"/> <!--result:表示對普通列名的映射, column:查詢出來的列名 property:type指定的pojo類型中的屬性名 最終resultMap對column和property作一個映射關係(對應關係) --> <result column="username_" property="username"/> </resultMap> </mapper>
使用 resoultMap
<!-- 使用resultMap作為輸出映射 resultMap:指定定義的resultMap的id,如果這個resultMap在其它的mapper.xml文件中,前邊需要添加namespace命名空間 --> <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap" > select id id_,username username_ from t_user where id=#{id} </select>
UserMapper.java示例
public interface UserMapper { /** 根據ID查詢用戶信息,使用resultMap進行輸出 */ public User findUserByIdResultMap(int id); }
Junit 測試示例
1 package com.mybatis.dao.test; 2 3 import java.io.InputStream; 4 import java.util.Date; 5 import java.util.List; 6 7 import org.apache.ibatis.io.Resources; 8 import org.apache.ibatis.session.SqlSession; 9 import org.apache.ibatis.session.SqlSessionFactory; 10 import org.apache.ibatis.session.SqlSessionFactoryBuilder; 11 import org.junit.Before; 12 import org.junit.Test; 13 14 import com.mybatis.entity.User; 15 import com.mybatis.entity.UserCustom; 16 import com.mybatis.entity.UserQueryVo; 17 import com.mybatis.mapper.UserMapper; 18 19 public class UserMapperTest { 20 21 private SqlSessionFactory sqlSessionFactory; 22 23 // 此方法是在執行findUserByIdTest之前執行 24 @Before 25 public void setUp() throws Exception { 26 String resource = "SqlMapConfig.xml"; 27 InputStream inputStream = Resources.getResourceAsStream(resource); 28 // 創建SqlSessionFcatory 29 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); 30 } 31 32 @Test 33 public void testFindUserByIdResultMap() { 34 SqlSession sqlSession = sqlSessionFactory.openSession(); 35 // 創建Usermapper對象,mybatis自動生成mapper代理對象 36 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 37 User user = mapper.findUserByIdResultMap(1); 38 System.out.println(user); 39 sqlSession.close(); 40 } 41 }UserMapperTest
2.3 用 resultType 進行輸出映射時,只有查詢出來的列名和 pojo 中的屬性名一致,該列才可以映射成功。如果不一致,可以通過定義一個 resultType 對列名和 pojo 屬性名之間作為一個映射關係
四、
1.動態SQL:mybatis核心對sql語句進行靈活操作,通過表達式進行判斷,對SQL進行拼接、組裝
UserMapper.xml、Junit測試代碼示例:
1 <!-- 用戶信息綜合查詢 2 #{userCustom.sex}:取出pojo包裝對象中性別值 3 ${userCustom.username}:取出pojo對象中用戶名稱 4 --> 5 <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" 6 resultType="com.mybatis.entity.UserCustom"> 7 select * from t_user 8 <!-- 動態sql查詢:where可以自動去掉第一個and --> 9 <where> 10 <if test="userCustom!=null"> 11 <if test="userCustom.sex!=null and userCustom.sex!='' "> 12 and sex=#{userCustom.sex} 13 </if> 14 <if test="userCustom.username!=null and userCustom.username!='' "> 15 and username=#{userCustom.username} 16 </if> 17 </if> 18 </where> 19 <!-- where sex=#{userCustom.sex} and username LIKE '%${userCustom.username}%' --> 20 </select>UserMapper.xml
1 @Test 2 public void testFindUserList() { 3 SqlSession sqlSession = sqlSessionFactory.openSession(); 4 //創造查詢條件 5 UserQueryVo userQueryVo = new UserQueryVo(); 6 UserCustom userCustom = new UserCustom(); 7 // userCustom.setSex("2"); 8 //這裡使用動態sql,如果不設置某個值,條件不會拼接sql中 9 userCustom.setUsername("小"); 10 userQueryVo.setUserCustom(userCustom); 11 // 創建Usermapper對象,mybatis自動生成mapper代理對象 12 UserMapper mapper = sqlSession.getMapper(UserMapper.class); 13 List<UserCustom>list=mapper.findUserList(userQueryVo); 14 //測試動態sql,屬性的非空判斷測試 15 // List<UserCustom>list=mapper.findUserList(null); 16 System.out.println(list); 17 sqlSession.commit(); 18 sqlSession.close(); 19 }testFindUserList
2. SQL片段:抽取動態sql,組成一個sql片段,方便重覆調用
2.1 定義sql片段
<!-- 定義sql片段,Id是唯一標識 建議:是基於單表來定義sql片段,這樣的話sql片段的可重用性才高,在sql片段中不要包含where --> <sql id="query_user_where" > <if test="userCustom!=null"> <if test="userCustom.sex!=null and userCustom.sex!='' "> and sex=#{userCustom.sex} </if> <if test="userCustom.username!=null and userCustom.username!='' "> and username=#{userCustom.username} </if> </if> </sql>
2.2 在 mapper.xml 中定義的 statement 中引用sql片段
<!-- 用戶信息綜合查詢 #{userCustom.sex}:取出pojo包裝對象中性別值 ${userCustom.username}:取出pojo對象中用戶名稱 --> <select id="findUserList" parameterType="com.mybatis.entity.UserQueryVo" resultType="com.mybatis.entity.UserCustom"> select * from t_user <!-- 動態sql查詢:where可以自動去掉第一個and --> <where> <!-- 引用sql片段的id,如果refid指定的不在本mapper.xml中,需要前邊加namespace --> <include refid="query_user_where"></include> <!-- 這裡可以引用其它的sql片段 --> </where> </select>
3. foreach:向 sql 傳遞數組或 list 時,mybatis 使用 foreach 解析
3.1 傳入多個id的
1 package com.mybatis.entity; 2 3 import java.util.List; 4 5 /** 6 * 7 * @ClassName: UserQueryVo 8 * @Description: TODO(包裝類型) 9 * @author warcaft 10 * 11 */ 12 public class UserQueryVo { 13 14 public List<Integer> ids; 15 16 public List<Integer> getIds() { 17 return ids; 18 } 19 20 public void setIds(List<Integer> ids) { 21 this.ids = ids; 22 } 23 }UserQueryVo .java
3.2 mapper.xml :實現兩條不同sql示例
1 <!-- 實現下邊的sql拼接 2 select * from t_user where id=1 OR id=2 OR id=3 3 --> 4 <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 5 resultType="com.mybatis.entity.User"> 6 select * from t_user 7 <where> 8 <if test="ids!=null"> 9 <!-- 使用foreach遍歷ids 10 collection:指定輸入對象的集合屬性 11 item:每個遍歷生成對象中 12 open:開始遍歷時拼接的串 13 close:技術遍歷時拼接的串 14 separator:遍歷的兩個對象中需要拼接的串 15 --> 16 <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or"> 17 id=#{user_id} 18 </foreach> 19 </if> 20 </where> 21 </select>mapper.xml
1 <!-- 實現下邊的sql拼接 2 select * from t_user whereid in(1,2,3) 3 --> 4 5 <select id="findUserByIds" parameterType="com.mybatis.entity.UserQueryVo" 6 resultType="com.mybatis.entity.User"> 7 select * from t_user 8 <where> 9 <if test="ids!=null"> 10 <!-- 11 使用foreach遍歷ids 12 collection:指定輸入對象的集合屬性 13 item:每個遍歷生成對象中 14 open:開始遍歷時拼接的串 15 close:技術遍歷時拼接的串 16 sepa