【基础知识】_MyBatis

MyBatis

MyBatis入门

MyBatis简介

mybatis与jdbc template相比最大的优点:使用配置文件动态配置sql语句,实现sql语句与java代码解耦,将sql开发人员和java开发人员的任务分开。

MyBatis开发步骤

  1. 在pom.xml文件中导入MyBatis坐标和其他相关坐标

  2. 在MySQL数据库中创建数据表

  3. 在项目domain包中创建数据表对应的javabean实体类

  4. 在resources文件夹下创建一个和dao层包同名的文件夹,比如:jia/zheng/mapper,在该文件夹中创建数据表对应的xml映射文件,将操作该数据表的所有sql语句都放到该映射文件中。

  5. 在resources文件夹下创建MyBatis的核心配置文件sqlMapConfig.xml

  6. 编写使用代码并使用

MyBatis映射文件概述

映射文件中主要可以配置增、删、改、查四种操作:

MyBatis核心配置文件概述

核心配置文件中的配置标签具有固定的顺序要求,必须按照如下图中的顺序来配置,否则会报错。

  • environments标签:数据库环境的配置,支持多环境配置,可以指定所要使用的环境配置。

  • mapper标签:

    resource表示相对class路径,而我们项目中resources文件夹下的文件就是直接放在class路径下的。

    ****

  • properties标签:实际开发中,习惯将数据源的配置信息单独抽取成一个properties文件,该标签可以加载额外配置的properties文件。

  • typeAliases标签:类型别名标签用来给项目中的JavaBean实体类设置一个短的别名。(注意吃此处是在核心配置文件中设置别名,然后再映射文件中使用别名。)

MyBatis使用时需要的API

  • SqlSession工厂构建器SqlSessionFactoryBuilder
  • SqlSession工厂对象SqlSessionFactory
  • SqlSession会话对象SqlSession

MyBatis的Dao层实现

采用 Mybatis 的代理开发方式实现 DAO 层的开发,这种方式是我们后面进入企业的主流。
Mapper 接口开发方法只需要程序员编写Mapper 接口(相当于Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体与之前使用template时每次都要编写的接口的实现类是一样的。

一般就是先创建好接口,定义好所需要使用的抽象方法,然后根据该接口在相应映射文件中配置mapper标签。

使用代理开发方式时要先通过MyBatis框架获得相应接口的实现类的实例对象。

MyBatis映射文件深入

动态sql语句

在MyBatis的映射文件中,前面我们的SQL都是比较简单的,有时候业务逻辑复杂时,我们的SQL应该是动态变化的。

<if>

我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询, 如果username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

<foreach>

<foreach>标签用于遍历集合,它的属性:

  • collection:代表要遍历的集合元素,注意编写时不要写#{}
  • open:代表语句的开始部分
  • close:代表结束部分
  • item:代表遍历集合的每个元素,生成的变量名
  • sperator:代表分隔符

SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的 。

MyBatis核心配置文件深入

typeHandlers标签

创建并配置使用自定义的数据库数据与java数据类型转换器,最常用的例子就是将数据库中的1970年至今毫秒值取出时,自动转换成java中的Date类型数据。

plugins标签

MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper将分页的复杂操作进行封装,使得使用简单的方式即可获得分页的相关数据。

  1. 在pom.xml文件中导入通用PageHelper坐标

  2. 在sqlMapConfig.xml文件中配置PageHelper插件

  3. 使用分页工具

  4. 还可以使用分页工具的其他方法获得分页相关的其他参数

MyBatis的多表操作

创建JavaBean实体时,在类中添加另一个JavaBean实体的对象作为私有属性。

1
2
3
4
5
6
7
8
/**
* 员工从表数据对象对应的封装实体。
*/
public class Employee {
private int id;
private String name;
private int age;
private Department department;
1
2
3
4
5
6
7
8
9
10
/**
* 部门主表数据对象对应的封装对象
*/
public class Department {
private int id;
private String dep_name;
private String dep_location;

//因为部门和员工是一对多的关系,所以部门中包含的应该是员工集合属性。
private List<Employee> employeeList;

在映射文件中配置,通过使用<resultMap>标签和<collection>标签使sql语句的查询结果中预期的列元素放入我们预设的JavaBean类的实例对象中。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<mapper namespace="jia.zheng.mapper.EmployeeMapper">

<!--重要:用resultMap标签来手动指定sql查询结果字段与java封装实体对象属性之间的映射关系-->
<resultMap id="employeeMap" type="employee">
<!--column:查询结果表中字段的名称 property:封装实体的属性名称-->
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="dep_id" property="department.id"/>
<result column="dep_name" property="department.dep_name"/>
<result column="dep_location" property="department.dep_location"/>
</resultMap>

<select id="findAllEmployee" resultMap="employeeMap">
SELECT *,d.id did FROM employee e,department d WHERE e.dep_id=d.id;
</select>
</mapper>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<mapper namespace="jia.zheng.mapper.DepartmentMapper">
<resultMap id="departmentMap" type="department">
<result column="did" property="id"/><!--为了区分查询结果表中员工和部门的id字段,我们在查询表中添加了一个did字段来表示部门的id字段,eid字段表示员工的id字段。-->
<result column="dep_name" property="dep_name"/>
<result column="dep_location" property="dep_location"/>

<!--配置java封装对象中的集合信息
property:java封装对象中的集合名称
ofType:当前集合中数据的类型
-->
<collection property="employeeList" ofType="employee">
<!--将查询结果表中数据与employee中属性进行映射-->
<result column="eid" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
</collection>

</resultMap>
<select id="findAllDepartment" resultMap="departmentMap">
SELECT *,d.id did,e.id eid FROM department d,employee e WHERE d.id=e.dep_id;
</select>
</mapper>

MyBatis注解开发

将sqlMapConfig.xml文件中的加载映射文件改成扫描使用注解的类所在的包,因为映射关系还是在的。

1
2
3
4
5
<!--加载映射关系,虽然用注解代替了mapper映射文件,但是还是有映射关系的。-->
<mappers>
<!--指定使用了mybatis注解的接口所在的包-->
<package name="jia.zheng.mapper"/>
</mappers>

简单增删改查只需要在接口相关抽象方法上添加一个相应注解即可,主要关注多表查询注解配置。

  • 一对一查询:

  • 一对多查询:

  • 多对多查询:

Spring整合MyBatis

整合思路

整合步骤
  1. 将SqlSessionFactory配置到Spring容器中

  2. 扫描Mapper,让Spring容器产生Mapper实现类

  3. 在applicationContext.xml文件中配置声明式事务控制

  4. 修改Service实现类代码