MyBatis学习笔记之二

1.分步查询

接口1中的代码如下:

public interface DepartmentMapper {
 public Department getDeptById(Integer id);
}

1.对应的sql中的文件如下

<?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">
<mapper namespace="com.atguigu.mybatis.dao.DepartmentMapper">
 <select id="getDeptById" resultType="com.atguigu.mybatis.bean.Department">
  select id,dept_name departmenName from tb1_dept where id=#{id}
 </select>
</mapper>

接口2中的代码如下:

public interface EmployeeMapperPlus {
 public Employee getEmpByIdStep(Integer id);
}

接口2对应的sql代码如下

 <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpByStep">
  <id column="id" property="id"/>
  <result column="last_name" property="lastName"/>
  <result column="email" property="email"/>
  <result column="gender" property="gender"/>
  <association property="dept" 
    select="com.atguigu.mybatis.dao.DepartmentMapper.getDeptById"
    column="d_id">
  </association>
 </resultMap>
 <select id="getEmpByIdStep" resultMap="MyEmpByStep">
  select * from tb1_employee where id=#{id}
 </select>
2.查询的延迟加载

在配置文件中配置如下两个配置

 <settings>
  <!--<setting name="mapUnderscoreToCamelCase" value="true"/>-->
  <!-- 显示的指定每个我们需要更改的配置的值,即使他是默认的,防止版本更新带来的问题 -->
  <setting name="lazyLoadingEnabled" value="true"/>
  <setting name="aggressiveLazyLoading" value="false"/>
 </settings>

测试运行结果如下:

DEBUG 07-03 09:40:50,571 ==>  Preparing: select * from tb1_employee where id=?   (BaseJdbcLogger.java:145) 
DEBUG 07-03 09:40:50,597 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 07-03 09:40:50,657 <==      Total: 1  (BaseJdbcLogger.java:145) 
jerry
3.查询部门的时候将部门对应的所有的员工信息也查询出来

类代码如下

public class Department {
 private Integer id;//省略get和set方法
 private String departmenName;
 private List<Employee> emps;
 }

接口代码如下:

public interface DepartmentMapper {
 public Department getDeptById(Integer id);
 public Department getDeptByIdPlus(Integer id);
}

sql配置文件如下:

<resultMap type="com.atguigu.mybatis.bean.Department" id="MyDept">
  <id column="d_id" property="id"/>
  <result column="dept_name" property="departmenName"/>
  <collection property="emps" ofType="com.atguigu.mybatis.bean.Employee">
   <id column="id" property="id"/>
   <result column="last_name" property="lastName"/>
   <result column="email" property="email"/>
   <result column="gender" property="gender"/>
  </collection>
 </resultMap>
 <select id="getDeptByIdPlus" resultMap="MyDept">
  SELECT e.*,d.dept_name
  from tb1_dept d
  LEFT JOIN tb1_employee e
  on d.id=e.d_id
  where d.id=#{id}
 </select>

测试代码如下:

 @Test
 public void test04() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  DepartmentMapper mapper=openSession.getMapper(DepartmentMapper.class);
  Department department=mapper.getDeptByIdPlus(1);
  System.out.println(department);
  List<Employee> emps=department.getEmps();
  for(Employee emp:emps) {
   System.out.println(emp);
  }
 }
4.定义使用分布查询完成

接口1中的代码如下:

public interface EmployeeMapperPlus {
 public Employee getEmpById(Integer id);
 public Employee getEmpAndDept(Integer id);
 public Employee getEmpByIdStep(Integer id);
 public List<Employee> getEmpsByDeptId(Integer deptId);
}

涉及到的sql查询语句如下

 <select id="getEmpsByDeptId" resultType="com.atguigu.mybatis.bean.Employee">
  select * from tb1_employee where d_id=#{deptId}
 </select>

接口2中的代码如下:

public interface DepartmentMapper {
 public Department getDeptById(Integer id);
 public Department getDeptByIdPlus(Integer id);
 public Department getDeptByIdStep(Integer id);
}

