1.MyBatis
1.1、什么是MyBatis?
- MyBatis是一款优秀的持久层框架,用于简化JDBC开发
- MyBatis本是Apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到google code,并且改名为MyBatis。2013年11月迁移到Github
- 官网:https://mybatis.p2hp.com/
持久层
- 负责将数据保存到数据库的那一层代码
- JavaEE三层架构:表现层、业务层、持久层
框架
- 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型
- 在框架的基础之上构建软件编写更加高效、规范、通用、可扩展
JDBC缺点

MyBatis简化

1.2、MyBatis快速入门

提示:Mybatis的持久层接口命名规范为 XxxMapper,也称为Mapper接口。
1). 创建springboot工程,并导入 mybatis的起步依赖、mysql的驱动包、lombok。


项目工程创建完成后,自动在pom.xml文件中,导入Mybatis依赖和MySQL驱动依赖。如下所示:

2). 数据准备:创建用户表user,并创建对应的实体类User。
- 用户表 user(如果已经存在,就不用创建了)
create table user(
id int unsigned primary key auto_increment comment 'ID,主键',
username varchar(20) comment '用户名',
password varchar(32) comment '密码',
name varchar(10) comment '姓名',
age tinyint unsigned comment '年龄'
) comment '用户表';
insert into user(id, username, password, name, age) values (1, 'daqiao', '123456', '大乔', 22),
(2, 'xiaoqiao', '123456', '小乔', 18),
(3, 'diaochan', '123456', '貂蝉', 24),
(4, 'lvbu', '123456', '吕布', 28),
(5, 'zhaoyun', '12345678', '赵云', 27);
- 实体类:实体类的属性名与表中的字段名一一对应。 实体类放在
com.itheima.pojo包下。
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id; //ID
private String username; //用户名
private String password; //密码
private String name; //姓名
private Integer age; //年龄
}
3). 配置Mybatis
在 application.properties 中配置数据库的连接信息。
#数据库访问的url地址
spring.datasource.url=jdbc:mysql://localhost:3306/web
#数据库驱动类类名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#访问数据库-用户名
spring.datasource.username=root
#访问数据库-密码
spring.datasource.password=root@1234
上述的配置,可以直接复制过去,不要敲错了。 全部都是 spring.datasource.xxxx 开头。
4). 编写Mybatis程序:编写Mybatis的持久层接口,定义SQL语句(注解)
在创建出来的springboot工程中,在引导类所在包下,在创建一个包 mapper 。在 mapper 包下创建一个接口 UserMapper ,这是一个持久层接口(Mybatis的持久层接口规范一般都叫 XxxMapper)。
UserMapper接口的内容如下:
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
/**
* 查询全部
*/
@Select("select * from user")
public List<User> findAll();
}
注解说明:
- @Mapper注解:表示是mybatis中的Mapper接口
程序运行时,框架会自动生成接口的实现类对象(代理对象),并给交Spring的IOC容器管理
- @Select注解:代表的就是select查询,用于书写select查询语句
5). 单元测试
在创建出来的SpringBoot工程中,在src下的test目录下,已经自动帮我们创建好了测试类 ,并且在测试类上已经添加了注解 @SpringBootTest,代表该测试类已经与SpringBoot整合。
该测试类在运行时,会自动通过引导类加载Spring的环境(IOC容器)。我们要测试那个bean对象,就可以直接通过@Autowired注解直接将其注入进行,然后就可以测试了。
测试类代码如下:
@SpringBootTest
class SpringbootMybatisQuickstartApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testFindAll(){
List<User> userList = userMapper.findAll();
for (User user : userList) {
System.out.println(user);
}
}
}
运行结果:


1.3、数据库连接池
在前面我们所讲解的mybatis中,使用了数据库连接池技术,避免频繁的创建连接、销毁连接而带来的资源浪费。
下面我们就具体的了解下数据库连接池。
-
介绍
1). 没有数据库连接池的情况

客户端执行SQL语句:要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行后又需要关闭连接对象从而释放资源,每次执行SQL时都需要创建连接、销毁链接,这种频繁的重复创建销毁的过程是比较耗费计算机的性能。
2). 有数据库连接池的情况

数据库连接池是个容器,负责分配、管理数据库连接(Connection)
- 程序在启动时,会在数据库连接池(容器)中,创建一定数量的Connection对象
允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
- 客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以复用)
释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
- 客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象
数据库连接池的好处:
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
-
产品
要怎么样实现数据库连接池呢?
- 官方(sun)提供了数据库连接池标准(javax.sql.DataSource接口)
- 功能:获取连接
-
public Connection getConnection() throws SQLException;
-
- 第三方组织必须按照DataSource接口实现
常见的数据库连接池:C3P0 、****DBCP 、****Druid 、****Hikari (springboot默认)
现在使用更多的是:Hikari、Druid (性能更优越)
1). Hikari(追光者) [默认的连接池]

