mybatis概述

mybatis 介绍

mybatis是一个持久层的框架,是apache下的顶级项目。

mybatis托管到goolecode下,再后来托管到github下。

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,因为有一部分需要我们自己编写sql)满足需要sql语句。

mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

mybatis框架执行过程

配置mybatis的配置文件,mybatis-config.xml(名称不固定,根据个人习惯)。

通过配置文件,加载mybatis运行环境,创建SqlSessionFactory会话工厂(SqlSessionFactory在实际使用时按单例方式)

通过SqlSessionFactory创建SqlSession。SqlSession是一个面向用户接口(提供操作数据库方法),SqlSession的实例不能被共享,实现对象是线程不安全的,建议sqlSession应用场合在方法体内。

调用sqlSession的方法去操作数据。如果需要提交事务,需要执行SqlSession的commit()方法。

释放资源,关闭SqlSession。

mybatis框架原理

mybatis开发dao的方法

  • 原始dao 的方法
    • 需要我们手动编写dao接口和实现类
    • 需要在dao实现类中注入一个SqlSessionFactory工厂
  • mapper代理开发方法

  只需要我们手动编写mapper接口(就是dao接口)。

  只需在编写mapper.xml(映射文件)和mapper.java需要遵循一个开发规范:

    • mapper.xml中namespace就是mapper.java的类全路径。
    • mapper.xml中statement的id和mapper.java中方法名一致。
    • mapper.xml中statement的parameterType指定输入参数的类型和mapper.java的方法输入参数类型一致
    • mapper.xml中statement的resultType指定输出结果的类型和mapper.java的方法返回值类型一致。

  SqlMapConfig.xml配置文件:可以配置properties属性、别名、mapper加载。

输入映射和输出映射

  • 输入映射
    • parameterType:指定输入参数类型可以简单类型、pojo、hashmap。
    • 对于综合查询,建议parameterType使用包装的pojo,有利于系统扩展。
  • 输出映射
    • resultType:查询到的列名和resultType指定的pojo的属性名一致,才能映射成功。
    • reusltMap:可以通过resultMap 完成一些高级映射。如果查询到的列名和映射的pojo的属性名不一致时,通过resultMap设置列名和属性名之间的对应关系(映射关系)。可以完成映射。
      • 高级映射: 将关联查询的列映射到一个pojo属性中。(一对一) 将关联查询的列映射到一个List中。(一对多)

动态sql语句

 mybatis核心:对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。

  • if 判断

  需求:

    • 用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。
    • 对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。  

  mapper.xml:

 1 <!-- 用户信息综合查询
 2     #{userCustom.sex}:取出pojo包装对象中性别值
 3     ${userCustom.username}:取出pojo包装对象中用户名称
 4  -->
 5 <select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"
 6         resultType="com.iot.mybatis.po.UserCustom">
 7     SELECT * FROM user
 8     <!--  where 可以自动去掉条件中的第一个and -->
 9     <where>
10         <if test="userCustom!=null">
11             <if test="userCustom.sex!=null and userCustom.sex != '' ">
12                AND user.sex=#{userCustom.sex}
13             </if>
14             <if test="userCustom.username!=null and userCustom.username != '' ">
15                AND user.username LIKE '%${userCustom.username}%'
16             </if>
17         </if>
18     </where>
19 
20 
21 </select>
22 
23 <!-- 用户信息综合查询总数
24     parameterType:指定输入类型和findUserList一样
25     resultType:输出结果类型
26 -->
27 <select id="findUserCount" parameterType="com.iot.mybatis.po.UserQueryVo" resultType="int">
28     SELECT count(*) FROM user
29     <where>
30         <if test="userCustom!=null">
31             <if test="userCustom.sex!=null and userCustom.sex != '' ">
32                 AND user.sex=#{userCustom.sex}
33             </if>
34             <if test="userCustom.username!=null and userCustom.username != '' ">
35                 AND user.username LIKE '%${userCustom.username}%'
36             </if>
37         </if>
38     </where>
39 </select>
  • foreach标签

  向sql传递数组或List,mybatis使用foreach解析

  在用户查询列表和查询总数的statement中增加多个id输入查询。两种方法,sql语句如下:

  •  SELECT * FROM USER WHERE id=1 OR id=10 OR id=16 
  •  SELECT * FROM USER WHERE id IN(1,10,16) 

   一个使用or,一个使用in

  • 在输入参数类型中添加List<Integer> ids传入多个id
1 public class User{
2 
3     //传入多个id
4     private List<Integer> ids;
5     
6     getter、setter方法
7     。。。
8 }
  • 修改mapper.xml

 1 <if test="ids!=null">
 2     <!-- 使用 foreach遍历传入ids
 3     collection:指定输入 对象中集合属性
 4     item:每个遍历生成对象中
 5     open:开始遍历时拼接的串
 6     close:结束遍历时拼接的串
 7     separator:遍历的两个对象中需要拼接的串
 8      -->
 9     <!-- 使用实现下边的sql拼接:
10      AND (id=1 OR id=10 OR id=16)
11      -->
12     <foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
13         <!-- 每个遍历需要拼接的串 -->
14         id=#{user_id}
15     </foreach>
16     
17     <!-- 实现  “ and id IN(1,10,16)”拼接 -->
18     <!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
19         每个遍历需要拼接的串
20         #{user_id}
21     </foreach> -->
22 
23 </if>
  • 测试

    • 添加一个testUser测试的方法中添加:
1 //传入多个id
2 List<Integer> ids = new ArrayList<Integer>();
3 ids.add(1);
4 ids.add(10);
5 ids.add(16);
6 //将ids通过user传入statement中
7 user.setIds(ids);
  • sql片段

将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。

    • 定义sql片段

 1 <!-- 定义sql片段
 2 id:sql片段的唯 一标识
 3 
 4 经验:是基于单表来定义sql片段,这样话这个sql片段可重用性才高
 5 在sql片段中不要包括 where
 6  -->
 7 <sql id="query_user_where">
 8     <if test="userCustom!=null">
 9         <if test="userCustom.sex!=null and userCustom.sex!=''">
10             AND user.sex = #{userCustom.sex}
11         </if>
12         <if test="userCustom.username!=null and userCustom.username!=''">
13             AND user.username LIKE '%${userCustom.username}%'
14         </if>
15     </if>
16 </sql>
View Code

  

    • 引用sql片段

 1 <!-- 用户信息综合查询
 2     #{userCustom.sex}:取出pojo包装对象中性别值
 3     ${userCustom.username}:取出pojo包装对象中用户名称
 4  -->
 5 <select id="findUserList" parameterType="com.iot.mybatis.po.UserQueryVo"
 6         resultType="com.iot.mybatis.po.UserCustom">
 7     SELECT * FROM user
 8     <!--  where 可以自动去掉条件中的第一个and -->
 9     <where>
10         <!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
11         <include refid="query_user_where"></include>
12         <!-- 在这里还要引用其它的sql片段  -->
13     </where>
14 </select>
View Code

 

原文地址:https://www.cnblogs.com/lhy-549/p/10087549.html