Mybatis学习(五)

7.MyBatis映射文件

7.1 输入映射

在mybatis中,输入映射使用parameterType来进行映射。

7.1.1 映射简单类型

参考  根据用户id 查询用户信息      parameterType="int"

 

7.1.2 映射pojo

参考 添加用户信息    parameterType="com.jxdd.mybatis.po.User"

 

7.1.3 映射包装pojo

开发中通过pojo传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。

7.1.3.1 需求

综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息).

7.1.3.2 创建包装pojo类

一般User.java类要和数据表表字段一致,最好不要在这里面添加其他字段,当使用mybatis的逆向工程时,会根据表结构,生成po类,如果在po类中扩展字段,此时会被覆盖掉。

所以针对要扩展的po类,我们需要创建一个扩展类,来继承它。

1 public class UserExt extends User{
2     //这里可以定义User的一些扩展信息
3 }
UserExt

定义POJO包装类

 1 public class UserQueryVO {
 2     private UserExt userExt;
 3 
 4     public UserExt getUserExt() {
 5         return userExt;
 6     }
 7 
 8     public void setUserExt(UserExt userExt) {
 9         this.userExt = userExt;
10     }
11 }
UserQueryVO

7.1.3.3 编写mapper接口

1 public List<UserExt> findUserList(UserQueryVO userQueryVO);

7.1.3.4 编写mapper映射文件

1     <select id="findUserList" parameterType="com.jxdd.mybatis.po.UserQueryVO" resultType="com.jxdd.mybatis.po.UserExt">
2         SELECT * FROM USER WHERE sex=#{userExt.sex} AND username LIKE '%${userExt.username}%'
3     </select>
UserMapper.xml

注意:入参的类型变为UserQueryVO、结果集的类型变为UserExt,#{}里面的参数变为UserQueryVO对象中的userExt属性的sex和username子属性。

7.1.3.5 编写测试代码

 1 @Test 
 2     public void findUserListTset(){
 3         //创建SqlSession对象
 4         SqlSession sqlSession = sqlSessionFactory.openSession();
 5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 6         //构造UserQueryVO对象
 7         UserQueryVO userQueryVO = new UserQueryVO();
 8         //构造UserExt对象
 9         UserExt userExt = new UserExt();
10         userExt.setSex("1");
11         userExt.setUsername("张三");
12         userQueryVO.setUserExt(userExt);
13         //调用mapper对象方法
14         List<UserExt> userList = userMapper.findUserList(userQueryVO);
15         System.out.println(userList);
16         //关闭连接
17         sqlSession.close();
18     }
test

运行结果

DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 235542568.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e0a1828]
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE sex=? AND username LIKE '%张三%' 
DEBUG [main] - ==> Parameters: 1(String)
DEBUG [main] - <==      Total: 2
[User [id=10, username=张三, sex=1, birthday=Thu Jul 10 00:00:00 CST 2014, address=北京市], User [id=24, username=张三丰, sex=1, birthday=null, address=北京市]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e0a1828]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@e0a1828]
DEBUG [main] - Returned connection 235542568 to pool.
结果

7.1.4 映射HashMap

 

同传递POJO对象一样,map的key相当于pojo的属性

7.1.4.1 编写mapper接口

1 public User findUserByHashmap(HashMap<String, Object> hashMap);
mapper

7.1.4.2 映射文件

1 <!-- 传递hashmap综合查询用户信息 -->
2     <select id="findUserByHashmap" parameterType="java.util.HashMap" resultType="com.jxdd.mybatis.po.User">
3         select * from user where id=#{id} and username like '%${username}%'
4     </select>
xml

7.1.4.3 编写测试代码

 1 @Test
 2     public void findUserByHashmapTest(){
 3         //创建SqlSession对象
 4         SqlSession sqlSession = sqlSessionFactory.openSession();
 5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 6         HashMap<String, Object> map = new HashMap<String, Object>();
 7         map.put("id", 28);
 8         map.put("username", "qt");
 9         User user = userMapper.findUserByHashmap(map);
10         System.out.println(user);
11         sqlSession.close();
12     }
test

7.2 输出映射

7.2.1 resultType

7.2.1.1 使用方法

使用resultType进行结果映射时,查询的列名和映射的pojo属性名完全一致,该列才能映射成功.

如果查询的列名和映射的pojo属性名全部不一致,则不会创建pojo对象

如果查询的列名和映射的pojo属性名有一个一致,就会创建pojo对象

 

7.2.1.2 输出简单类型

当输出结果只有一列时,可以使用ResultType指定简单类型作为输出结果类型。

 

7.2.1.2.1 需求

查询用户总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息)

7.2.1.2.2 mapper映射文件

1 <!-- 综合查询用户信息总数,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
2     <select id="findUsersCount" parameterType="com.jxdd.mybatis.po.UserQueryVO"
3             resultType="int">
4             SELECT count(1) FROM USER WHERE sex = #{userExt.sex} AND username    LIKE '%${userExt.username}%'
5     </select>
xml

