SpringBoot整合Mybatis-plus入门
1、简介
MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提 高效率而生。关于mybatis-plus的更多介绍及特性,可以参考mybatis-plus官网。
2、Mybatis-plus特性
- 无侵入:只做增强不做改变,引入它不会对现有工程产生影响,如丝般顺滑
- 损耗小:启动即会自动注入基本 CURD,性能基本无损耗,直接面向对象操作
- 强大的 CRUD 操作:内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操 作,更有强大的条件构造器,满足各类使用需求
- 支持 Lambda 形式调用:通过 Lambda 表达式,方便的编写各类查询条件,无需再担心字段写错
- 支持多种数据库:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、 SQLServer2005、SQLServer 等多种数据库
- 支持主键自动生成:支持多达 4 种主键策略(内含分布式唯一 ID 生成器 - Sequence),可自由配置,完美 解决主键问题
- 支持 XML 热加载:Mapper 对应的 XML 支持热加载,对于简单的 CRUD 操作,甚至可以无 XML 启动
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式调用,实体类只需继承 Model 类即可进行强大的 CRUD 操作
- 支持自定义全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 支持关键词自动转义:支持数据库关键词(order、key…)自动转义,还可自定义关键词
- 内置代码生成器:采用代码或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 层代 码,支持模板引擎,更有超多自定义配置等您来使用
- 内置分页插件:基于 MyBatis 物理分页,开发者无需关心具体操作,配置好插件之后,写分页等同于普通 List 查询
- 内置性能分析插件:可输出 Sql 语句以及其执行时间,建议开发测试时启用该功能,能快速揪出慢查询
- 内置全局拦截插件:提供全表 delete 、 update 操作智能分析阻断,也可自定义拦截规则,预防误操作
- 内置 Sql 注入剥离器:支持 Sql 注入剥离,有效预防 Sql 注入攻击
3、SpringBoot整合Mybatis-plus
3.1 导入依赖
这里我们用到了lombok工具包,这个在最后会讲到。
<!--简化代码的工具包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!--mybatis-plus的springboot支持-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.0.5</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
3.2 编写application.yml配置文件
spring:
application:
name: mybatis-plus-test
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://172.16.55.185:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true&useS SL=false
username: root
password: root
3.3 创建表
CREATE TABLE `user` (
`id` bigint(20) NOT NULL COMMENT '主键ID',
`name` varchar(30) DEFAULT NULL COMMENT '姓名',
`age` int(11) DEFAULT NULL COMMENT '年龄',
`email` varchar(50) DEFAULT NULL COMMENT '邮箱',
`first_name` varchar(50) DEFAULT NULL COMMENT '姓氏',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
-- 插入数据
INSERT INTO `user` (`id`, `name`, `age`, `email`,`first_name`) VALUES ('1', 'Lisi', '19', 'test1@myself.com','李');
INSERT INTO `user` (`id`, `name`, `age`, `email`,`first_name`) VALUES ('2', 'Jack', '25', 'test2@myself.com','Jack');
INSERT INTO `user` (`id`, `name`, `age`, `email`,`first_name`) VALUES ('3', 'Tom', '28', 'test3@myself.com','Tom');
INSERT INTO `user` (`id`, `name`, `age`, `email`,`first_name`) VALUES ('4', 'Zhnagsan', '21', 'test4@myself.com','张');
INSERT INTO `user` (`id`, `name`, `age`, `email`,`first_name`) VALUES ('5', 'Wangwu', '29', 'test5@myself.com','王');
3.4 创建实体对象
@Data
@TableName(value = "user")//指定表名,如果表名和实体名称一致,可以省略不写
public class User {
//若实体类属性名与表主键列名一致可省略value
@TableId(value = "id",type = IdType.AUTO)//指定自增策略
private Long id;
private String name;
private Integer age;
private String email;
//若没有开启驼峰命名,或者表中列名不符合驼峰规则,可通过该注解指定数据库表中的列名,exist标明数据表中有没有对应列
@TableField(value = "first_name",exist = true)
private String firstName;
}
3.5 编写UserMapper
public interface UserMapper extends BaseMapper<User> {
}
想了解BaseMapper提供了哪些基础的CRUD操作,有兴趣的可以进入BaseMapper类中查看,下面会有增、删、改、查等测试演示,这里就不截图列出来了。
3.6 编写SpringBoot启动类
@MapperScan("cn.dws.mybatisplus.mapper") //设置mapper接口的扫描包 @SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
3.7 测试
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
for (User user : userList) {
System.out.println(user);
}
}
}
本文涉及代码较多,为了不影响篇幅,故非必要处不再截图。接下来的所有操作都是基于此整合好的项目。
4、BaseMapper 的CRUD操作
在MybatisPlus中,BaseMapper中定义了一些常用的CRUD方法,当我们自定义的Mapper接口继承BaseMapper 后即可拥有了这些方法。
4.1 插入数据
@Test
public void testSave(){
User user = new User();
user.setAge(25);
user.setEmail("Xiaohong@qq.com");
user.setName("Xiaohong");
user.setFirstName("小");
int count = this.userMapper.insert(user);
System.out.println("新增数据成功! count => " + count);
}
4.2 修改数据
@Test
public void testUpdate(){
User user = new User();
user.setId(6L);
user.setName("Liyan");
//根据主键id修改数据
this.userMapper.updateById(user);
System.out.println("修改成功!"); }
4.3 删除数据
@Test
public void testDelete(){
//根据主键id删除数据
this.userMapper.deleteById(7L);
System.out.println("删除成功!"); }
4.4 条件查询
@Test
public void testSelectByLe(){
QueryWrapper queryWrapper = new QueryWrapper(new User());
// 查询年龄小于等于20的用户
queryWrapper.le("age", 20);
List<User> users = this.userMapper.selectList(queryWrapper);
for (User user : users) {
System.out.println(user);
}
}
4.5 like查询
@Test
public void testSelectByLike(){
QueryWrapper queryWrapper = new QueryWrapper(new User());
//查询名字中包含“o”的用户
queryWrapper.like("name", "o");
List<User> users = this.userMapper.selectList(queryWrapper);
for (User user : users) {
System.out.println(user);
}
}
4.6 分页查询
4.6.1 首先需要配置分页插件
@configration //标注该类为配置类,启动器启动时会自动加载该类
public class MyConfig {
/**
* 分页插件
**/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
4.6.2 分页查询实现
@Test
public void testSelectPage() {
Page<User> page = new Page<>(1, 2);
IPage<User> userIPage = this.userMapper.selectPage(page, null);
System.out.println("总条数 ------> " + userIPage.getTotal());
System.out.println("当前页数 ------> " + userIPage.getCurrent());
System.out.println("当前每页显示数 ------> " + userIPage.getSize());
List<User> records = userIPage.getRecords();
for (User user : records) {
System.out.println(user);
}
}
更多配置:http://mp.baomidou.com/guide/config.html#%E5%9F%BA%E6%9C%AC%E9%85%8D%E7%BD%AE
5、使用MybatisPlus的AutoGenerator插件生成代码文件
5.1 依赖
<!--freemarker模板引擎-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
<version>2.3.28</version>
</dependency>
5.2 编写CodeGenerator
public class CodeGenerator {
/**
* <p>
* 读取控制台内容
* </p>
*/
public static String scanner(String tip) {
Scanner scanner = new Scanner(System.in);
StringBuilder help = new StringBuilder();
help.append("请输入" + tip + ":");
System.out.println(help.toString());
if (scanner.hasNext()) {
String ipt = scanner.next();
if (StringUtils.isNotEmpty(ipt)) {
return ipt;
}
}
throw new MybatisPlusException("请输入正确的" + tip + "!");
}
public static void main(String[] args) {
// 代码生成器
AutoGenerator mpg = new AutoGenerator();
// 全局配置
GlobalConfig gc = new GlobalConfig();
String projectPath = System.getProperty("user.dir");
gc.setOutputDir(projectPath + "/src/main/java");
gc.setAuthor("dws");
gc.setOpen(false);
mpg.setGlobalConfig(gc);
// 数据源配置
DataSourceConfig dsc = new DataSourceConfig();
dsc.setUrl("jdbc:mysql://192.168.163.132:3306/haoke? useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true");
// dsc.setSchemaName("public");
dsc.setDriverName("com.mysql.jdbc.Driver");
dsc.setUsername("root");
dsc.setPassword("root");
mpg.setDataSource(dsc);
// 包配置
PackageConfig pc = new PackageConfig();
pc.setModuleName(scanner("模块名"));
pc.setParent("cn.dws.haoke.server");
mpg.setPackageInfo(pc);
// 自定义配置
InjectionConfig cfg = new InjectionConfig() {
@Override
public void initMap() {
// to do nothing
}
};
List<FileOutConfig> focList = new ArrayList<>();
focList.add(new FileOutConfig("/templates/mapper.xml.ftl") {
@Override
public String outputFile(TableInfo tableInfo) {
// 自定义输入文件名称
return projectPath + "/src/main/resources/mapper/" +
pc.getModuleName()
+ "/" + tableInfo.getEntityName() + "Mapper" +
StringPool.DOT_XML;
}
});
cfg.setFileOutConfigList(focList);
mpg.setCfg(cfg);
mpg.setTemplate(new TemplateConfig().setXml(null));
// 策略配置
StrategyConfig strategy = new StrategyConfig();
strategy.setNaming(NamingStrategy.underline_to_camel);
strategy.setColumnNaming(NamingStrategy.underline_to_camel);
strategy.setSuperEntityClass("cn.dws.haoke.domain.BasePojo");
strategy.setEntityLombokModel(true);
strategy.setRestControllerStyle(true);
strategy.setSuperControllerClass("com.baomidou.ant.common.BaseController");
strategy.setInclude(scanner("表名"));
strategy.setSuperEntityColumns("id");
strategy.setControllerMappingHyphenStyle(true);
strategy.setTablePrefix(pc.getModuleName() + "_");
mpg.setStrategy(strategy);
mpg.setTemplateEngine(new FreemarkerTemplateEngine());
mpg.execute();
}
}
6、Lombok
lombok提供了简单的注解的形式来帮助我们简化消除一些必须有但显得很臃肿的 java 代码,尤其是针对pojo,在 MybatisPlus中使用lombok。
6.1 Lombok依赖及插件安装
6.1.1 依赖
<!--简化代码的工具包-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
<version>1.18.4</version>
</dependency>
6.1.2 安装IDEA插件
File -> Settings打开设置界面,然后
注意:如果不安装插件,程序可以正常执行,但是看不到生成的一些代码,如:get、set方法。
6.2 常用注解
- @Data:注解在类上;提供类所有属性的 getting 和 setting 方法,此外 还提供了equals、canEqual、 hashCode、toString 方法
- @Setter:注解在属性上;为属性提供 setting 方法
- @Getter:注解在属性上;为属性提供 getting 方法
- @Slf4j:注解在类上;为类提供一个 属性名为log 的 slf4j日志对象
- @NoArgsConstructor:注解在类上;为类提供一个无参的构造方法
- @AllArgsConstructor:注解在类上;为类提供一个全参的构造方法
- @Builder:使用Builder模式构建对象
6.3 测试
6.3.1 @Data
6.3.2 @Slf4j
6.3.3 @AllArgsConstructor
6.3.4 @Builder
测试结果: