一、输入映射
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映射文件实例详解,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对服务器之家网站的支持!