7.2.1.2.3 编写mapper接口

1 //综合查询用户信息总数。学习:resultType输出简单类型
2     public int findUsersCount(UserQueryVO vo);
mapper

7.2.1.2.4 编写测试类

 1 @Test
 2     public void findUsersCountTest(){
 3         //创建SqlSession对象
 4         SqlSession sqlSession = sqlSessionFactory.openSession();
 5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 6         //构造UserQueryVO对象
 7         UserQueryVO userQueryVO = new UserQueryVO();
 8         //构造UserExt对象
 9         UserExt userExt = new UserExt();
10         userExt.setSex("1");
11         userExt.setUsername("张三");
12         userQueryVO.setUserExt(userExt);
13         int count = userMapper.findUsersCount(userQueryVO);
14         System.out.println(count);
15         sqlSession.close();
16     }
test

 

7.2.1.3 输出POJO单个对象和列表

参考 根据用户id查询用户信息   和  根据用户名称模糊查询用户列表

总结:同样的mapper映射文件,返回单个对象和对象列表时,mapper接口在生成动态代理的时候,会根据返回值的类型,决定调用selectOne方法还是selectList方法。

 

7.2.2 resultMap

resultMap可以进行高级结果映射(一对一,一对多映射)

7.2.2.1 使用方法

如果查询出来的列名和属性名不一致,通过定义一个resultMap将列名和pojo属性名之间作一个映射关系。

1.定义resultMap

2.使用resultMap作为statement的输出映射类型.

 

7.2.2.2 需求

 

把下面SQL的输出结果集进行映射

 

SELECT id id_,username username_,sex sex_ FROM USER WHERE id = 1

 

7.2.2.3 mapper映射文件

 

 1 <!-- 
 2         [id]:定义resultMap的唯一标识
 3         [type]:定义该resultMap最终映射的pojo对象
 4         [id标签]:映射结果集的唯一标识列,如果是多个字段联合唯一,则定义多个id标签
 5         [result标签]:映射结果集的普通列
 6         [column]:SQL查询的列名,如果列有别名,则该处填写别名
 7         [property]:pojo对象的属性名
 8     -->
 9     <resultMap type="com.jxdd.mybatis.po.User" id="userResultMap">
10         <id column="id_" property="id"/>
11         <result column="username_" property="username"/>
12         <result column="sex_" property="sex"/>
13     </resultMap>
14     <!-- 根据ID查询用户信息(学习resultMap) -->
15     <select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
16         SELECT id id_,username username_,sex sex_ FROM USER WHERE id = #{id}
17     </select>
xml

7.2.2.4 mapper接口定义

1 //根据ID查询用户信息(学习resultMap)
2 public User findUserByIdResultMap(int id);
mapper

定义Statement使用resultMap映射结果集时,Mapper接口定义方法的返回值类型为mapper映射文件中resultMap的type类型。

7.2.2.5 测试代码

1 @Test
2     public void findUserByIdResultMapTest(){
3         //创建SqlSession对象
4         SqlSession sqlSession = sqlSessionFactory.openSession();
5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
6         User user = userMapper.findUserByIdResultMap(1);
7         System.out.println(user);
8         sqlSession.close();
9     }
test

7.3 动态sql

 

通过Mybatis提供的各种动态标签实现动态拼接sql,使得mapper映射文件在编写SQL时更加灵活,方便。常用动态SQL标签有:if、where、foreach

 

7.3.1 If、where标签

If标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。注意:用if进行判断是否为空时,不仅要判断null,也要判断空字符串‘’;

Where标签:会去掉条件中的第一个and符号

7.3.1.1 需求

用户信息综合查询列表statement的定义使用动态SQL。

7.3.1.2 映射文件

 1 <!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
 2     <select id="findUsersByQueryVO" parameterType="com.jxdd.mybatis.po.UserQueryVO"
 3             resultType="com.jxdd.mybatis.po.User">
 4             SELECT * FROM USER
 5         <where>
 6             <if test="userExt != null">
 7                 <if test="userExt.sex != null and userExt.sex != ''">
 8                     AND sex = #{userExt.sex}
 9                 </if>
10                 <if test="userExt.username != null and userExt.username != ''">
11                     AND username LIKE '%${userExt.username}%'
12                 </if>
13             </if>
14         </where>
15     </select>
xml

7.3.1.3 mapper接口定义

1 //通过包装类来进行复杂的用户信息综合查询
2 public List<UserExt> findUsersByQueryVO(UserQueryVO userQueryVO);
mapper

7.3.1.4 测试代码

 1 @Test
 2     public void findUsersByQueryVOTest(){
 3         //创建SqlSession对象
 4         SqlSession sqlSession = sqlSessionFactory.openSession();
 5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 6         //构造UserQueryVO对象
 7         UserQueryVO userQueryVO = new UserQueryVO();
 8         //构造UserExt对象
 9         UserExt userExt = new UserExt();
10         userExt.setUsername("qt");
11         userQueryVO.setUserExt(userExt);
12         List<UserExt> list = userMapper.findUsersByQueryVO(userQueryVO);
13         System.out.println(list);
14         sqlSession.close();
15     }
test

