springboot整合mybatis-plus
Posted 听钱塘信起
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了springboot整合mybatis-plus相关的知识,希望对你有一定的参考价值。
目录
写在前面
mybatis-plus顾名思义就是mybatis的增强工具。对于mybatis的功能只做扩展、不做改变。体现在内置的Mapper对CRUD进行了封装、只需要通过简单的配置即可实现增删改查操作。而不用编写XML和SQL。
前置的项目搭建和数据库表:
传送门:
一、环境准备:
1.1、导入依赖
将springboot 整合mybatis的依赖替换为整合mybatis-plus的起步依赖;
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
IDEA按照一个插件Maven Helper可以查看是否有依赖冲突。
1.2、修改配置文件
端口、数据库、mybatis-plus日志输出、驼峰映射、xml位置等
server: port: 8889 spring: datasource: url: jdbc:mysql://localhost:3308/boot_mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True username: root password: root mybatis-plus: mapper-locations: mapper/*.xml configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl map-underscore-to-camel-case: true type-aliases-package: com.example.demo.entity
1.3、IUser实体类
绑定表名、主键名
@Data
@TableName("t_user")
public class IUser
/**
* 指定主键名、主键生产策略
*/
@TableId(value = "u_id", type = IdType.AUTO)
private Integer uId;
/**
*指定列名,若一致可以不用指定
*/
@TableField("user_name")
private String userName;
private String email;
private String passWord;
private Date birth;
private int gender;
1.4、UserMapper
只要继承BaseMapper<~>即可、其他方法和xml可以删掉。
@Mapper
public interface IUserMapper extends BaseMapper<IUser>
IUserMapper继承BaseMapper<~>后就可以不用编写XML来实现了
二、使用
测试须知
本文直接在测试类中注入IUserMapper、编写测试方法进行测试。service层、controller层就不写了
@Autowired private IUserMapper userMapper;
可以看到,自己并没有新建方法,而userMapper可以调用BaseMapper提供的众多方法。
可以看到BaseMapper提供的方法需要的参数有字符串、实体类、map、条件构造器等。下文将使用一些用例来测试这些方法。为了增加观感、只展示如何使用、执行结果、SQL日志就不截图占用篇幅了。
2.1、基础增删改查
2.1.1 新增一条User数据
@Test public void insert() IUser user = new IUser(); user.setUserName("韩信"); user.setPassWord("123"); user.setEmail("123@qin.com"); userMapper.insert(user);
2.1.2 根据条件删除User
根据ID删除
@Test public void deleteById() userMapper.deleteById(84);
根据某列精准匹配删除
@Test public void deleteByMap() Map<String, Object> map = new HashMap<>(); map.put("user_name","韩信"); userMapper.deleteByMap(map);
2.1.3 修改数据User信息
根据ID修改
@Test public void updateById() IUser user = new IUser(); user.setUserName("李白"); user.setUId(81); userMapper.updateById(user);
2.1.3 根据条件查询用户
查询全部用户
@Test public void selectList() userMapper.selectList(null);
根据ID查询
@Test public void selectById() userMapper.selectById(81);
根据某列精确匹配
@Test public void selectByMap() Map<String, Object> map = new HashMap<>(); map.put("user_name","李白"); userMapper.selectByMap(map);
2.2、批量操作
2.2.1 批量新增
@Test public void batchUpdate() IUser user1 = new IUser(); IUser user2 = new IUser(); IUser user3 = new IUser(); user1.setUserName("彭于晏"); user2.setUserName("吴彦祖"); user3.setUserName("胡歌"); user1.setPassWord("123"); user2.setPassWord("123"); user3.setPassWord("123"); ArrayList<IUser> userList = new ArrayList<>(); userList.add(user1); userList.add(user2); userList.add(user3); userList.forEach(user -> userMapper.insert(user); );
2.2.2 批量删除
@Test public void deleteBatchIds() List<Integer> ids = new ArrayList<>(); ids.add(85); ids.add(86); ids.add(87); ids.add(89); userMapper.deleteBatchIds(ids);
2.2.3 批量查询
根据ids
@Test public void selectBatchIds() List<Integer> ids = new ArrayList<>(); ids.add(85); ids.add(86); ids.add(87); ids.add(89); userMapper.selectBatchIds(ids);
2.3、查询条件构造器【QueryWrapper】使用
条件构造器就是通过链式编程的形式构造where后面的SQL
可选项有
比如:查询user_name="李白" and email like "123" 的用户
@Test public void selectListByQueryWrapper() QueryWrapper<IUser> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_name","李白") .like("email","123"); userMapper.selectList(queryWrapper);
比如:查询user_name="李白" and pass_word like "123" 的用户
@Test public void selectMapsByQueryWrapper() QueryWrapper<IUser> queryWrapper = new QueryWrapper<>(); queryWrapper.eq("user_name","李白") .like("pass_word","123"); userMapper.selectMaps(queryWrapper);
但是存在许多硬编码。
2.4、修改条件构【UpdateWrapper】造器使用
也是通过链式编程的方式拼接修改条件;
比如,将用户名为张三的密码修改为456@qq.cpm
@Test public void updateByUpdateWrapper() UpdateWrapper<IUser> updateWrapper = new UpdateWrapper<>(); IUser user = new IUser(); updateWrapper.eq("user_name","张三") .set("email","456@qq.cpm"); userMapper.update(user,updateWrapper);
,
也是存在字段的硬编码
以上可否已经感觉到了mybatis-plus的强大之处?可还记得实体类做了数据库字段和实体属性的映射。那用使用条件构造器和修改构造器的时候还要再确认数据库字段是否显得字段映射有点多余?
开个玩笑,修改一个构造器就可以减少硬编码了。
三、减少硬编码
【LambdaQueryWrapper】来减少硬编码、直接通过类获取属性的方式得到字段
比如查询姓"张"的所有用户
@Test public void updateByLambdaQueryWrapper() LambdaQueryWrapper<IUser> lambdaQueryWrapper = new LambdaQueryWrapper<>(); lambdaQueryWrapper.like(IUser::getUserName,"张"); userMapper.selectList(lambdaQueryWrapper);
【LambdaUpdateWrapper】减少硬编码
将张三的邮箱修改为45679@qq.com
@Test public void updateByLambdaUpdateWrapper() LambdaUpdateWrapper<IUser> lambdaUpdateWrapper = new LambdaUpdateWrapper<>(); IUser user = new IUser(); lambdaUpdateWrapper.eq(IUser::getUserName,"张三") .set(IUser::getEmail,"45679@qq.cpm"); userMapper.update(user,lambdaUpdateWrapper);
上述就是springboot整合mybatis-plus的大部分内容了。
四、代码生成器
任何重复、有结构的数据都可以用代码生成。这里的代码生成器是指通过表名一键生成项目的目录结构、实体类、xxx.xml等。
准备一个springboot空项目:
准备一张数据库表:
CREATE TABLE `t_user` ( `u_id` int NOT NULL AUTO_INCREMENT COMMENT '主键', `user_name` varchar(10) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '用户登录名', `email` varchar(50) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci DEFAULT NULL COMMENT '邮箱', `pass_word` varchar(30) CHARACTER SET utf8mb3 COLLATE utf8mb3_general_ci NOT NULL COMMENT '密码', `birth` date DEFAULT NULL COMMENT '生日', `start_date` date DEFAULT NULL COMMENT '注册时间', `update_date` date DEFAULT NULL COMMENT '最后修改时间', `gender` bigint NOT NULL DEFAULT '2' COMMENT '性别,0:男,1:女,2:保密', `is_action` int DEFAULT NULL COMMENT '逻辑删除字段', `version` int DEFAULT NULL COMMENT '乐观锁配置', PRIMARY KEY (`u_id`) USING BTREE ) ENGINE=InnoDB AUTO_INCREMENT=88 DEFAULT CHARSET=utf8mb3 ROW_FORMAT=DYNAMIC;
引入依赖:mybatis-plus的版本不一样配置也有所不同
<!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- MP 起步依赖--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.4.0</version> </dependency> <!-- 模板引擎 --> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity-engine-core</artifactId> <version>2.0</version> </dependency> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-generator</artifactId> <version>3.4.0</version> <!-- <scope>test</scope> --> </dependency>
yml
spring: datasource: url: jdbc:mysql://localhost:3308/generate?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver
测试工具类
/** * @author Alex */ public class GeneratorUtils public static void main(String[] args) autoGenerator(); public static void autoGenerator() AutoGenerator autoGenerator = new AutoGenerator(); autoGenerator.setDataSource(getDataSourceConfig()); autoGenerator.setGlobalConfig(getGlobalConfig()); autoGenerator.setPackageInfo(getPackageInfo()); autoGenerator.setStrategy(getStrategyConfig()); autoGenerator.execute(); /** * 设置数据源 * @return */ public static DataSourceConfig getDataSourceConfig() DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:mysql://localhost:3308/generate?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&AllowPublicKeyRetrieval=True"); dsc.setSchemaName("public"); dsc.setDriverName("com.mysql.cj.jdbc.Driver"); dsc.setUsername("root"); dsc.setPassword("root"); dsc.setDbType(DbType.MYSQL); return dsc; /** * 设置全局配置 * @return */ public static GlobalConfig getGlobalConfig() GlobalConfig gc = new GlobalConfig(); String path = System.getProperty("user.dir"); gc.setOutputDir(path+"/src/main/java");//参数是一个目录,所以需要获取当前系统目录 gc.setAuthor("Alex"); gc.setOpen(true);//是否打开资源管理器 gc.setFileOverride(true);//是否覆盖已经生成的 gc.setServiceName("%sService");//去service的I前缀 gc.setIdType(IdType.INPUT);// id生成策略 gc.setDateType(DateType.ONLY_DATE); return gc; /** *包配置 * @return */ public static PackageConfig getPackageInfo() PackageConfig pc = new PackageConfig(); pc.setModuleName("common"); pc.setParent("com.example.demo"); pc.setEntity("entity"); pc.setMapper("mapper"); pc.setService("service"); pc.setController("controller"); return pc; /** * 策略配置 * @return */ public static StrategyConfig getStrategyConfig() StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel);// 下划线转驼峰命名 strategy.setColumnNaming(NamingStrategy.underline_to_camel); // 设置映射的表名,多张表 strategy.setInclude("t_user"); strategy.setEntityLombokModel(true);// 是否启用lombok开启注解 strategy.setLogicDeleteFieldName("isAction");//设置逻辑删除字段 // 时间自动填充配置 TableFill startDate = new TableFill("startDate", FieldFill.INSERT); TableFill updateDate = new TableFill("updateDate", FieldFill.UPDATE); ArrayList<TableFill> list = new ArrayList<>(); list.add(startDate); list.add(updateDate); strategy.setTableFillList(list); // 乐观锁配置 strategy.setVersionFieldName("version"); // rustful 格式 strategy.setRestControllerStyle(true); return strategy;
生成目录:生成common模块的项目项目结构
调整:
- 移动下xxxMapper.xml的位置,并在xxxxMapper的接口上加上@Mapper注解
- 启动类上添加:@MapperScan("com.example.demo.mapper")
测试使用:
新增一个用户:
@Autowired private TUserMapper userMapper; @Test public void insert() TUser user = new TUser(); user.setUserName("王维"); user.setPassWord("qwe@qwe"); userMapper.insert(user);
结果:
补充:由于配置的参数都可以是固定的、需要手动改变的只有数据库的表名。因此将将其打包成工具、连接数据库后指定下表名。即可生成结构相同的目录结构、具体需要什么是什么目录根据实际情况而定。
mybatis-plus整合springboot入门
1、mybatis-plus快速入门
2、springboot整合mybatis-plus
(1)、映入maven依赖
<!--mybaitsi-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.3.1.tmp</version>
</dependency>
备注:springboot版本:2.2.6.RELEASE
(2)、yml文件数据库和mybatis-plus配置
#数据库配置
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql://localhost:3306/mybaits-plus?useUnicode=true&characterEncoding=UTF-8&useSSL=false&nullCatalogMeansCurrent=true&serverTimezone=Asia/Shanghai
#mybatis-plus配置
logging:
level:
com:
example:
demo:
mapper: debug
mybatis-plus:
mapper-locations: classpath*:mappers/*.xml
# 实体扫描,多个package用逗号或者分号分隔
type-aliases-package: com.example.demo.model
configuration:
# 驼峰下划线转换
map-underscore-to-camel-case: true
cache-enabled: false
call-setters-on-nulls: true
global-config:
# 刷新mapper 调试神器
refresh: true
banner: false
#数据库大写下划线转换
#capital-mode: true
#序列接口实现类配置
#key-generator: com.baomidou.springboot.xxx
# 数据库相关配置
db-config:
db-type: mysql
# 主键类型 AUTO:"数据库ID自增", INPUT:"用户输入ID",ID_WORKER:"全局唯一ID (数字类型唯一ID)", UUID:"全局唯一ID UUID";
id-type: AUTO
# 字段策略 IGNORED:"忽略判断",NOT_NULL:"非 NULL 判断"),NOT_EMPTY:"非空判断"
field-strategy: not_empty
capital-mode: true
#逻辑删除配置
logic-delete-value: 1
logic-not-delete-value: 0
(3)、数据准备
CREATE TABLE `user` (
`id` bigint(11) NOT NULL COMMENT ‘主键ID‘,
`name` varchar(30) NOT NULL COMMENT ‘姓名‘,
`age` int(11) NOT NULL COMMENT ‘年龄‘,
`email` varchar(50) NOT NULL COMMENT ‘邮箱‘,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `mybaits-plus`.`user` (`id`, `name`, `age`, `email`) VALUES (‘1‘, ‘Jone‘, ‘18‘, ‘test1@baomidou.com‘);
INSERT INTO `mybaits-plus`.`user` (`id`, `name`, `age`, `email`) VALUES (‘2‘, ‘Jack‘, ‘20‘, ‘test2@baomidou.com‘);
INSERT INTO `mybaits-plus`.`user` (`id`, `name`, `age`, `email`) VALUES (‘3‘, ‘Tom‘, ‘28‘, ‘test3@baomidou.com‘);
INSERT INTO `mybaits-plus`.`user` (`id`, `name`, `age`, `email`) VALUES (‘4‘, ‘Sandy‘, ‘21‘, ‘test4@baomidou.com‘);
INSERT INTO `mybaits-plus`.`user` (`id`, `name`, `age`, `email`) VALUES (‘5‘, ‘Billie‘, ‘24‘, ‘test5@baomidou.com‘);
CREATE TABLE `course` (
`id` bigint(20) NOT NULL,
`course` varchar(10) NOT NULL,
`user_id` bigint(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
INSERT INTO `mybaits-plus`.`course` (`id`, `course`, `user_id`) VALUES (‘1‘, ‘语文‘, ‘2‘);
(4)、创建实体类
@Data
public class User implements Serializable {
private static final long serialVersionUID = -5817579076869802231L;
private Long id;
private String name;
private Integer age;
private String email;
}
(5)、service层和dao层
public interface UserService extends IService<User> {
PageInfo<User> selectPage(int pageNo, int pageSize, User user);
PageInfo<User> selectPageCustom(int pageNo, int pageSize, User user);
PageInfo<Map<String, Object>> selectPageCustomMap(int pageNo, int pageSize);
}
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
@Resource
private UserMapper userMapper;
@Override
public PageInfo<User> selectPage(int pageNo, int pageSize, User user) {
Page<User> page = new Page<>(pageNo,pageSize,false);
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.like("name",user.getName());
wrapper.orderByAsc("id");
page = userMapper.selectPage(page, wrapper);
return new PageInfo<>(page);
}
@Override
public PageInfo<User> selectPageCustom(int pageNo, int pageSize, User user) {
Page<User> page = new Page<>(pageNo,pageSize);
userMapper.pageMyQuery(page,user.getName());
return new PageInfo<>(page);
}
@Override
public PageInfo<Map<String, Object>> selectPageCustomMap(int pageNo, int pageSize) {
Page<Map<String, Object>> page = new Page<>(pageNo,pageSize);
page = userMapper.pageMyMapQuery(page);
return new PageInfo<>(page);
}
public interface UserMapper extends BaseMapper<User> {
Page<User> pageMyQuery(Page<User> pageInfo, @Param("name") String name);
Page<Map<String,Object>> pageMyMapQuery(Page pageInfo);
}
mapper文件
<?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.example.demo.mapper.UserMapper"> <select id="pageMyQuery" parameterType="User" resultType="User"> select id,name,age from user where name = #{name} </select> <select id="pageMyMapQuery" resultType="map"> SELECT * FROM course c LEFT JOIN `user` u on c.id = u.id </select> </mapper>
(6)、单元测试
1 @SpringBootTest
2 @RunWith(SpringRunner.class)
3 public class MybatisPlusTest {
4
5 @Autowired
6 private UserService userService;
7 /**
8 * 全局id生成器
9 */
10 @Autowired
11 private DefaultIdentifierGenerator defaultIdentifierGenerator;
12
13 /**
14 * list查询
15 */
16 @Test
17 public void selectList(){
18 List<User> list = userService.list();
19 Assert.assertEquals(6, list.size());
20 list.forEach(System.out::println);
21 }
22
23 /**
24 *单条插入
25 */
26 @Test
27 public void inset(){
28 User user = new User();
29 user.setName("张三");
30 user.setAge(20);
31 user.setEmail("1165523762@qq.com");
32 user.setId(defaultIdentifierGenerator.nextId(user));
33 userService.save(user);
34 }
35
36 /**
37 * 批量插入
38 */
39 @Test
40 public void saveBatch(){
41 List<User> list = new ArrayList<>();
42 User user1 = new User();
43 user1.setName("王五");
44 user1.setAge(20);
45 user1.setEmail("1234567@qq.com");
46 user1.setId(defaultIdentifierGenerator.nextId(user1));
47 list.add(user1);
48
49 User user2 = new User();
50 user2.setName("李四");
51 user2.setAge(20);
52 user2.setEmail("7654321@qq.com");
53 user2.setId(defaultIdentifierGenerator.nextId(user1));
54 list.add(user2);
55
56 userService.saveBatch(list);
57
58 }
59
60 /**
61 * 按照id集合删除
62 */
63 @Test
64 public void delBatch(){
65 List<Long> ids = new ArrayList<>();
66 ids.add(1259742998092120066L);
67 ids.add(1259749231041806337L);
68 userService.removeByIds(ids);
69 }
70
71 /**
72 * 分页查询
73 */
74 @Test
75 public void queryPage(){
76 User user = new User();
77 user.setName("李四");
78 PageInfo<User> userPageInfo = userService.selectPage(1,3,user);
79 System.err.println(userPageInfo);
80 }
81
82 /**
83 * 自定义分页查询返回T
84 */
85 @Test
86 public void queryPageCustom(){
87 User user = new User();
88 user.setName("李四");
89 PageInfo<User> userPageInfo = userService.selectPageCustom(1,3,user);
90 System.err.println(userPageInfo);
91 }
92
93 /**
94 * 自定义分页查询返回map
95 */
96 @Test
97 public void queryPageCustomMap(){
98 PageInfo<Map<String,Object>> userPageInfo = userService.selectPageCustomMap(1,3);
99 System.err.println(userPageInfo);
100 }
补充:PageInfo源码(自定义分页实体类)
@Data
public class PageInfo<T> {
/**
* 当前页
*/
private Long pageNo;
/**
* 每页显示条数
*/
private Long PageSize;
/**
* 总条数
*/
private Long total;
/**
* 结果集
*/
private List<T> result;
public PageInfo(Page<T> page) {
this.pageNo = page.getCurrent();
this.PageSize = page.getSize();
this.total = page.getTotal();
this.result = page.getRecords();
}
}
mybatis-plus配置类
@Configuration
public class MybatisPlusConfig {
/**
* 全局id生成器
* @return
*/
@Bean
public DefaultIdentifierGenerator identifierGenerator(){
return new DefaultIdentifierGenerator();
}
/**
* 分页插件
* @return
*/
@Bean
public PaginationInterceptor paginationInterceptor(){
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求 默认false
// paginationInterceptor.setOverflow(false);
// 设置最大单页限制数量,默认 500 条,-1 不受限制
// paginationInterceptor.setLimit(500);
// 开启 count 的 join 优化,只针对部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
}
以上是关于springboot整合mybatis-plus的主要内容,如果未能解决你的问题,请参考以下文章
[SpringBoot系列]SpringBoot如何整合SSMP
SpringBoot完成SSM整合之SpringBoot整合junit