MyBatis简介

下载地址 : https://github.com/mybatis/mybatis-3

Mybatis特性

  • 首先,这是一个持久层框架。支持定制化 SQL、存储过程以及高级映射等功能。
  • MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数(比如某些数据的拼接)以及获取结果集(不需要再手动获解析结果集)
  • MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old JavaObjects,普通的Java对象)映射成数据库中的记录
  • MyBatis 是一个 半自动的ORM(Object Relation Mapping,指Java实体类对象关系型数据库中的一条记录之间的关系)框架

MyBatis搭建

首先创建maven工程,引入依赖

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<dependencies>
<!-- Mybatis核心 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!-- junit测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- MySQL驱动 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.16</version>
</dependency>
</dependencies>

然后创建MyBatis的核心配置文件,是一个xml文件。整合spring之后,这个配置文件可以省略。不重要。

这里主要用于配置连接数据库的环境以及MyBatis的全局配置信息

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--设置连接数据库的环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver-->
<!--MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<package name="mappers/UserMapper.xml"/>
</mappers>
</configuration>

接着,就可以创建mapper接口 。

MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类。可以通过mybatis里的功能来为其创建代理实现类。当我们调用接口中的方法,就会直接对应一条SQL语句。

1
2
3
public interface UserMapper {
int insertUser();
}

创建MyBatis的映射文件

注意ORMObject Relationship Mapping)对象关系映射。(对象:Java的实体类对象 ,关系:关系型数据库 ,映射:二者之间的对应关系)

Java概念 数据库概念
属性 字段/列
对象 记录/行
1
2
3
4
5
6
7
8
9
10
<?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.mapper.UserMapper">
<!--int insertUser();-->
<insert id="insertUser">
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
</insert>
</mapper>

特殊SQL

在特殊查询中,通常需要获取参数值

MyBatis获取参数值的两种方式 :

  • ${} , 本质就是字符串拼接。注意${}需要手动加单引号。
  • #{} ,本质就是占位符赋值。

模糊查询

select * from t_user where username like "%"#{mohu}"%"

批量删除 :通过一个SQL语句删除多个数据。

这里ids = “1,2,3”

delete from t_user where id in (${ids})

当然,也可以delete from t_user where id = 5 OR id = 6;

动态设置表名 :

select * from ${tableName}

添加功能获取自增的主键:

useGeneratedKeys:设置使用自增的主键,意思是:对于支持自动生成记录主键的数据库,如:MySQL,SQL Server,此时设置useGeneratedKeys参数值为true,在执行添加记录之后可以获取到数据库自动生成的主键ID。(Oracle不支持自动生成主键)

keyProperty:因为增删改有统一的返回值是受影响的行数,因此只能将获取的自增的主键放在传输的参数user对象的某个属性中

1
2
3
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{age},#{sex})
</insert>

自定义映射resultMap

若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射

1
2
3
4
5
6
7
8
id:表示自定义映射的唯一标识 ,type:查询的数据要映射的实体类的类型
<resultMap id="userMap" type="User">
id:设置主键的映射关系
<id property="id" column="id"></id>
property:设置映射关系中实体类中的属性名 ,column:设置映射关系中表中的字段名
<result property="userName" column="user_name"></result>
<result property="password" column="password"></result>
</resultMap>

多对一(一对一)映射处理

使用场景 : 查询员工信息以及员工所对应的部门信息(即多个员工对应一个部门)

可以使用三种方法 :

  • 级联关系
  • 使用 association标签
  • 分步查询(同样可以适用一对多)

例如查询语句为 :

1
2
3
<select id="getEmpAndDeptByEid" resultMap="empDeptMap">
select emp.*,dept.* from t_emp emp left join t_dept dept on emp.did = dept.did where emp.eid = #{eid}
</select>

级联关系 :

1
2
3
4
5
6
7
8
<resultMap id="empDeptMap" type="Emp">
<id column="eid" property="eid"></id>
<result column="ename" property="ename"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
<result column="did" property="dept.did"></result>
<result column="dname" property="dept.dname"></result>
</resultMap>

association标签: 专门用来处理多对一关系

1
2
3
4
5
6
7
8
9
10
11
12
<resultMap id="empDeptMap" type="Emp">
<id column="eid" property="eid"></id>
<result column="ename" property="ename"></result>
<result column="age" property="age"></result>
<result column="sex" property="sex"></result>
//property : 设置需要处理映射关系的属性的属性名。
//javaType : 设置需要处理的类型
<association property="dept" javaType="Dept">
<id column="did" property="did"></id>
<result column="dname" property="dname"></result>
</association>
</resultMap>

分步查询 :

现在要查的是员工以及员工部门,就要先查员工,再根据员工的部分id去部门表里查询部门信息。

具体代码就不写了,大体就是在代码中分两个步骤写,先查一个表、再查一个表。。

优势 : 可以实现延迟加载(懒加载),减少内存消耗。

通过 lazyLoadingEnabledaggressiveLazyLoading开启懒加载。

lazyLoadingEnabled :延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。

aggressiveLazyLoading :按需加载。当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。

一对多映射处理

场景举例 : 查询一个部门信息以及这个部分下的所有员工信息。

可以适用两种方法 :

  • collection标签
  • 分布查询

collection标签

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<resultMap id="deptEmpMap" type="Dept">
<id property="did" column="did"></id>
<result property="dname" column="dname"></result>
<!--ofType:设置collection标签所处理的集合属性中存储数据的类型-->
<collection property="emps" ofType="Emp">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
</collection>
</resultMap>
<!--Dept getDeptEmpByDid(@Param("did") int did);-->
<select id="getDeptEmpByDid" resultMap="deptEmpMap">
select dept.*,emp.* from t_dept dept left join t_emp emp on dept.did =
emp.did where dept.did = #{did}
</select>

动态SQL

Mybatis框架的动态SQL技术是一种根据特定条件动态拼装SQL语句的功能,它存在的意义是为了解决 拼接SQL语句字符串时的痛点问题。

包含 <if> <where> <trim> <foreach> <sql> 等标签。

<trim>用于去掉或添加标签中的内容,常用属性:

  • prefix:在trim标签中的内容的前面添加某些内容
  • prefixOverrides:在trim标签中的内容的前面去掉某些内容
  • suffix:在trim标签中的内容的后面添加某些内容
  • suffixOverrides:在trim标签中的内容的后面去掉某些内容