涉及到的sql查询语句如下

 <resultMap type="com.atguigu.mybatis.bean.Department" id="MyDeptStep">
  <id column="id" property="id"/>
  <result column="dept_name" property="departmenName"/>
  <collection property="emps" 
   select="com.atguigu.mybatis.dao.EmployeeMapperPlus.getEmpsByDeptId"
   column="id">
  <!--多列的值传递过去
   column="{key1=column1,key2=column2}"
   fecthType="lazy"
   lazy:延迟加载
   eager:立即加载
  -->
  </collection>
 </resultMap>
 <select id="getDeptByIdStep" resultMap="MyDeptStep">
  select id,dept_name departmenName from tb1_dept where
  id=#{id}
 </select>
5.需求:封装Employee

如果查出的是女生,就把部门信息查询出来,否则不查询;
如果是男生,就把last_name这一列的值赋值为email
sql查詢配置如下

 <resultMap type="com.atguigu.mybatis.bean.Employee" id="MyEmpDis">
  <id column="id" property="id"></id>
  <result column="last_name" property="lastName"></result>
  <result column="email" property="email"></result>
  <result column="gender" property="gender"></result>
  <discriminator javaType="string" column="gender">
   <case value="0" resultType="com.atguigu.mybatis.bean.Employee">
    <association property="dept" 
     select="com.atguigu.mybatis.dao.DepartmentMapper.getDeptById"
     column="d_id">
    </association>
   </case>
   <case value="1" resultType="com.atguigu.mybatis.bean.Employee">
    <id column="id" property="id"></id>
    <result column="last_name" property="lastName"></result>
    <result column="last_name" property="email"></result>
    <result column="gender" property="gender"></result>
   </case>
  </discriminator>
 </resultMap>
 <select id="getEmpByIdStep" resultMap="MyEmpDis">
  select * from tb1_employee where id=#{id}
 </select>
com.atguigu.mybatis.dao.DepartmentMapper.getDeptById的配置如下
 <select id="getDeptByIdStep" resultMap="MyDeptStep">
  select id,dept_name departmenName from tb1_dept where
  id=#{id}
 </select>

測試代碼如下:

 @Test
 public void test04() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  EmployeeMapperPlus mapper=openSession.getMapper(EmployeeMapperPlus.class);
  Employee employee=mapper.getEmpByIdStep(1);
  System.out.println(employee);
 }
6.动态sql

1.if标签

7.OGNL

在这里插入图片描述
1.if标签测试

public interface EmployeeMapperDynamicSQL {
 public List<Employee> getEmpsByConditionIf(Employee employee);
}

sql配置文件

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.mybatis.dao.EmployeeMapperDynamicSQL">
 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee" >
  select id,last_name lastName,email,gender from tb1_employee
  <where> 
  <!--只会去掉第一个多出来的and或者or-->
  <if test="id!=null">
   id=#{id}
  </if>
  <if test="lastName!=null and lastName!=&quot;&quot;">
   and last_name like #{lastName}
  </if>
  <if test="email!=null and email.trim()!=&quot;&quot;">
   and email=#{email}
  </if>
  <if test="gender==0 or gender==1">
   and gender=#{gender}
  </if>
  </where>
 </select>
</mapper>
8.使用trim进行查询
<select id="getEmpsByConditionTrim" resultType="com.atguigu.mybatis.bean.Employee">
 select id,last_name lastName,email,gender from tb1_employee
 <!-- 
  prefix:前缀,给拼串后的整个字符串加一个前缀
  prefixOverrides:去掉整个字符串前面多余的字符
  suffix:给拼串后的整个字符串加一个后缀
  suffixOverrides:去掉整个字符串后面多余的字符
  -->
 <trim prefix="where" prefixOverrides="" suffix="" suffixOverrides="and"> 
 <if test="id!=null">
  id=#{id} and
 </if>
 <if test="lastName!=null and lastName!=&quot;&quot;">
  last_name like #{lastName} and
 </if>
 <if test="email!=null and email.trim()!=&quot;&quot;">
  email=#{email} and
 </if>
 <if test="gender==0 or gender==1">
  gender=#{gender}
 </if>
 </trim> 
</select>
9.choose标签
<select id="getEmpsByConditionChoose" resultType="com.atguigu.mybatis.bean.Employee">
  select id,last_name lastName,email,gender from tb1_employee
  <where>
   <choose >
    <when test="id!=null">
     id=#{id}
    </when>
    <when test="lastName!=null">
     last_name like #{lastName}
    </when>
    <when test="email!=null">
     email=#{email}
    </when>
    <otherwise>
     gender=0
    </otherwise>
   </choose>
  </where>
 </select>
