一、MyBatis入门
1.1 快速入门
1.1.1 创建SpringBoot-MyBatis工程
1.1.2 创建数据库
/*
Navicat Premium Data Transfer
Source Server : localhost
Source Server Type : MySQL
Source Server Version : 80013
Source Host : localhost:3306
Source Schema : spingboot-mybatis-demo
Target Server Type : MySQL
Target Server Version : 80013
File Encoding : 65001
Date: 05/01/2024 10:29:12
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL,
`name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`gender` bigint(20) NULL DEFAULT NULL,
`phone` varchar(11) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '张三', 55, 1, '18800000000');
INSERT INTO `user` VALUES (2, '李四', 45, 1, '18800000001');
INSERT INTO `user` VALUES (3, '王五', 38, 1, '18800000002');
INSERT INTO `user` VALUES (4, '赵六', 42, 2, '18800000003');
INSERT INTO `user` VALUES (5, '田七', 37, 1, '18800000004');
INSERT INTO `user` VALUES (6, '刘八', 48, 1, '18800000005');
SET FOREIGN_KEY_CHECKS = 1;
1.1.3 加载POM依赖
<!-- Mybatis的起步依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- MySQL启动包 -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Mybatis 单元测试依赖 -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter-test</artifactId>
<version>3.0.3</version>
<scope>test</scope>
</dependency>
1.1.4 配置Mytabis
# 数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# URL
spring.datasource.url=jdbc:mysql://localhost:3306/spingboot-mybatis-demo
# 用户名
spring.datasource.username=root
# 密码
spring.datasource.password=root
注意:如果properties文件中出现中文乱码
1.1.5 pojo:编写用户实体类
省略
1.1.6 service:编写查询用户信息的结构
@Mapper // 在运行时,会自动生成该接口的实现类对象(代理对象),并且将该对象交给IOC容器管理
public interface UserMapper {
/**
* 查询全部用户信息
*/
@Select("select * from user")
public List<User> userList();
}
1.1.7 测试
@SpringBootTest // springboot 整合单元测试的注解
class SpringbootMybatisApplicationTests {
@Autowired
private UserMapper userMapper;
@Test
public void testUserList() {
List<User> users = userMapper.userList();
users.forEach(user -> {
System.out.println(user);
});
}
}
1.1.8 默认在MyBatis中编写SQL是没有提示的,可以做如下配置
如果编写的SQL语句表名报红,需要在IDEA中连接数据库
1.2 数据库连接池
- 数据库连接池是一个容器,负责分配,管理数据库连接
- 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个
- 释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
- 优点:
- 资源重用
- 提升系统响应速度
- 避免数据库连接遗漏
<!-- druid 数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.16</version>
</dependency>
连接池配置
# 数据库连接池驱动
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
# 初始化时建立物理连接的个数。初始化发生在显示调用init方法,或者第一次getConnection时
spring.datasource.druid.initial-size=10
# 最小连接池数量
spring.datasource.druid.min-idle=10
# 最大连接池数量
spring.datasource.druid.max-active=200
# 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置
spring.datasource.druid.max-wait=60000
# 关闭空闲连接的检测时间间隔.Destroy线程会检测连接的间隔时间,如果连接空闲时间大于等于minEvictableIdleTimeMillis则关闭物理连接。
spring.datasource.druid.time-between-eviction-runs-millis=60000
# 连接的最小生存时间.连接保持空闲而不被驱逐的最小时间
spring.datasource.druid.min-evictable-idle-time-millis=300000
# 验证数据库服务可用性的sql.用来检测连接是否有效的sql 因数据库方言而差, 例如 oracle 应该写成 SELECT 1 FROM DUAL
spring.datasource.druid.validation-query=SELECT 1
# 申请连接时检测空闲时间,根据空闲时间再检测连接是否有效.建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRun
spring.datasource.druid.test-while-idle=true
# 申请连接时直接检测连接是否有效.申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
spring.datasource.druid.test-on-borrow=false
# 归还连接时检测连接是否有效.归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
spring.datasource.druid.test-on-return=false
# 开启PSCache
spring.datasource.druid.pool-prepared-statements=true
# 设置PSCache值
spring.datasource.druid.max-pool-prepared-statement-per-connection-size=20
# 连接出错后再尝试连接三次
spring.datasource.druid.connection-error-retry-attempts=3
# 数据库服务宕机自动重连机制
spring.datasource.druid.break-after-acquire-failure=true
# 连接出错后重试时间间隔
spring.datasource.druid.time-between-connect-error-millis=300000
# 异步初始化策略
spring.datasource.druid.async-init=true
# 是否自动回收超时连接
spring.datasource.druid.remove-abandoned=true
# 超时时间(以秒数为单位)
spring.datasource.druid.remove-abandoned-timeout=1800
# 事务超时时间
spring.datasource.druid.transaction-query-timeout=6000
# 连接池的过滤器的属性
spring.datasource.druid.filters=stat,wall,log4j2
# 合并多个DruidDataSource的监控数据
spring.datasource.druid.use-global-data-source-stat=true
# 通过connectProperties属性来打开mergeSql功能;慢SQL记录
spring.datasource.druid.connection-properties=druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000
1.3 LomBok
通过注解,自动生成构造器,getter/setter、equals、hashCode、toString等方法,并且可以自动化生成日志变量,简化Java开发、提高效率
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id;
private String name;
private Integer age;
private Integer gender;
private String phone;
}
二、MyBatis基础操作
2.1 删除
@Delete("delete from emp where id= #{id}")
public void deleteEmp(Integer id);
2.2 新增
注意:如果需要新增主键返回,需要增加@Options注解
@Options(keyProperty = "id", useGeneratedKeys = true) // 主键返回
@Insert("INSERT INTO emp(username,password,name,gender,image,job,entrydate,create_time,update_time,dept_id) " +
"VALUES(#{username}, #{password}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{createTime}, #{updateTime}, #{deptId})")
public void insertEmp(Emp emp);
2.3 修改
@Update("update emp set dept_id=#{deptId}, update_time=#{updateTime} where id=#{id}")
public void updateEmp(Emp emp);
2.3 查询
注意:如果存在驼峰命名的变量,需要开启Mybatis的驼峰命名封装
mybatis.configuration.map-underscore-to-camel-case=true
2.3.1 根据ID查询员工信息
@Select("select * from emp where id=#{id}")
public Emp selectEmpById(Integer id);
2.3.2 模糊查询
- 方式一:
${}
注意:模糊查询应该使用${}传递参数,而不是#{}
@Select("select * from emp where name like '%${name}%' and gender=#{gender}")
public List<Emp> selectEmpWhere(Emp emp);
- 方式二:
concat('%',#{},'%')
【推荐使用】
@Select("select * from emp where name like concat('%', #{name}, '%') and gender=#{gender}")
public List<Emp> selectEmpWhere(Emp emp);
三、XML映射文件
3.1 规范
- XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
- XML映射文件的namespace属性为Mapper接口全限定名一致
- XML映射文件中SQL语句的ID与Mapper接口中的方法名一致,并保持返回类型一致。
XML文件约束
<?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="org.mybatis.example.BlogMapper">
...
</mapper>
3.2 MybatisX
快速定位XML文件的位置
3.3 案例
<select id="selectEmpWhere" resultType="com.ming.pojo.Emp">
select * from emp where name like concat('%', #{name}, '%') and gender=#{gender} order by update_time desc
</select>
属性 | 说明 |
---|---|
resultType | 返回值类型:指的是单条记录所封装的类型 |
四、动态SQL
随着用户的输入或外部条件的变化而变化的SQL语句,我们称之为
动态SQL
4.1 IF语句
<select id="selectEmpWhere" resultType="com.ming.pojo.Emp">
select * from emp
<where>
<if test="name != null">
name like concat('%', #{name}, '%')
</if>
<if test="gender != null">
and gender=#{gender}
</if>
</where>
order by update_time desc
</select>
<update id="updateEmp">
update emp
<set>
<if test="deptId != null">
dept_id=#{deptId},
</if>
<if test="updateTime != null">
update_time=#{updateTime}
</if>
</set>
<where>
<if test="id != null">
id = #{id}
</if>
</where>
</update>
4.2 ForEach语句【批量删除】
<delete id="deleteEmps">
delete from emp
<where>
id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</where>
</delete>
属性 | 说明 |
---|---|
collection | 遍历的集合 |
item | 遍历出来的元素 |
separator | 分隔符 |
open | 遍历之前拼接的SQL片段 |
close | 遍历结束后拼接的SQL片段 |
4.3 <sql><include>
SQL片段的抽取和引用,一般联合使用
<sql id="commonSelect">
id,username,password,name,gender,image,job,entrydate,create_time,update_time,dept_id
</sql>
<select id="selectEmpWhere" resultType="com.ming.pojo.Emp">
select
<include refid="commonSelect"></include>
from emp
</select>