从控制台输出的日志,我们也可以看出,springboot底层默认使用的数据库连接池就是 Hikari。
2). Druid(德鲁伊)
- Druid连接池是阿里巴巴开源的数据库连接池项目
- 功能强大,性能优秀,是Java语言最好的数据库连接池之一
如果我们想把默认的数据库连接池切换为Druid数据库连接池,只需要完成以下两步操作即可:
参考官方地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter
①. 在pom.xml文件中引入依赖
<dependency>
<!-- Druid连接池依赖 -->
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.19</version>
</dependency>
②. 在application.properties中引入数据库连接配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/web
spring.datasource.druid.username=root
spring.datasource.druid.password=1234
配置完毕之后,我们再次运行单元测试,大家会看到控制台输出的日志中,已经将连接池切换为了 Druid连接池。

1.4、增删改查操作
-
删除
- 需求:根据ID删除用户信息
- SQL:delete from user where id = 5;
- Mapper接口方法:
- 方式一:
-
/** * 根据id删除 */ @Delete("delete from user where id = 5") public void deleteById();
这种方式执行删除操作,调用deleteById方法只能删除id为5的用户信息,因为将id直接写死在代码中了,不可取。
- 方式二:
/**
* 根据id删除
*/
@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);
在Mybatis中,我们可以通过参数占位符号 #{...} 来占位,在调用deleteById方法时,传递的参数值,最终会替换占位符。
- 编写单元测试方法进行测试
-
在单元测试类中,增加如下测试方法.
-
@Test public void testDeleteById(){ userMapper.deleteById(36); }
-
运行单元测试,结果如下:

运行之后,我们发现,#{...} 占位符,其实最终被替换成了 ?占位符,生成的是预编译的SQL语句。【推荐】
- DML语句执行完毕,是有返回值的,我们可以为Mapper接口方法定义返回值来接收,如下:
-
/** * 根据id删除 */ @Delete("delete from user where id = #{id}") public Integer deleteById(Integer id);
-
Integer类型的返回值,表示DML语句执行完毕影响的记录数。
- Mybatis的提供的符号,有两个,一个是
#{...},另一个是${...},区别如下:
| 符号 | 说明 | 场景 | 优缺点 |
|---|---|---|---|
| # | 占位符。执行时,会将#{…}替换为?,生成预编译SQL | 参数值传递 | 安全、性能高 (推荐) |
| $ | 拼接符。直接将参数拼接在SQL语句中,存在SQL注入问题 | 表名、字段名动态设置时使用 | 不安全、性能低 |
那在企业项目开发中,强烈建议使用 #{...} 。
-
新增
- 需求:添加一个用户
- SQL:insert into user(username,password,name,age) values('zhouyu','123456','周瑜',20);
- Mapper接口:
/**
* 添加用户
*/
@Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})")
public void insert(User user);
如果在SQL语句中,我们需要传递多个参数,我们可以把多个参数封装到一个对象中。然后在SQL语句中,我们可以通过#{对象``属性``名}的方式,获取到对象中封装的属性值。
- 单元测试:
在测试类中添加测试方法,代码如下:
@Test
public void testinsert() {
User user = new User(null,"zhouyu","123456","周瑜",18);
userMapper.insert(user);
}
运行结果如下:

-
修改
- 需求:根据ID更新用户信息
- SQL:update user set username = 'zhouyu', password = '123456', name = '周瑜', age = 20 where id = 1;
- Mapper接口方法:
/**
* 根据id更新用户信息
*/
@Update("update user set username = #{username},password = #{password},name = #{name},age = #{age} where id = #{id}")
public void update(User user);
- 单元测试:
在测试类中添加测试方法,代码如下:
@Test
public void testupdate() {
User user = new User(1,"zhouyu","123456","周瑜",20);
userMapper.update(user);
}
运行结果如下:

-
查询
- 需求:根据用户名和密码查询用户信息
- SQL:select* fromuser whereusername = 'zhouyu' and password = '123456'
- Mapper接口方法:
/**
* 根据用户名和密码查询用户信息
*/
@Select("select * from user where username = #{username} and password = #{password}")
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);
@param注解的作用是为接口的方法形参起名字的。(由于用户名唯一的,所以查询返回的结果最多只有一个,可以直接封装到一个对象中)
- 单元测试:
在测试类中添加测试方法,代码如下:
@Test
public void testselect() {
User user = userMapper.findByUsernameAndPassword("zhouyu","123456");
System.out.println(user);
}
运行结果如下:

说明:基于官方骨架创建的springboot项目中,接口编译时会保留方法形参名,@Param注解可以省略 (#{形参名})。

1.5、XML映射配置
Mybatis的开发有两种方式:
-
注解
-
XML
-
XML配置文件规范
使用Mybatis的注解方式,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。
在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
- XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

浙公网安备 33010602011771号