10.set标签
 <select id="updateEmp">
  update tb1_employee
   <set>
    <if test="lastName!=null">
     last_name=#{lastName},
    </if>
    <if test="email!=null">
     email=#{email},
    </if>
    <if test="gender!=null">
     gender=#{gender},
    </if>
   </set> 
   <where>
   id=#{id}
   </where>
 </select>

测试代码

 @Test
 public void test05() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  EmployeeMapperDynamicSQL mapper=openSession.getMapper(EmployeeMapperDynamicSQL.class);
  Employee employee=new Employee(3,"%e%","test1","0");
  mapper.updateEmp(employee);
  openSession.commit();
  openSession.close();
 }

测试结果为:

DEBUG 07-03 15:40:05,351 ==>  Preparing: update tb1_employee SET last_name=?, email=?, gender=? WHERE id=?   (BaseJdbcLogger.java:145) 
DEBUG 07-03 15:40:05,386 ==> Parameters: %e%(String), test1(String), 0(String), 3(Integer)  (BaseJdbcLogger.java:145) 
11.foreach标签的使用(批量查询)

接口中申明的函数

public List<Employee> getEmpsByConditionForeach(@Param("ids") List<Integer> ids);

sql中写的语句

 <select id="getEmpsByConditionForeach" resultType="com.atguigu.mybatis.bean.Employee">
  select * from tb1_employee where id in
  <!-- 
   collection:指定要遍历的集合
    list类型的参数会特殊处理封装在map中,map的key就叫list
   item:将当前遍历出的元素赋值给指定的变量
   index:索引。遍历list的时候是index的索引。
          遍历map的时候index表示的就是map的key,item就是map的值
   -->
  <foreach collection="ids" item="item_id" 
   separator="," open="(" close=")">
   #{item_id}
  </foreach>
 </select>

java测试代码如下

 @Test
 public void test05() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  EmployeeMapperDynamicSQL mapper=openSession.getMapper(EmployeeMapperDynamicSQL.class);
  List<Employee> employees=mapper.getEmpsByConditionForeach(Arrays.asList(1,2,3));
  for(Employee employee:employees) {
   System.out.println(employee);
  }
  openSession.close();
 }

运行结果如下:

