今天无脑将介绍 Mybatis - Plus + Spring Boot 框架的基本使用,开启低代码时代,分享给大家,希望帮助大家大幅提高开发能力!
一、Mybatis - Plus 介绍
1.1 概述
MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
MyBatis-Plus 提供了强大的条件构造器(Wrapper)来构建查询条件,包括 QueryWrapper 和UpdateWrapper 等。
1.2 特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美解决主键问题
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 分页插件支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多种数据库
- 内置性能分析插件:可输出 SQL 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
二、Mybatis - Plus 框架使用
2.1 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Mybatis - Plus 依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
2.2 mapper 层和 service 层
/**
* <p>
* 存储用户信息的表 服务实现类
* </p>
*
* @author qf
* @since 2023-11-02
*/
@Service
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {
}
/**
* <p>
* 存储用户信息的表 Mapper 接口
* </p>
*
* @author qf
* @since 2023-11-02
*/
@Mapper
public interface UsersMapper extends BaseMapper<Users> {
}
2.3 使用内置方法执行 SQL 语句
- QueryWrapper<Users>.lambda():表示是使用 Lambda 表达式的方法进行操作。
2.3.1 查询
- select(String... columns):指定查询的字段,可以选择需要查询的字段。
- selectOne:用于查询满足条件的单个实体记录。
- selectList:用于查询数据库并返回一个列表。
- Integer selectCount(Wrapper<T> queryWrapper):根据条件查询记录数量
- T selectById(Serializable id):根据主键查询一条记录
- List<T> selectBatchIds(Collection<? extends Serializable> idList):根据主键批量查询记录
- List<T> selectByMap(Map<String, Object> columnMap):根据条件查询记录
2.3.1.1 无条件和有条件查询
// 查询单个用户数据
QueryWrapper<Users> queryWrapper = new QueryWrapper<>();
queryWrapper.lambda().eq(Users::getId,9999);
Users users = usersMapper.selectOne(queryWrapper);
// 查询 id 为 9999 的用户数据
QueryWrapper<Users> qw = new QueryWrapper<>();
qw.lambda().eq(Users::getId,9999);
List<Users> users = usersMapper.selectList(qw);
// 查询 id 大于 9999 的用户数据
QueryWrapper<Users> qw = new QueryWrapper<>();
qw.lambda().gt(Users::getId,9999);
List<Users> users = usersMapper.selectList(qw);
// 查询 id 小于等于 9999 的用户数据
qw.lambda().le(Users::getId,9999);
// 查询 id 在 [3000026, 3000030] 的数据,包头包尾
qw.lambda().between(Users::getId,3000026, 3000030);
// 查询 id 包含 6 的用户数据
qw.lambda().like(Users::getId,6);
// 查询 id 不包含 6 的用户数据
qw.lambda().notLike(Users::getId,6);
// 查询 id 等于 3000026,并且 密码为 123456 的用户数据
qw.lambda()
.and(i -> i.eq(Users::getId, 3000026))
.and(i -> i.eq(Users::getPassword, 123456));
// 下面都查询 id 等于 3000027,或 密码为 123456 的用户数据
qw.lambda()
.and(i -> i.eq(Users::getId, 3000027))
.or(i -> i.eq(Users::getPassword, 123456));
qw.lambda()
.or(i -> i.eq(Users::getId, 3000027))
.or(i -> i.eq(Users::getPassword, 123456));
// 下面都查询 id 不等于 3000027,或 密码不是 123456 的用户数据
qw.lambda()
.not(i -> i.eq(Users::getId, 3000027))
.not(i -> i.eq(Users::getPassword, 123456));
// 按照 id 进行降序排序查询数据
qw.lambda().orderByDesc(Users::getId);
List<Users> users = usersMapper.selectList(qw);
// 查询 u_id 、u_password 用户数据
qw.lambda().select(Users::getId, Users::getPassword);
List<Users> users = usersMapper.selectList(qw);
// 查询 id 在 小于 3000028 的语句里的数据,如 in (...,3000028)
qw.inSql("u_id", "select u_id from users where u_id < 3000028");
List<Users> users = usersMapper.selectList(qw);
2.3.1.2 分页查询
- 查询会有问题,打印的是全部数据。
/* Page<Users> page = new Page<>(1,2);
QueryWrapper<Users> qw = new QueryWrapper<>();
qw.lambda().ne(Users::getId,9999);
IPage<Users> userPage = usersMapper.selectPage(page, qw);
List<Users> users = userPage.getRecords();
System.out.println(users);*/
IPage<Users> page = Page.of(1, 2);
QueryWrapper<Users> qw = new QueryWrapper<>();
qw.lambda().ge(Users::getId,99990);
List<Users> list = iUsersService.list(page, qw);
System.out.println(list);
2.3.1.3 分组查询
- 无 having 条件
// 查询 role_id 对应的数量总和
qw.select("role_id","count(role_id) as c").groupBy("role_id");
List<Map<String, Object>> users = usersMapper.selectMaps(qw);
// 打印结果:
// [{c=3, role_id=1}, {c=92, role_id=2}, {c=5, role_id=3}, {c=8, role_id=4}, ......]
- 有 having 条件
// 查询数量大于等于 5 且 小于等于 7 的数据
qw.select("role_id","count(role_id) as c")
.groupBy("role_id").having("c >= {0} and c <= {1}",5,7);
List<Map<String, Object>> users = usersMapper.selectMaps(qw);
// 打印结果:
// [{c=5, role_id=3}, {c=6, role_id=5}, {c=7, role_id=6}]
// 查询数量 在 (5,7,6) 里的数据
qw.select("role_id","count(role_id) as c").groupBy("role_id").having("c in (5,7,6)");
List<Map<String, Object>> users = usersMapper.selectMaps(qw);
// 打印结果:
// [{c=5, role_id=3}, {c=6, role_id=5}, {c=7, role_id=6}]
2.3.1.4 自定义查询条件
- apply(String applySql, Object... params):自定义 SQL 条件
qw.apply("u_id >= {0} and u_password = {1} ", 9999, "123456");
List<Users> users = usersMapper.selectList(qw);
2.3.1.5 批量查询
- List<T> selectBatchIds(Collection<? extends Serializable> idList):根据主键批量查询记录。
// 批量查询 id 为 9999,3000026,3000027 的用户数据
List<Integer> list = new ArrayList<>();
Collections.addAll(list,9999,3000026,3000027);
List<Users> users = usersMapper.selectBatchIds(list);
2.3.2 增加
- int insert(T entity):插入一条记录。
- int insertBatchSomeColumn(List<T> entityList):批量插入记录。
- int insertOrUpdate(T entity):插入或更新一条记录。
- int insertOrUpdateBatchSomeColumn(List<T> entityList):批量插入或更新记录。
// 插入一条用户记录
Users users = new Users();
users.setId(1000);
users.setPassword("123");
users.setImgUrl(null);
users.setIsActive(true);
users.setIsDeleted(true);
users.setRoleId(1);
int count = usersMapper.insert(users);
2.3.3 更新
- int updateById(T entity):根据主键更新一条记录
- int update(T entity, Wrapper<T> updateWrapper):根据条件更新记录
- int updateBatchById(List<T> entityList):批量更新记录
// 根据 id 为 1000 进行修改用户数据
Users users = new Users();
users.setId(1000);
users.setPassword("12356");
users.setImgUrl(null);
users.setIsActive(true);
users.setIsDeleted(true);
users.setRoleId(1);
UpdateWrapper<Users> uw = new UpdateWrapper<>();
uw.lambda().eq(Users::getId, 1000);
int count = usersMapper.update(users, uw);
2.3.4 删除
- int deleteById(Serializable id):根据主键删除一条记录。
- int deleteById(T entity):根据对象删除一条记录。
- int deleteByMap(Map<String, Object> columnMap):根据条件删除记录
- int delete(Wrapper<T> queryWrapper):根据条件删除记录。
- int deleteBatchIds(@Param("coll") Collection<?> idList):批量删除。
// 根据用户对象的主键进行删除
Users users = new Users();
users.setId(1000);
users.setPassword("12356");
users.setImgUrl(null);
users.setIsActive(true);
users.setIsDeleted(true);
users.setRoleId(1);
int count = usersMapper.deleteById(users);
三、自定义 SQL
@Select、@Update、@Insert、@Delete 注解或者 XML 映射文件来定义自定义 SQL 查询。
- 注意:不符合驼峰命名法的还是要自己手写字段映射。
3.1 案例
// 查询 id 小于特定值的用户数据
@Select("Select * from users where u_id < #{id};")
@ResultMap("userResultMap")
List<Users> selectByUserId(@Param("id") Integer id);
<mapper namespace="com.qf.zzp.mybatis_plus.mapper.UsersMapper">
<resultMap id="userResultMap" type="com.qf.zzp.mybatis_plus.entity.Users">
<id column="u_id" property="id"/>
<result column="u_password" property="password"/>
</resultMap>
</mapper>
实体类:
/**
* 用户
* <p>
* 存储用户信息的表
* </p>
*
* @author qf
* @time 2023/11/03
* @since 2023-11-02
* @see java.io.Serializable
* @see java.lang.RuntimePermission
*/
@TableName(value = "users")
@Data
public class Users implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 用户ID
*/
@TableId(type = IdType.AUTO)
private Integer id;
/**
* 密码
*/
@TableField(value = "u_password")
private String password;
/**
* 图片路径
*/
private String imgUrl;
/**
* 激活状态 (1=激活, 0=未激活)
*/
private Boolean isActive;
/**
* 角色 ID
*/
private Integer roleId;
/**
* 删除状态 (1=未删除, 0=已删除)
*/
private Boolean isDeleted;
}
四、多表查询
多表关联:Mybatis - Plus 还未实现
- join(String sql):进行多表关联查询。
queryWrapper.join("JOIN dept d ON d.id = user.dept_id");
五、内置方法说明
- eq() :是一种条件构造器方法,通常用于构建查询条件,用于查询时筛选数据库表中某一列等于指定值的记录。
- gt() :通常用于创建查询条件,以检索大于某个特定值的数据记录。
- ge():大于等于条件查询。
- ne():不等于条件查询。
- lt():小于条件查询。
- le():小于等于条件查询。
- between("column_name", minValue, maxValue):区间条件查询。
- notBetween("column_name", minValue, maxValue):反向区间条件查询。
- like():模糊查询。
- notLike():反向模糊查询。
- in("column_name", value1, value2, value3):IN 条件查询。
- and() :用于在查询条件中添加一个 "AND" 条件,将多个条件组合为一个条件,所有条件必须同时满足。
- or() :用于在查询条件中添加一个 "OR" 条件,允许满足其中任何一个条件即可。
- not() :用于对条件进行取反操作,即排除满足条件的记录。
- orderByAsc(String... columns):升序排序。
- orderByDesc(String... columns):降序排序。
- groupBy(String... columns):指定 GROUP BY 子句中的字段。
-
- having(String sqlHaving, Object... params):指定 HAVING 子句中的条件。
- inSql(String column, String inValue):使用子查询作为 IN 条件。
- apply(String applySql, Object... params):自定义 SQL 条件
空值条件
- isNull(String column):字段为 null 条件
- isNotNull(String column):字段不为 null 条件
queryWrapper.isNull("address");
queryWrapper.isNotNull("phone");
嵌套条件
-
- nested(Consumer<QueryWrapper<T>> consumer):嵌套的查询条件,可以使用 and 和 or 连接多个条件。
queryWrapper.nested(qw -> qw.eq("age", 25).or().like("name", "John"));
Lock 超时条件
-
- last(String lastSql):添加在 SQL 的最后,可用于添加 FOR UPDATE 等锁定条件。
queryWrapper.last("FOR UPDATE");
六、PageHelper 分页插件的使用
6.1 PageHelper功能介绍
PageHelper是一个用于MyBatis的分页插件,它提供了丰富的功能来简化和增强数据库分页查询的操作。以下是PageHelper插件的一些主要功能:
- 数据库分页查询:PageHelper允许您在数据库查询中轻松实现分页功能,而无需手动编写复杂的SQL语句。您可以指定要查询的页码和每页显示的记录数,并PageHelper将自动为您生成合适的SQL语句。
- 总记录数的查询:PageHelper支持自动执行总记录数查询,以获取匹配查询条件的总记录数。这对于生成分页信息和显示分页导航非常有用。
- 合理化参数:PageHelper可以自动合理化(normalize)pageNum和pageSize参数,确保它们在合理的范围内。例如,它可以确保页码不小于1,页大小不小于1。
- 支持多种数据库:PageHelper支持多种数据库,包括MySQL、Oracle、PostgreSQL、SQL Server等,因此您可以在不同数据库中使用相同的分页查询方式。
- 自定义排序:您可以根据需要指定自定义的排序规则,以按照不同字段或多个字段进行排序。
- 内置支持Count SQL优化:PageHelper内置了对Count SQL查询的优化,可以提高查询性能。
- 支持多层嵌套查询:PageHelper可以处理多层嵌套查询,使得复杂的分页查询也能轻松实现。
- 分页信息封装:PageHelper返回的分页结果是一个Page对象,它包含了查询结果数据以及分页信息,如当前页码、总记录数、总页数等。
- 可自定义的配置:PageHelper允许您根据项目需求进行灵活的配置,包括设置合理化参数、是否启用总记录数查询、是否启用Count SQL优化等。
6.2 导入依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
<!--
下面这个依赖适用于原始的 Mybatis 框架使用
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.2</version>
</dependency>-->
6.3 配置文件
6.3.1 配置选项
- offsetAsPageNum:
-
- 默认值:false
- 含义:如果设置为true,PageHelper会把参数中的页码值当做偏移量(即起始行号),这意味着页码从1开始,而不是从0开始。例如,页码1对应的偏移量是0,页码2对应的偏移量是1,以此类推。如果设置为false,页码和偏移量一样,从0开始。
- rowBoundsWithCount:
-
- 默认值:false
- 含义:如果设置为true,PageHelper会进行count查询,以获取总记录数。这通常用于在分页结果中显示总记录数。启用此选项会在查询分页数据的同时执行额外的count查询,以获取总记录数。如果设置为false,PageHelper不会执行count查询。
- reasonable:
-
- 默认值:false
- 含义:如果设置为true,PageHelper会合理化(normalize)pageNum和pageSize参数,确保它们在合理的范围内。合理化会确保页码不小于1,页大小不小于1。如果pageNum小于1,将自动设置为1;如果pageSize小于1,将自动设置为1。如果设置为false,PageHelper不会对pageNum和pageSize进行合理化处理。
- pageSizeZero:
-
- 默认值:false
- 含义:如果设置为true,当pageSize为0时,会返回所有的数据,而不是抛出异常。这对于不需要分页的查询可能是有用的。
- supportMethodsArguments:
-
- 默认值:false
- 含义:如果设置为true,PageHelper将支持将pageNum和pageSize作为参数传递给MyBatis的查询方法,而不仅仅依赖ThreadLocal中的参数。这可以在使用MyBatis的方法参数时更加灵活。
- returnPageInfo:
-
- 默认值:none
- 含义:这个选项决定了PageHelper返回的结果对象类型。默认情况下,返回的是Page对象。可以设置为always,使PageHelper始终返回Page对象,无论是否执行了分页查询。也可以设置为check,以检查是否执行了分页查询,如果没有,返回的是原始的查询结果对象。
- params:
-
- 默认值:none
- 含义:此选项用于设置额外的参数,可以按照具体需求进行配置。例如,可以使用params="pageNum=pageNumKey;pageSize=pageSizeKey"将PageHelper的参数名映射到自定义参数名。
- countColumn:
-
- 默认值:* (所有列)
- 含义:此选项用于设置用于count查询的列名,通常是数据库表中的主键列名。如果不设置,PageHelper会尝试使用 *(所有列)进行count查询。
PaginationInnerInterceptor 的主要作用是拦截 MyBatis SQL 查询,自动添加分页相关的 SQL 语句,如 LIMIT 或 OFFSET 子句,以实现分页查询的功能。具体作用如下:
- 自动分页:PaginationInnerInterceptor 可以拦截 MyBatis 执行的查询语句,自动在查询语句中添加分页参数,以实现分页查询功能。这样,您不需要手动编写分页查询的 SQL 语句。
- 分页参数处理:该拦截器可以从查询方法的参数中获取分页参数,包括页码和每页记录数,然后根据这些参数自动生成相应的 SQL 语句。
- 排序处理:除了分页,PaginationInnerInterceptor 还可以处理排序参数,根据排序参数自动生成 SQL 中的 ORDER BY 子句。
- 自动统计总记录数:该拦截器还能够自动执行一个总记录数查询,以获取匹配查询条件的总记录数,这对于构建分页信息非常有用。
6.3.2 配置代码
/**
* @author 无戏
* @projectName
* @date 2023/11/4 9:10
*/
@Configurable
@MapperScan("com.qf.zzp.mybatis_plus.mapper")
public class PageHelperConfig {
@Bean
public PageHelper pageHelper(){
PageHelper pageHelper = new PageHelper();
Properties properties = new Properties();
properties.setProperty("offsetAsPageNum", "true");
properties.setProperty("rowBoundsWithCount", "true");
properties.setProperty("reasonable", "true");
pageHelper.setProperties(properties);
return pageHelper;
}
@Bean
public PaginationInnerInterceptor paginationInnerInterceptor() {
return new PaginationInnerInterceptor();
}
}
6.4 获得分页信息
// 开启分页器,第一个参数为当前页吗,第二个参数为每页展示的数据量
PageHelper.startPage(1, 3);
// mybatis-plus 自带查询所有方法
List<Users> users = usersMapper.selectList(null);
// 获得分页信息
PageInfo<Users> pageInfo = new PageInfo<>(users);
long totalRecords = pageInfo.getTotal(); // 获取总记录数
int totalPages = pageInfo.getPages(); // 获取总页数
int currentPage = pageInfo.getPageNum(); // 获取当前页码
int pageSize = pageInfo.getPageSize(); // 获取每页记录数
List<Users> list = pageInfo.getList();
System.out.println("获取总记录数:" + totalRecords);
System.out.println("获取总页数:" + totalPages);
System.out.println("获取当前页码:" + currentPage);
System.out.println("获取每页记录数:" + pageSize);
System.out.println(":" + list);
System.out.println("检查是否有下一页:" + pageInfo.isHasNextPage());
System.out.println("检查是否有上一页:" + pageInfo.isHasPreviousPage());
System.out.println("检查是否为第一页:" + pageInfo.isIsFirstPage());
System.out.println("检查是否为最后一页:" + pageInfo.isIsLastPage());
System.out.println("获取导航页码中的最后一页:" + pageInfo.getNavigateFirstPage());
6.5 特殊符号处理
6.5.1 SQL注入:
为了防止 SQL 注入攻击,我们需要对特殊字符进行转义或者使用参数绑定。在使用 MyBatis 进行数据库查询时,应该尽量使用参数绑定,而不是直接拼接 SQL 语句。参数绑定可以通过使用 #{} 或 ${} 来实现。其中,#{}会将参数值转义后作为预编译参数传递给数据库,而${}则会直接将参数值拼接到 SQL 语句中,所以在使用 ${} 时需要特别注意防止 SQL 注入。
6.5.2 XML 转义:
在 MyBatis 的 XML 配置文件中,如果我们需要在SQL语句中使用特殊字符(如 <、>、& 等),需要进行XML转义,以避免解析错误。常见的转义字符如下:
特殊字符 | 转义字符 |
< |
|
> |
|
& |
|
" |
|
’ |
|
<= |
|
>= |
|
6.5.3 使用 CDATA 区段
<![CDATA[ ]]> 是 xml 语法,在 <![CDATA[ ]]> 内部的所有内容都会被解析器忽略,不进行转义。CDATA 区段可以用来包含一些特殊字符或标记,而不会被XML解析器解析。
特殊字符 | 编码 |
< | <![CDATA[<]]> |
> | <![CDATA[>]]> |
& | <![CDATA[&]]> |
" | <![CDATA["]]> |
’ | <![CDATA[']]> |
<= | <![CDATA[<=]]> |
>= | <![CDATA[>=]]> |
!= | <![CDATA[!=]]> |
七、多数据源
- 使用 @DS 切换数据源。
@DS 可以注解在方法上或类上,同时存在就近原则 方法上注解 优先于 类上注解。
注解 | 结果 |
没有@DS | 默认数据源 |
@DS("dsName") | dsName可以为组名也可以为具体某个库的名称 |
7.1 导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.3.2</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-generator</artifactId>
<version>RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- pageHelper 分页插件依赖 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.4.6</version>
</dependency>
<!-- <dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.2</version>
</dependency>-->
<!-- 多数据源依赖 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot3-starter</artifactId>
<version>RELEASE</version>
</dependency>
</dependencies>
7.2 配置数据源
7.2.1 properties 文件配置
- 比较多
spring.datasource.dynamic.primary=master
spring.datasource.dynamic.strict=false
spring.datasource.dynamic.datasource.master.url=jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.dynamic.datasource.master.username=root
spring.datasource.dynamic.datasource.master.password=1234
spring.datasource.dynamic.datasource.master.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dynamic.datasource.slave_1.url=jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
spring.datasource.dynamic.datasource.slave_1.username=root
spring.datasource.dynamic.datasource.slave_1.password=1234
spring.datasource.dynamic.datasource.slave_1.driver-class-name=com.mysql.cj.jdbc.Driver
7.2.2 yaml 文件配置
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
url: jdbc:mysql://localhost:3306/xmbg?serverTimezone=UTC&characterEncoding=utf8&useUnicode=true&useSSL=false
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
7.2.3 业务层使用
- 加 @DS 注解,在方法或类上都可以。在方法上的优先级高于类上的。
/**
* <p>
* 存储用户信息的表 服务实现类
* </p>
*
* @author qf
* @since 2023-11-02
*/
@Service
@DS("slave_1")
public class UsersServiceImpl extends ServiceImpl<UsersMapper, Users> implements IUsersService {
@Autowired
private UsersMapper usersMapper;
@Override
public List<Users> selectByUserId(Integer id) {
return usersMapper.selectByUserId(id);
}
}
八、注解说明
@Table: 注解用于指定实体类与数据库表之间的映射关系。主要注解参数如下:
- value:该属性用于指定数据库表的表名。这是 @TableName 注解中的主要属性,它表示实体类要与哪个数据库表进行映射。
- resultMap:指定结果映射的 ID。这个参数允许你在 XML 映射文件中指定要使用的结果映射 ID。
- excludeProperty:排除不需要映射的字段。该参数接受一个字符串数组,其中包含了不需要映射的字段名。
- keepGlobalFormat:保留全局配置的字段格式化功能。默认为 false。如果设置为 true,则保留全局配置的字段格式化功能
@TableField 注解用于配置数据库表字段与实体类字段之间的映射关系。它有多个属性,其中最常用的属性包括:
- value:该属性用于指定数据库表中的字段名,与实体类字段名进行映射。例如,@TableField("user_name") 表示 username 字段与数据库表中的 user_name 字段进行映射。
- exist:用于标识字段是否存在于数据库表中,默认为 true。如果设置为 false,MyBatis-Plus 在生成 SQL 语句时会忽略该字段,即不包括在查询条件中。
- el:用于设置字段在实体类中的 EL 表达式,用于动态生成 SQL。这个属性可以用来根据一些条件动态决定是否包含该字段。例如,@TableField(el = "activeFlag == 1") 表示只有当 activeFlag 等于 1 时,才包括该字段。
- typeHandler:用于指定字段类型处理器,可以自定义处理数据库字段与 Java 类型之间的转换。通常情况下,MyBatis-Plus 会自动选择合适的类型处理器,但你也可以通过这个属性来自定义处理器。
- fill:用于配置字段填充策略。字段填充是在插入和更新操作时,自动填充某些字段的值,例如创建时间和更新时间。你可以使用该属性来指定填充策略。
以上就是本期分享,希望对大家有帮助吧~
走过路过关注一波儿吧,感谢!
有 三连 的给个 三连 ,没三连的 给个点赞 也是美滋滋的,谢谢各位大佬。
我是无脑,点赞 + 在看 还是想求一下的,祝大家都能心想事成、发大财、行大运。