目录和知识汇总
- 1.分步查询
- 2.查询的延迟加载
- 3.查询部门的时候将部门对应的所有的员工信息也查询出来
- 4.定义使用分布查询完成
- 5.需求:封装Employee
- 6.动态sql
- 7.OGNL
- 8.使用trim进行查询
- 9.choose标签
- 10.set标签
- 11.foreach标签的使用(批量查询)
- 12.foreach标签的使用(批量保存)
- 13.Oracle数据库批量保存
- 14.mybatis中两个重要的内置参数
- 15.绑定变量
- 16.sql标签
- 17.MyBatis的缓存机制
- 18.和缓存有关的设置/属性:
- 19.缓存工作原理示意图
- 20.第三方缓存整合
- 21.第三方整合结构图
- 22.MyBatis Generator逆向工程
- 23.逆向工程使用MyBatis3的测试结果
- 24. MyBatis工作原理
- 25.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!=""">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
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!=""">
last_name like #{lastName} and
</if>
<if test="email!=null and email.trim()!=""">
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!=""">
and last_name like #{lastName}
</if>
<if test="email!=null and email.trim()!=""">
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封装结果
注意:四大对象每个创建的时候都有一个