DEBUG 07-03 19:51:47,535 ==>  Preparing: select * from tb1_employee where id in ( ? , ? , ? )   (BaseJdbcLogger.java:145) 
DEBUG 07-03 19:51:47,582 ==> Parameters: 1(Integer), 2(Integer), 3(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 07-03 19:51:47,700 <==      Total: 2  (BaseJdbcLogger.java:145) 
Employee [id=1, lastName=jerry, email=jerry@atguigu.com, gender=0, dept=null]
Employee [id=3, lastName=%e%, email=test1, gender=0, dept=null]
12.foreach标签的使用(批量保存)

接口代码如下:

 public void addEmps(@Param("emps")List<Employee> emps);

sql配置文件如下:

 <insert id="addEmps">
  insert into tb1_employee(last_name,email,gender,d_id)
  values
  <foreach collection="emps" item="emp" separator=",">
   (#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
  </foreach>
 </insert>

测试代码如下:

@Test
public void test05() throws Exception{
 String resource = "mybatis-config.xml";
 InputStream inputStream = Resources.getResourceAsStream(resource);
 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
 SqlSession openSession=sqlSessionFactory.openSession();  
 EmployeeMapperDynamicSQL mapper=openSession.getMapper(EmployeeMapperDynamicSQL.class);
 List<Employee> emps=new ArrayList<>();
 Department dept=new Department(1);
 emps.add(new Employee(null,"smith","smith","1",dept));
 emps.add(new Employee(null,"smith2","smith","1",dept));
 emps.add(new Employee(null,"smith3","smith","0",dept));
 emps.add(new Employee(null,"smith4","smith","0",dept));
 mapper.addEmps(emps);
 openSession.commit();
 openSession.close();
}

第二种方式
数据库连接配置文件中做如下的配置

 jdbc.url:jdbc:mysql://localhost:3306/mybaties?serverTimezone=GMT&&allowMultiQueries=TRUE

sql语句如下:

<insert id="addEmps">
 <foreach collection="emps" item="emp" separator=";">
  insert into tb1_employee(last_name,email,gender,d_id)
  values(#{emp.lastName},#{emp.email},#{emp.gender},#{emp.dept.id})
 </foreach>
</insert>
13.Oracle数据库批量保存

在这里插入图片描述
在这里插入图片描述
实现代码:
在这里插入图片描述
在这里插入图片描述

14.mybatis中两个重要的内置参数

两个内置参数:
不只是方法传递过来的参数可以用来被判断取值
mybaties默认还有两个内置参数:
1._parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装为一个map:_parameter就是代表这个map
2._databaseId:如果配置了databaseIdProvider标签
_databaseId就是代表当前数据库的别名oracle
测试接口函数如下:

public List<Employee> getEmpsTestInnerParameter(Employee employee);

sql语句如下:

 <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
  <if test="_databaseId=='mysql'">
   select * from tb1_employee
   <if test="_parameter!=null">
    where last_name=#{_parameter.lastName}
   </if>
  </if>
  <if test="_databaseId=='oracle'">
   select * from employees
  </if>
 </select>
15.绑定变量
 <select id="getEmpsTestInnerParameter" resultType="com.atguigu.mybatis.bean.Employee">
  <bind name="_lastName" value="'%'+lastName+'%'"/>
  <if test="_databaseId=='mysql'">
   select * from tb1_employee
   <if test="_parameter!=null">
    where last_name like #{_lastName}
   </if>
  </if>
  <if test="_databaseId=='oracle'">
   select * from employees
  </if>
 </select>
16.sql标签

抽取可重用的sql标签

<sql id="column">
 id,last_name lastName,email,gender,${testColumn}
</sql>

引用的sql语句如下:

 <select id="getEmpsByConditionIf" resultType="com.atguigu.mybatis.bean.Employee" >
  select <include refid="column">
   <property name="testColumn" value="abc"></property>
  </include> from tb1_employee
  where 1=1  
  <if test="id!=null">
   and id=#{id}
  </if>
  <if test="lastName!=null and lastName!=&quot;&quot;">
   and last_name like #{lastName}
  </if>
  <if test="email!=null and email.trim()!=&quot;&quot;">
   and email=#{email}
  </if>
  <if test="gender==0 or gender==1">
   and gender=#{gender}
  </if>
 </select>

作用:
1.sql抽取:经常将要查询的列名,或者插入用的列名抽取出来方便引用
2.include来引用已经抽取的sql语句
3.include还可以自定义一些property,sql标签内部就能使用自定义的属性
取值方式为${prop},不能使用#{}

17.MyBatis的缓存机制

两级缓存
一级缓存:本地缓存,与数据库同一次会话查询到的数据会放在本地缓存中,以后如果需要获取相同的数据,直接从数据库中拿,没必要去查询数据库;属于sqlSession级别的缓存,一级缓存是一直开启的。
一级缓存失效的情况(没有使用到当前一级缓存的情况,需要再向数据库发出查询)
1.sqlSession不同。
2.sqlSession相同,查询条件不同。(当前一级缓存中还没有这个数据)。
3.sqlSession相同,两次查询之间执行了增删改操作(这次增删改可能对当前数据有影响)
4.sqlSession相同,手动清楚了一级缓存(缓存清空)
openSessison.clearCache();
测试样例
sql配置如下:

 <select id="getEmpById" resultType="employee" databaseId="mysql">
   select * from tb1_employee where id = #{id}
  </select>

测试代码如下:

 @Test
 public void test02() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  try {
   EmployeeMapper mapper=openSession.getMapper(EmployeeMapper.class);
   Employee emp01=mapper.getEmpById(1);
   System.out.println(emp01);
   Employee emp02=mapper.getEmpById(1);
   System.out.println(emp02);
   System.out.println(emp01==emp02);
  }finally {
   openSession.close();
  }
 }

测试结果如下:

DEBUG 07-06 09:59:39,813 ==>  Preparing: select * from tb1_employee where id = ?   (BaseJdbcLogger.java:145) 
DEBUG 07-06 09:59:39,861 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 07-06 09:59:39,914 <==      Total: 1  (BaseJdbcLogger.java:145) 
Employee [id=1, lastName=jerry, email=jerry@atguigu.com, gender=0, dept=null]
Employee [id=1, lastName=jerry, email=jerry@atguigu.com, gender=0, dept=null]
true

二级缓存:全局缓存。基于namespace级别的缓存,一个namespace对应一个二级缓存。
工作机制:
1.一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中;
2.如果会话关闭,一级缓存中的数据会被保存到二级缓存中,新的会话查询信息 ,就可以参照二级缓存中的内容;
3.不同的namespace查出的数据会放在自己对应的缓存中(map)。查出的数据都会被默认先放到一级缓存中,只有会话提交或者关闭以后,一级缓存中的数据才会转到二级缓存中。
测试样例:
在配置文件中进行配置

 <settings>
  <setting name="chacheEnable" value="true"/>
 </settings>

去mapper.xml中配置使用二级缓存

 <cache eviction="FIFO" flushInterval="60000" readOnly="false" size="1024" />

属性说明:
eviction=“FIFO”:缓存回收策略:
• LRU – 最近最少使用的:移除最长时间不被使用的对象。
• FIFO – 先进先出:按对象进入缓存的顺序来移除它们。
• SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
• WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
• 默认的是 LRU。
flushInterval:刷新多长时间清空一次
• 默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
size:引用数目,正整数
• 代表缓存最多可以存储多少个对象,太大容易导致内存溢出
readOnly:只读,true/false
• true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。
• false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。
type="";指定自定义缓存的全类名;实现Cache接口即可。
POJO需要实现序列化接口

public class Employee implements Serializable{
 private static final long serialVersionUID = 857579980893303333L;
 private Integer id;
 private String lastName;
 private String email;
 private String gender;
 private Department dept;//方法省略
}
public class Department implements Serializable{
 private static final long serialVersionUID = 8575799808933023456L;
 private Integer id;
 private String departmenName;
 private List<Employee> emps;
}//方法省略

测试方法如下:

 @Test
 public void test03() throws Exception{
  String resource = "mybatis-config.xml";
  InputStream inputStream = Resources.getResourceAsStream(resource);
  SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  SqlSession openSession=sqlSessionFactory.openSession();  
  SqlSession openSession2=sqlSessionFactory.openSession();  
  try {
   EmployeeMapper mapper=openSession.getMapper(EmployeeMapper.class);
   EmployeeMapper mapper2=openSession2.getMapper(EmployeeMapper.class);
   Employee emp01=mapper.getEmpById(1);
   System.out.println(emp01);
   openSession.close();
   Employee emp02=mapper2.getEmpById(1);
   System.out.println(emp02);
   openSession2.close();
  }finally {
   openSession.close();
  }
 }

运行结果如下:

DEBUG 07-06 12:12:40,674 Cache Hit Ratio [com.atguigu.mybatis.dao.EmployeeMapper]: 0.0  (LoggingCache.java:62) 
DEBUG 07-06 12:12:40,685 ==>  Preparing: select * from tb1_employee where id = ?   (BaseJdbcLogger.java:145) 
DEBUG 07-06 12:12:40,730 ==> Parameters: 1(Integer)  (BaseJdbcLogger.java:145) 
DEBUG 07-06 12:12:40,786 <==      Total: 1  (BaseJdbcLogger.java:145) 
Employee [id=1, lastName=jerry, email=jerry@atguigu.com, gender=0, dept=null]
DEBUG 07-06 12:12:40,838 Cache Hit Ratio [com.atguigu.mybatis.dao.EmployeeMapper]: 0.5  (LoggingCache.java:62) 
Employee [id=1, lastName=jerry, email=jerry@atguigu.com, gender=0, dept=null]
18.和缓存有关的设置/属性:

1)cacheEbabled=true:false;关闭缓存(关闭二级缓存,一级缓存一直可用的)
2)每个select标签都有useCash=“true”
false:不使用缓存(一级缓存依然使用,二级缓存不使用)
3)每个增删改标签的:flushCash=“true”
增删改执行完成后就会清楚缓存
测试:flushCache=“true”,一级和二级缓存就清空了。
4)sqlSession.clearCache();只是清除当前session的一级缓存。
5)localCacheScope:本地缓存作用域(一级缓存session);当前会话的所有数据保存在会话缓存中。
statement可以禁用一级缓存。

