一、輸入映射
parameterType
指定輸入參數的Java類型,可以使用別名或者類的全限定名。它可以接收簡單類型、POJO、HashMap。
1、傳遞簡單類型
根據用戶ID查詢用戶信息:
1
2
3
|
<select id= "findUserById" parameterType= "int" resultType= "com.itheima.mybatis.po.User" > SELECT * FROM USER WHERE id =#{id} </select> |
2、傳遞POJO對象
添加用戶:
1
2
3
4
5
6
|
<insert id= "insertUser" parameterType= "com.itheima.mybatis.po.User" > <selectKey keyProperty= "id" resultType= "int" order= "AFTER" > SELECT LAST_INSERT_ID() </selectKey> INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address}) </insert> |
3、傳遞POJO包裝對象
開發中通過pojo傳遞查詢條件 ,查詢條件是綜合的查詢條件,不僅包括用戶查詢條件還包括其它的查詢條件(比如將用戶購買商品信息也作為查詢條件),
這時可以使用包裝對象傳遞輸入參數。
3.1需求
綜合查詢用戶信息,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息)。
3.2 定義包裝對象
一般User.java類要和數據表表字段一致,最好不要在這里面添加其他字段,在mybatis的逆向工程時,會根據表結構,生成po類,
如果在po類中擴展字段,此時會被覆蓋掉。
所以針對要擴展的po類,我們需要創建一個擴展類,來繼承它。
1
2
3
|
public class UserExt extends User{ //這里可以定義user的一些擴展信息 } |
定義POJO包裝類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
public class UserQueryVO { //用戶信息 private UserExt userExt; //商品ID集合 private List<Integer> idList; //商品信息 public List<Integer> getIdList() { return idList; } public void setIdList(List<Integer> idList) { this .idList = idList; } public UserExt getUserExt() { return userExt; } public void setUserExt(UserExt userExt) { this .userExt = userExt; } //訂單信息 } |
3.3編寫Mapper接口
//通過包裝類來進行復雜的用戶信息綜合查詢
public List<UserExt> findUserList(UserQueryVO userQueryVO);
3.4編寫mapper映射文件
1
2
3
4
|
<!-- 通過包裝類來進行復雜的用戶信息綜合查詢 --> <select id= "findUserList" parameterType= "userQueryVO" resultType= "userExt" > SELECT * FROM USER WHERE sex=#{userExt.sex} AND username LIKE '%${userExt.username}%' </select> |
注意:入參的類型變為UserQueryVO、結果集的類型變為UserExt,#{}里面的參數變為UserQueryVO對象中的userExt屬性的sex和username子屬性。
3.5編寫測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@Test public void findUserListTest() { // 創建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通過SqlSession,獲取mapper接口的動態代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper. class ); //構造userQueryVO對象 UserQueryVO userQueryVO = new UserQueryVO(); // 構造UserExt對象 UserExt userExt = new UserExt(); userExt.setSex( "1" ); userExt.setUsername( "小明" ); userQueryVO.setUserExt(userExt); // 調用mapper對象的方法 List<UserExt> list = userMapper.findUserList(userQueryVO); System.out.println(list); // 關閉SqlSession sqlSession.close(); } |
4、傳遞HashMap
同傳遞POJO對象一樣,map的key相當于pojo的屬性。
4.1映射文件
1
2
3
4
|
<!-- 傳遞hashmap綜合查詢用戶信息 --> <select id= "findUserByHashmap" parameterType= "hashmap" resultType= "user" > select * from user where id=#{<span style= "color:#ff0000;" >id</span>} and username like '%${<span style="color:#ff0000;">username</span>}%' </select> |
上邊紅色標注的id和username是hashmap的key。
4.2測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
Public void testFindUserByHashmap() throws Exception{ //獲取session SqlSession session = sqlSessionFactory.openSession(); //獲限mapper接口實例 UserMapper userMapper = session.getMapper(UserMapper. class ); //構造查詢條件Hashmap對象 HashMap<String, Object> map = new HashMap<String, Object>(); map.put( "id" , 1 ); map.put( "username" , "管理員" ); //傳遞Hashmap對象查詢用戶列表 List<User>list = userMapper.findUserByHashmap(map); //關閉session session.close(); } |
異常測試:
傳遞的map中的key和sql中解析的key不一致。
測試結果沒有報錯,只是通過key獲取值為空。
二、輸出映射
1、resultType
(1)使用方法
使用resultType進行結果映射時,查詢的列名和映射的pojo屬性名完全一致,該列才能映射成功。
如果查詢的列名和映射的pojo屬性名全部不一致,那么映射的對象為空,不會創建pojo對象;
如果查詢的列名和映射的pojo屬性名有一個一致,那么映射的對象不為空,會創建pojo對象,但是只有映射正確的那一個屬性才有值。
(2)輸出簡單類型
注意,對簡單類型的結果映射也是有要求的,查詢的列必須是一列,才能映射為簡單類型。
當輸出結果只有一列時,可以使用ResultType指定簡單類型作為輸出結果類型。
2.1需求
綜合查詢用戶總數,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息)。
2.2Mapper映射文件
1
2
3
4
5
|
<!-- 綜合查詢用戶信息總數,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息) --> <select id= "findUsersCount" parameterType= "UserQueryVO" resultType= "int" > SELECT count( 1 ) FROM USER WHERE sex = #{userExt.sex} AND username LIKE '%${userExt.username}%' </select> |
2.3Mapper接口
1
2
|
//綜合查詢用戶信息總數。學習:resultType輸出簡單類型 public int findUsersCount(UserQueryVO vo); |
2.4測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Test public void testFindUsersCount() { // 創建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通過SqlSession,獲取mapper接口的動態代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper. class ); //構造userQueryVO對象 UserQueryVO userQueryVO = new UserQueryVO(); // 構造UserExt對象 UserExt userExt = new UserExt(); userExt.setSex( "1" ); userExt.setUsername( "小明" ); userQueryVO.setUserExt(userExt); int count = mapper.findUsersCount(userQueryVO); System.out.println(count); // 關閉SqlSession sqlSession.close(); } |
(3)輸出POJO單個對象和列表
注意:輸出單個pojo對象和pojo列表(盛放pojo對象)時,mapper映射文件中的resultType的類型是一樣的,mapper接口的方法返回值不同。
3.1Mapper映射文件
1
2
3
|
<select id= "findUsersByName" parameterType= "java.lang.String" resultType= "cn.itcast.mybatis.po.User" > SELECT * FROM USER WHERE username LIKE '%${value}%' </select> |
3.2Mapper接口
1、輸出單個pojo對象
1
2
|
//根據用戶名稱來模糊查詢用戶信息 public User findUsersByName(String username); |
2、輸出pojo列表
1
2
|
//根據用戶名稱來模糊查詢用戶信息列表 public List<User> findUsersByName(String username); |
總結:同樣的mapper映射文件,返回單個對象和對象列表時,mapper接口在生成動態代理的時候,
會根據返回值的類型,決定調用selectOne方法還是selectList方法。
2、resultMap
resultMap可以進行高級結果映射(一對一、一對多映射)。
(1)使用方法
如果查詢出來的列名和屬性名不一致,通過定義一個resultMap將列名和pojo屬性名之間作一個映射關系。
1、 定義resultMap
2、 使用resultMap作為statement的輸出映射類型。
(2)需求
把下面SQL的輸出結果集進行映射
1
|
SELECT id id_,username username_,sex sex_FROM USER WHERE id = 1 |
(3)Mapper映射文件
定義resultMap:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
|
<!-- 定義resultMap --> <!-- [id]:定義resultMap的唯一標識 [type]:定義該resultMap最終映射的pojo對象 [id標簽]:映射結果集的唯一標識列,如果是多個字段聯合唯一,則定義多個id標簽 [result標簽]:映射結果集的普通列 [column]:SQL查詢的列名,如果列有別名,則該處填寫別名 [property]:pojo對象的屬性名 --> <resultMap type= "user" id= "userResultMap" > <id column= "id_" property= "id" /> <result column= "username_" property= "username" /> <result column= "sex_" property= "sex" /> </resultMap> |
定義statement:
1
2
3
4
|
<!-- 根據ID查詢用戶信息(學習resultMap) --> <select id= "findUserByIdResultMap" parameterType= "int" resultMap= "userResultMap" > SELECT id id_,username username_,sex sex_ FROM USER WHERE id = #{id} </select> |
(4)Mapper接口定義
1
2
3
|
//根據ID查詢用戶信息(學習resultMap) public User findUserByIdResultMap( int id);<strong> </strong> |
定義Statement使用resultMap映射結果集時,Mapper接口定義方法的返回值類型為mapper映射文件中resultMap的type類型。
(5)測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
|
@Test public void findUserByIdResultMapTest() { // 創建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通過SqlSession,獲取mapper接口的動態代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper. class ); // 調用mapper對象的方法 User user = userMapper.findUserByIdResultMap( 1 ); System.out.println(user); // 關閉SqlSession sqlSession.close(); } |
三、動態SQL
1、If和where
Ø If標簽:作為判斷入參來使用的,如果符合條件,則把if標簽體內的SQL拼接上。
注意:用if進行判斷是否為空時,不僅要判斷null,也要判斷空字符串‘';
Ø Where標簽:會去掉條件中的第一個and符號。
(1)需求
用戶信息綜合查詢列表和用戶信息綜合查詢總數這兩個statement的定義使用動態SQL。
(2)映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
|
<!-- 綜合查詢用戶信息,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息) --> <select id= "findUsersByQueryVO" parameterType= "cn.itcast.mybatis.po.QueryUserVO" resultType= "User" > SELECT * FROM USER <where> < if test= "userExt != null" > < if test= "userExt.sex != null and userExt.sex != ''" > AND sex = #{userExt.sex} </ if > < if test= "userExt.username != null and userExt.username != ''" > AND username LIKE '%${userExt.username}%' </ if > </ if > </where> </select> <!-- 綜合查詢用戶信息總數,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息) --> <select id= "findUsersCount" parameterType= "QueryUserVO" resultType= "int" > SELECT count( 1 ) FROM USER <where> < if test= "userExt != null" > < if test= "userExt.sex != null and userExt.sex != ''" > AND sex = #{userExt.sex} </ if > < if test= "userExt.username != null and userExt.username != ''" > AND username LIKE '%${userExt.username}%' </ if > </ if > </where> </select> |
(3)Mapper接口
1
2
3
4
|
//通過包裝類來進行復雜的用戶信息綜合查詢 public List<UserExt> findUserList(UserQueryVO userQueryVO); //綜合查詢用戶總數 public int findUsersCount(UserQueryVO userQueryVO); |
(4)測試代碼
不傳用戶名:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
@Test public void testFindUserList() throws Exception{ // 創建UserMapper對象 SqlSession sqlSession = sqlSessionFactory.openSession(); // 由mybatis通過sqlsession來創建代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper. class ); QueryUserVO vo = new QueryUserVO(); User user = new User(); //此處使用動態SQL,不傳username參數 user.setSex( "1" ); // user.setUsername("小明"); vo.setUser(user); List<User> list = mapper.findUserList(vo); System.out.println(user); sqlSession.close(); } |
輸出的SQL如下(也不包含用戶名):
通過測試可以得知,打印出的SQL語句確實會隨著條件的滿足情況而不一樣。
2、SQL片段
Mybatis提供了SQL片段的功能,可以提高SQL的可重用性。
2.1定義SQL片段
使用sql標簽來定義一個SQL片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!-- 定義SQL片段 --> <!-- [sql標簽]:定義一個SQL片段 [id]:SQL片段的唯一標識 建議: 1 、SQL片段中的內容最好是以單表來定義 2 、如果是查詢字段,則不要寫上SELECT 3 、如果是條件語句,則不要寫上WHERE --> <sql id= "select_user_where" > < if test= "userExt != null" > < if test= "userExt.sex != null and userExt.sex != ''" > AND sex = #{userExt.sex} </ if > < if test= "userExt.username != null and userExt.username != ''" > AND username LIKE '%${userExt.username}%' </ if > </ if > </sql> |
2.2引用SQL片段
使用<includerefid='' /> 來引用SQL片段:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!-- 根據用戶id來查詢用戶信息(使用SQL片段) --> <!-- [include標簽]:引用已經定義好的SQL片段 [refid]:引用的SQL片段id --> <select id= "findUserList" parameterType= "userQueryVO" resultType= "userExt" > SELECT * FROM USER <where> <include refid= "select_user_where" /> </where> </select> <!-- 綜合查詢用戶信息總數,需要傳入查詢條件復雜,比如(用戶信息、訂單信息、商品信息) --> <select id= "findUsersCount" parameterType= "QueryUserVO" resultType= "int" > SELECT count( 1 ) FROM USER <where> <include refid= "select_user_where" /> </where> </select> |
3、foreach
向sql傳遞數組或List時,mybatis使用foreach解析數組里的參數并拼接到SQL中。
(1)傳遞pojo對象中的list集合
1.1需求
在用戶查詢列表和查詢總數的statement中增加多個id輸入查詢。
1.2SQL
1
|
SELECT * FROM user WHERE id IN ( 1 , 10 , 16 ) |
1.3定義pojo中的list屬性
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
|
package com.itheima.mybatis.po; import java.util.List; /** * <p>Title: UserQueryVO</p> * <p>Description: TODO(這里用一句話描述這個類的作用) <p> */ public class UserQueryVO { //用戶信息 private UserExt userExt; //商品ID集合 private List<Integer> idList; //商品信息 public List<Integer> getIdList() { return idList; } public void setIdList(List<Integer> idList) { this .idList = idList; } public UserExt getUserExt() { return UserExt; } public void setUserExt(UserExt userExt) { this .UserExt = UserExt; } //訂單信息 } |
1.4映射文件
1
2
3
4
5
6
7
8
9
10
11
|
<!-- [foreach標簽]:表示一個foreach循環 --> <!-- [collection]:集合參數的名稱,如果是直接傳入集合參數,則該處的參數名稱只能填寫[list]。 --> <!-- [item]:每次遍歷出來的對象 --> <!-- [open]:開始遍歷時拼接的串 --> <!-- [close]:結束遍歷時拼接的串 --> <!-- [separator]:遍歷出的每個對象之間需要拼接的字符 --> < if test= "idList != null and idList.size > 0" > <foreach collection= "idList" item= "id" open= "AND id IN (" close= ")" separator= "," > #{id} </foreach> </ if > |
1.5Mapper接口
1
2
|
//根據用戶ID的集合查詢用戶列表(學習foreach標簽之通過POJO對象傳ID集合) public List<UserExt> findUserList(UserQueryVO vo); |
1.6測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
@Test public void testFindUserList() { // 創建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通過SqlSession,獲取mapper接口的動態代理對象 UserMapper mapper = sqlSession.getMapper(UserMapper. class ); // 構造QueryUserVO對象 QueryUserVO vo = new QueryUserVO(); // UserExt ext = new UserExt(); // ext.setUsername("小明"); // ext.setSex("1"); // vo.setUserExt(ext); // 創建用戶ID集合,然后設置到QueryUserVO對象中 List<Integer> idList = new ArrayList<Integer>(); idList.add( 1 ); idList.add( 10 ); idList.add( 16 ); vo.setIdList(idList); // 調用mapper代理對象的方法 List<UserExt> list = mapper.findUserList(vo); System.out.println(list); // 關閉SqlSession sqlSession.close(); } |
(2)直接傳遞List集合
2.1需求
根據用戶ID的集合查詢用戶列表
2.2SQL
1
|
SELECT * FROM user WHERE id IN ( 1 , 10 , 16 ) |
2.3映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
<!-- 根據用戶ID的集合查詢用戶列表(學習foreach標簽之直接傳ID集合) --> <!-- [foreach標簽]:表示一個foreach循環 [collection]:集合參數的名稱,如果是直接傳入集合參數,則該處的參數名稱只能填寫[list]。 [item]:定義遍歷集合之后的參數名稱 [open]:開始遍歷之前需要拼接的SQL串 [close]:結束遍歷之后需要拼接的SQL串 [separator]:遍歷出的每個對象之間需要拼接的字符 --> <select id= "findUsersByIdList" parameterType= "java.util.List" resultType= "user" > SELECT * FROM USER <where> < if test= "list != null and list.size > 0" > <foreach collection= "list" item= "id" open= "AND id IN (" close= ")" separator= "," > #{id} </foreach> </ if > </where> </select> |
2.4Mapper接口
1
2
|
//根據用戶ID的集合查詢用戶列表(學習foreach標簽之直接傳ID集合) public List<User> findUsersByIdList (List<Integer> idList); |
2.5測試代碼
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
@Test public void findUsersByIdListTest() { // 創建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 通過SqlSession,獲取mapper接口的動態代理對象 UserMapper userMapper = sqlSession.getMapper(UserMapper. class ); // 構造List<Integer>集合 List<Integer> idList = new ArrayList<Integer>(); idList.add( 1 ); idList.add( 10 ); idList.add( 16 ); // 調用mapper對象的方法 List<User> list = userMapper.findUsersByIdList (idList); System.out.println(list); // 關閉SqlSession sqlSession.close(); } |
以上所述是小編給大家介紹的Mybatis映射文件實例詳解,希望對大家有所幫助,如果大家有任何疑問請給我留言,小編會及時回復大家的。在此也非常感謝大家對服務器之家網站的支持!