运行结果

7.3.2 SQL片段

Mybatis提供了SQL片段的功能,可以提高SQL的可重用性

7.3.2.1 定义sql片段

使用sql标签来定义一个SQL片段:

 1 <!-- 定义sql片段 -->
 2     <!--
 3         [sql标签]:定义一个sql片段
 4         [id]: sql片段的唯一标识
 5         建议:
 6         1、SQL片段中的内容最好是以单表来定义
 7         2、如果是查询字段,则不要写上SELECT
 8         3、如果是条件语句,则不要写上WHERE 
 9      -->
10     <sql id="select_user_where">
11         <if test="userExt != null">
12             <if test="userExt.sex != null and userExt.sex != ''">
13                 AND sex = #{userExt.sex}
14             </if>
15             <if test="userExt.username != null and userExt.username != ''">
16                 AND username LIKE '%${userExt.username}%'
17             </if>
18         </if>
19     </sql>
sql片段

7.3.2.2 引用sql片段

1 <!-- 综合查询用户信息,需要传入查询条件复杂,比如(用户信息、订单信息、商品信息) -->
2     <select id="findUsersByQueryVO" parameterType="com.jxdd.mybatis.po.UserQueryVO"
3             resultType="com.jxdd.mybatis.po.User">
4             SELECT * FROM USER
5         <where>
6             <include refid="select_user_where"></include>
7         </where>
8     </select>
引用sql片段

 

7.3.3 Foreach

向sql传递数组或List时,mybatis使用foreach解析数组里的参数并拼接到SQL中。

7.3.3.1 传递pojo对象中的List集合

在用户查询列表和查询总数的statement中增加多个id输入查询

7.3.3.2 定义pojo中的List的属性

 1 public class UserQueryVO {
 2     private UserExt userExt;
 3     
 4     //id集合
 5     private List<Integer> idList;
 6     
 7     public List<Integer> getIdList() {
 8         return idList;
 9     }
10 
11     public void setIdList(List<Integer> idList) {
12         this.idList = idList;
13     }
14 
15     public UserExt getUserExt() {
16         return userExt;
17     }
18 
19     public void setUserExt(UserExt userExt) {
20         this.userExt = userExt;
21     }
22 }
pojo

7.3.3.3 映射文件

 1 <!-- 根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合) -->
 2     <!-- 
 3         [foreach标签]:表示一个foreach循环
 4         [collection]:集合参数的名称,如果是直接传入集合参数,则该处的参数名称只能填写[list]。
 5         [item]:定义遍历集合之后的参数名称
 6         [open]:开始遍历之前需要拼接的SQL串
 7         [close]:结束遍历之后需要拼接的SQL串
 8         [separator]:遍历出的每个对象之间需要拼接的字符
 9      -->
10     <select id="findUsersByIdList" parameterType="java.util.List" resultType="com.jxdd.mybatis.po.User">
11         SELECT * FROM USER
12         <where>
13             <if test="list != null and list.size > 0">
14                 <foreach collection="list" item="id" open="AND id IN (" close=")" separator=",">
15                     #{id}
16                 </foreach>
17             </if>
18         </where>
19     </select>
xml

7.3.3.4 mapper接口

1 //根据用户ID的集合查询用户列表(学习foreach标签之直接传ID集合)
2     public List<User> findUsersByIdList (List<Integer> idList);
mapper

7.3.3.5 测试代码

 1 @Test
 2     public void findUsersCountFTest(){
 3         //创建SqlSession对象
 4         SqlSession sqlSession = sqlSessionFactory.openSession();
 5         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
 6         //构造UserQueryVO对象
 7         UserQueryVO userQueryVO = new UserQueryVO();
 8         List<Integer> idList = new ArrayList<Integer>();
 9         idList.add(1);
10         idList.add(10);
11         idList.add(16);
12         userQueryVO.setIdList(idList);
13         List<User> list = userMapper.findUsersByIdList(idList);
14         System.out.println(list);
15         sqlSession.close();
16     }
test

 

 

 

mybatis与hibernate的区别及各自应用场景

Mybatis技术特点:

1、  通过直接编写SQL语句,可以直接对SQL进行性能的优化;

2、  学习门槛低,学习成本低。只要有SQL基础,就可以学习mybatis,而且很容易上手;

3、  由于直接编写SQL语句,所以灵活多变,代码维护性更好。

4、  不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。

5、  需要编写结果映射。

Hibernate技术特点:

1、  标准的orm框架,程序员不需要编写SQL语句。

2、  具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。

3、  学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。

4、  程序员不能自主的去进行SQL性能优化。

 

Mybatis应用场景:

         需求多变的互联网项目,例如电商项目。

Hibernate应用场景:

         需求明确、业务固定的项目,例如OA项目、ERP项目等。

 

posted @ 2016-12-02 13:49  qttttt  阅读(237)  评论(0)    收藏  举报