19.缓存工作原理示意图

在这里插入图片描述

20.第三方缓存整合

1)导入第三方缓存包即可;
2)导入与第三方缓存整合的适配包
3)mapper.xml中使用自定义缓存

21.第三方整合结构图

在这里插入图片描述

22.MyBatis Generator逆向工程

1.导入逆向包
2.配置文件
大的主目录下配置文件mbg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
 <!-- 
  targetRuntime="MyBatis3Simple":生成简单版的CRUD
  MyBatis3:豪华版
 -->
  <context id="DB2Tables" targetRuntime="MyBatis3Simple">
   <!-- jdbcConnection:指定如何连接到目标数据库 -->
    <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/mybaties?serverTimezone=GMT"
        userId="root"
        password="stoneSml@123">
    </jdbcConnection>
        <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    <!-- javaModelGenerator:指定javaBean的生成策略 
 targetPackage="test.model":目标包名
 targetProject="\MBGTestProject\src":目标工程
 -->
    <javaModelGenerator targetPackage="com.atguigu.mybatis.bean" 
      targetProject=".\src">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    <!-- sqlMapGenerator:sql映射生成策略: -->
    <sqlMapGenerator targetPackage="com.atguigu.mybatis.dao"  
     targetProject=".\conf">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    <!-- javaClientGenerator:指定mapper接口所在的位置 -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mybatis.dao"  
     targetProject=".\src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>
    <!-- 指定要逆向分析哪些表:根据表要创建javaBean -->
    <table tableName="tb1_dept" domainObjectName="Department"></table>
    <table tableName="tb1_employee" domainObjectName="Employee"></table>
  </context>
</generatorConfiguration>
23.逆向工程使用MyBatis3的测试结果
@Test
 public void testMyBatis3() throws IOException{
  SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
  SqlSession openSession = sqlSessionFactory.openSession();
  try{
   EmployeeMapper mapper = openSession.getMapper(EmployeeMapper.class);
   //xxxExample就是封装查询条件的
   //1、查询所有
   //List<Employee> emps = mapper.selectByExample(null);
   //2、查询员工名字中有e字母的,和员工性别是1的
   //封装员工查询条件的example
   EmployeeExample example = new EmployeeExample();
   //创建一个Criteria,这个Criteria就是拼装查询条件
   //select id, last_name, email, gender, d_id from tbl_employee 
   //WHERE ( last_name like ? and gender = ? ) or email like "%e%"
   Criteria criteria = example.createCriteria();
   criteria.andLastNameLike("%e%");
   criteria.andGenderEqualTo("1");
   Criteria criteria2 = example.createCriteria();
   criteria2.andEmailLike("%e%");
   example.or(criteria2);
   List<Employee> list = mapper.selectByExample(example);
   for (Employee employee : list) {
    System.out.println(employee.getId());
   }
}finally{
   openSession.close();
  }
 }   
24. MyBatis工作原理

在这里插入图片描述
在这里插入图片描述
1.
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
2.获取sqlSession对象
返回一个DefaultSQLSession对象,包含Executor和Configuration
这一步会创建Executor对象;
在这里插入图片描述
3.获取接口的代理对象(MapperProxy)
getMapper,使用MapperProxyFactory创建一个MapperProxy的代理对象
代理对象里面包含了,DefaultSqlSession(Executor)
在这里插入图片描述
4.
在这里插入图片描述
缓存中保存的key:方法id+sql+参数xxx
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

25.MyBatis调用总结

1.根据配置文件(全局,sql映射)来初始化Configuration对象
2.创建一个DefaultSqlSession对象,他里面包含Configuration以及Executor(根据全局配置文件中的defaultExecutorType创建出对应的Executor)
3.DefaultSqlSession.getMapper(),拿到Mapper接口对应的MapperProxy;
4.MapperProxy里面有(DefaultSqlSession);
5.执行增删改查方法:
1)调用DefaultSqlSession的增删改查(Executor);
2)会创建一个StatementHandler对象(同时也会创建出ParameterHandler和ResultSetHandler)
3)调用StatementHandler预编译参数以及设置参数值,使用ParameterHandler来给sql设置参数;
4)调用StatementHandler的增删改查方法;
5)ResultSetHandler封装结果
注意:四大对象每个创建的时候都有一个

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值