MyBaitsPlus
- 导入依赖
-
- 主配置文件中的数据源相关配置
- UserMapper接口
- 测试
- @Mapper注解和@MapperScan注解
- 配置日志
- @TableId注解
- 插入操作
- 主键生成策略
-
- 雪花算法(默认使用):
- 主键自增
- 其余的策略解释
- 更新操作
- 自动填充
-
- 方式一:数据库级别(工作中不建议这么做)
-
- 1.在表中新增字段create_time、update_time
- 2. 再次测试插入方法,需要先把实体类同步!
- mysql日期相关的知识点
- 方式二:代码级别
-
- 1.删除数据库中的默认值、更新操作
- 2.在实体类字段属性上需要注释
- 3.自定义实现类 MyMetaObjectHandler(实现元对象处理器接口)
- 4.测试
- 字段填充坑
- 乐观锁
-
- 测试MP乐观锁插件
-
- 1.数据库中添加version字段,默认值为1
- 2.在实体类的字段上加上@Version注解
- 3.配置插件
- 4.测试
- 查询操作
- 分页查询
-
- 1.配置分页插件
- 2.直接使用Page对象即可
-
- 如果返回类型是IPage,那么分页返回的IPage对象与传入IPage的对象是同一个
- 多数据源下的分页插件设置
- 好用的工具===》Arrays用法总结
- 删除操作
-
- 逻辑删除
-
- 说明
-
- 这里mybaitsPlus提供的逻辑删除功能,只对其默认提供给我们的增删改查的slq语句生效,如果是我们自己写的,则不会拥有其功能
- 1.在数据表中增加deleted字段
- 2. 实体类中同步属性
- 3. 配置
- 4.测试
- 结合P6Spy进行SQL性能分析
-
- 1.导入依赖
- 2.接着编辑 application.properties 文件,更换数据库连接驱动
-
- 3.最后创建 spy.properties 配置文件即可:
- 4.测试
-
- 注意,插件会影响性能,建议开发和测试环境下使用
- @Profile注解详解
- 进阶技巧
- 1. 使用日志系统记录 sql
- 2. 将日志输出到文件
-
- 3.自定义日志格式
- 条件构造器(Wrapper)
-
- 测试一
- 测试二
- 测试三---范围查询
- 测试四---模糊查询
- 测试五----子查询
- 测试六---排序
- 代码生成器
-
- EasyCode介绍
- 1.1 EasyCode是一个什么东西?
- 1.2 原理
- 1.3 使用环境
- 1.4 支持的数据库类型
- 1.5 功能说明:
- 1.6 功能对比:
- 2.EasyCode使用
-
- 2.1 下载Easy Code插件
- 2.2 创建一个SpringBoot项目
- 2.3 配置数据源
- 2.4 自定义生成模板
- 2.5 以user表为例,根据你定义的模板生成代码,文章的最后贴出我使用的自定义的模板
- 新创建一个分组Lombok,可以在生成实体类的时候使用Lombok注解
- 多个分组的切换
- easycode使用说明推荐两篇文章
- Java开发神器Lombok使用说明推荐两篇文章
导入依赖
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--mybaits-plus第三方提供的启动器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3.1</version>
</dependency>
导入上面这个增强版依赖之后,下面两个依赖无需再次导入:
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
主配置文件中的数据源相关配置
spring:
datasource: #是否使用安全连接
#mysal 8驱动不同com.mysql.cj.jdbc.Driver,还需要增加时区的配置 serverTimezone=GMT%2B8
url: jdbc:mysql://localhost:3306/tx?userSSL=false&useUnicode=true&characterEncoding=utf-8
username: root
password: 126433
driver-class-name: com.mysql.jdbc.Driver
UserMapper接口
//继承BaseMapper基本类,接口里面已经写了很多的crud方法
@Mapper
public interface UserMapper extends BaseMapper<User>
{}
测试
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
@Test
void contextLoads()
{
//参数是一个Wrapper,条件构造器,这里我们先不使用 null
//查询全部用户
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);
}
}
@Mapper注解和@MapperScan注解
1、@Mapper注解:
作用:在接口类上添加了@Mapper,在编译之后会生成相应的接口实现类
添加位置:接口类上面
@Mapper
public interface UserDAO {
//代码
}
如果想要每个接口都要变成实现类,那么需要在每个接口类上加上@Mapper注解,比较麻烦,解决这个问题用@MapperScan
2、@MapperScan
作用:指定要变成实现类的接口所在的包,然后包下面的所有接口在编译之后都会生成相应的实现类
添加位置:是在Springboot启动类上面添加,
@SpringBootApplication
@MapperScan("com.winter.dao")
public class SpringbootMybatisDemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringbootMybatisDemoApplication.class, args);
}
}
添加@MapperScan(“com.winter.dao”)注解以后,com.winter.dao包下面的接口类,在编译之后都会生成相应的实现类
配置日志
#开启日志功能
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台输出
@TableId注解
这个注解表示表的主键
@NoArgsConstructor
@AllArgsConstructor
@Data
public class User
{
String name;
Integer age;
@TableId(value="id",type = IdType.AUTO)
Integer id;
}
接受两个参数
value = 主键列名
type = 主键类型
可选类型:
使用@TableId注解时,类型为: type = IdType.AUTO 数据库也需要设置自增
否则会出 Cause: java.sql.SQLException: Field ‘id’ doesn’t have a default value
插入操作
//测试插入
@Test
public void testInsert(){
User user = new User();
user.setName("淮城一只猫");
user.setAge(5);
user.setEmail("2424496907@qq.com");
int result = userMapper.insert(user); //自动生成id
System.out.println(result); //受影响的行数
System.out.println(user); //发现id自动回填
}
主键生成策略
默认使用ID_WORKER,全局唯一id----雪花算法
分布式系统唯一id生成方案汇总
雪花算法(默认使用):
snowflake是Twitter开源的分布式ID生成算法,结果是一个long型的ID。其核心思想是:使用41bit作为毫秒数,10bit作为机器的ID(5个bit是数据中心,5个bit的机器ID),12bit作为毫秒内的流水号(意味着每个节点在每毫秒可以产生 4096 个 ID),最后还有一个符号位,永远是0。可以保证几乎全球唯一!
主键自增
我们需要配置注解自增:
- 实体类字段上:@TableId(type = IdType.AUTUO)
- 数据库字段一定要自增
其余的策略解释
public enum IdType {
AUTO(0), //id自增
NONE(1), //未设置主键
INPUT(2), //手动输入,一旦手动输入后,就需要自己去写id,否则id为空
ID_WORKER(3), //默认值,全局唯一id
UUID(4), //全局唯一id,uuid
ID_WORKER_STR(5); //ID_WORKER的字符串表示法
}
更新操作
//测试更新
@Test
public void testUpdate(){
User user = new User();
user.setId(6L);
user.setName("我的博客叫:淮城一只猫");
user.setAge(6);
user.setEmail("2424496907@qq.com");
//注意:updateById参数是一个对象
int result = userMapper.updateById(user); //自动生成id
System.out.println(result); //受影响的行数
}
自动填充
创建时间、修改时间!这些操作一般自动化完成的,我们不希望手动更新!
阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified几乎所有表都要配置上!而且需要自动化!
方式一:数据库级别(工作中不建议这么做)
1.在表中新增字段create_time、update_time
2. 再次测试插入方法,需要先把实体类同步!
private Date creteTime;
private Date updateTime;
mysql日期相关的知识点
mysql中的日期类型小结笔记
MySQL-datetime类型的列设置默认值为CURRENT_TIMESTAMP
MySQL中datetime字段的默认值CURRENT_TIMESTAMP
方式二:代码级别
1.删除数据库中的默认值、更新操作
2.在实体类字段属性上需要注释
//字段必须声明TableField注解,属性fill选择对应策略,该声明告知Mybatis-Plus需要预留注入SQL字段
// 注意!这里需要标记为填充字段
@TableField(fill = FieldFill.INSERT)
private Date creteTime;
@TableField(fill = FieldFill.INSERT_UPDATE)
private Date updateTime;
策略枚举如下:
public enum FieldFill {
/**
* 默认不处理
*/
DEFAULT,
/**
* 插入填充字段
*/
INSERT,
/**
* 更新填充字段
*/
UPDATE,
/**
* 插入和更新填充字段
*/
INSERT_UPDATE
}
3.自定义实现类 MyMetaObjectHandler(实现元对象处理器接口)
@Slf4j
@Component//填充处理器MyMetaObjectHandler在 Spring Boot 中需要声明@Component或@Bean注入
public class MyMetaObjectHandler implements MetaObjectHandler
{
//插入时填充策略
@Override
public void insertFill(MetaObject metaObject) {
log.info("start insert fill ....");
this.setFieldValByName("createTime",new Date(),metaObject);
this.setFieldValByName("updateTime",new Date(),metaObject);
}
//更新时填充策略
@Override
public void updateFill(MetaObject metaObject) {
log.info("start update fill ....");
this.setFieldValByName("updateTime",new Date(),metaObject);
}
}
4.测试
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
@Test
void contextLoads()
{
User user=new User();
user.setAge(18);
user.setName("hhhh");
int ret = userMapper.insert(user);
System.out.println(user);
}
}
字段填充坑
自动填充字段错误示范:
自动填充字段仅针对其他字段,并不是针对主键id,主键id一般使用主键方法、全局配置或直接设置
这里的字段名是实体的字段名,不是数据库字段名,如果创建时间、更新时间等为未生效,很有可能是实体字段未设置自动填充
正确示范:
源码:
乐观锁
乐观锁:顾名思义乐观,它总是认为不会出现问题,无论干什么都不去上锁!如果出现问题,再次更新值测试
悲观锁:顾名思义悲观,它总是认为会出现问题,无论干什么都会加上锁!再去操作
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
测试MP乐观锁插件
1.数据库中添加version字段,默认值为1
2.在实体类的字段上加上@Version注解
@Version //乐观锁注解
private Integer version;
说明:
- 支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
- 整数类型下 newVersion = oldVersion + 1
- newVersion 会回写到 entity 中
- 仅支持 updateById(id) 与 update(entity, wrapper) 方法
- 在 update(entity, wrapper) 方法下, wrapper 不能复用!!!
3.配置插件
@MapperScan("com.Mapper")
@EnableTransactionManagement //自动管理事务(默认也是开启的)
@Configuration //配置类
public class MybaitsPlusConfig {
//注册乐观锁插件
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mybatisPlusInterceptor;
}
}
4.测试
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
//测试乐观锁成功!
@Test
public void testOptimisticLocker1() {
//1.查询用户信息
User user = userMapper.selectById(276);
//2.修改用户信息
user.setName("aaa");
user.setAge(18);
//3.执行更新操作
userMapper.updateById(user);
}
//测试乐观锁失败!多线程下
@Test
public void testOptimisticLocker2() {
//线程1
User user1 = userMapper.selectById(276);
user1.setName("aaa");
//模拟另外一个线程执行插队操作
User user2 = userMapper.selectById(276);
user2.setName("bbb");
userMapper.updateById(user2);
//自旋锁多次操作尝试提交
userMapper.updateById(user1);
}
}
查询操作
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
//测试查询
@Test
public void testSelectById() {
User user = userMapper.selectById(276);
System.out.println("===========================");
System.out.println(user);
}
//测试批量查询
@Test
public void testSelectByBatchId()
{
List<User> users = userMapper.selectBatchIds(Arrays.asList(270, 271, 272));
System.out.println("===========================");
users.forEach(System.out::println);
}
//条件查询之一 使用map操作
@Test
public void testSelectBatchIds() {
HashMap<String, Object> map = new HashMap<>();
//自定义查询,同时满足map集合中的所有条件
map.put("name","bbb");
map.put("age","18");
List<User> users = userMapper.selectByMap(map);
System.out.println("===========================");
users.forEach(System.out::println);
}
}
分页查询
分页在网站中使用非常多!
- 原始limit进行分页
- pageHelper第三方插件
- MP其实也内置了分页插件
1.配置分页插件
//Spring boot方式
@Configuration
@MapperScan("com.baomidou.cloud.service.*.mapper*")
public class MybatisPlusConfig {
// 旧版
@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;
}
// 最新版
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
}
- setMaxLimit: 设置最大分页数
- setOverflow:是否对超过最大分页时做溢出处理,默认false不处理,即直接丢弃溢出的数据,为true时,怎么把溢出数据放入到下一个分页中。
- setDbType:设置数据库类型以匹配不同方言
- setDialect: 设置分页方言
- setOptimizeJoin:优化Join分页语句,默认true
2.直接使用Page对象即可
//测试分页查询
@Test
public void testPage() {
//参数一:当前页
//参数二:页面大小
//使用了分页插件之后,所有的分页操作页变得简单了
Page<User> page = new Page<>(1,5);
//第二个参数是查询条件
userMapper.selectPage(page,null);
page.getRecords().forEach(System.out::println);
System.out.println(page.getTotal());
}
分页查询常用的方法:
@Test
public void testPage() {
Page<Employee> page = new Page<>(1,1);
List<Employee > emps =
employeeMapper.selectPage(page, null);
System.out.println(emps);
System.out.println("===============获取分页相关的一些信息======================");
System.out.println("总条数:" +page.getTotal());
System.out.println("当前页码: "+ page.getCurrent());
System.out.println("总页码:" + page.getPages());
System.out.println("每页显示的条数:" + page.getSize());
System.out.println("是否有上一页: " + page.hasPrevious());
System.out.println("是否有下一页: " + page.hasNext());
//将查询的结果封装到page对象中
page.setRecords(emps);
}
如果返回类型是IPage,那么分页返回的IPage对象与传入IPage的对象是同一个
多数据源下的分页插件设置
项目配置单数据源的时候,mybatis-plus分页插件正常使用,配置多数据源的时候,mybatis-plus分页插件失效。
方式一:
方式二:
好用的工具===》Arrays用法总结
Arrays用法总结
删除操作
//通过id删除
@Test
public void testDeleteById() {
userMapper.deleteById(174);
}
//通过id批量删除
@Test
public void testDeleteBatchId() {
userMapper.deleteBatchIds(Arrays.asList(177, 178));
}
//通过map删除
@Test
public void testDeleteMap() {
HashMap<String, Object> map = new HashMap<>();
map.put("name", "大忽悠1号");
userMapper.deleteByMap(map);
}
逻辑删除
物理删除:从数据库中直接移除
逻辑删除:在数据库中没有被移除,而是通过一个变量来让他失效!delete=0 => delete=1
管理员可以查看被删除的记录!防止数据的丢失,类似于回收站!
说明
这里mybaitsPlus提供的逻辑删除功能,只对其默认提供给我们的增删改查的slq语句生效,如果是我们自己写的,则不会拥有其功能
只对自动注入的sql起效:
插入: 不作限制
查找: 追加where条件过滤掉已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
更新: 追加where条件防止更新到已删除数据,且使用 wrapper.entity 生成的where条件会忽略该字段
删除: 转变为 更新
例如:
删除: update user set deleted=1 where id = 1 and deleted=0 (如果走了自动注入sql的删除操作,那么其实执行的是更新操作,即将deleted值变为1,即逻辑删除掉了)
查找: select id,name,deleted from user where deleted=0 (查找的时候只会查找出没有被逻辑删除掉的用户)
字段类型支持说明:
支持所有数据类型(推荐使用 Integer,Boolean,LocalDateTime)
如果数据库字段使用datetime,逻辑未删除值和已删除值支持配置为字符串null,另一个值支持配置为函数来获取值如now()
附录:
逻辑删除是为了方便数据恢复和保护数据本身价值等等的一种方案,但实际就是删除。
如果你需要频繁查出来看就不应使用逻辑删除,而是以一个状态去表示。
测试一下:
1.在数据表中增加deleted字段
2. 实体类中同步属性
//逻辑删除字段
@TableLogic
private Integer deleted;
3. 配置
mybatis-plus:
global-config:
db-config:
logic-delete-field: flag # 全局逻辑删除的实体字段名(since 3.3.0,配置后可以忽略不配置步骤2)
logic-delete-value: 1 # 逻辑已删除值(默认为 1)
logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
4.测试
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
//通过id删除
@Test
public void testDeleteById()
{
userMapper.deleteById(174);
}
}
结合P6Spy进行SQL性能分析
我们在开发中,会遇到一些慢sql,我们有必要把它揪出来 。测试!druid…
MP也提供性能分析插件,如果超过这个时间就停止运行!官方3.1.0以上版本推荐使用p6spy!
P6Spy 是一个可以用来在应用程序中拦截和修改数据操作语句的开源框架。 通过 P6Spy 我们可以对 SQL 语句进行拦截,相当于一个 SQL 语句的记录器,这样我们可以用它来作相关的分析,比如性能分析。
注意:该插件有性能损耗,建议平时开发测试时使用,不建议生产环境使用。
1.导入依赖
<!--p6spy性能分析插件-->
<dependency>
<groupId>p6spy</groupId>
<artifactId>p6spy</artifactId>
<version>3.9.0</version>
</dependency>
2.接着编辑 application.properties 文件,更换数据库连接驱动
P6Spy 工作原理:P6Spy 通过劫持 JDBC 驱动,在调用实际 JDBC 驱动前拦截调用的目标语,达到 SQL 语句日志记录的目的。
spring:
datasource: #是否使用安全连接
#mysal 8驱动不同com.mysql.cj.jdbc.Driver,还需要增加时区的配置 serverTimezone=GMT%2B8
url: jdbc:p6spy:mysql://localhost:3306/tx?userSSL=false&useUnicode=true&characterEncoding=utf-8
username: root
password: 123456
driver-class-name: com.p6spy.engine.spy.P6SpyDriver
profiles:
active: dev #激活开发环境
3.最后创建 spy.properties 配置文件即可:
#3.2.1以上使用
modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
#3.2.1以下使用或者不配置
#modulelist=com.p6spy.engine.logging.P6LogFactory,com.p6spy.engine.outage.P6OutageFactory
# 自定义日志打印
logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
#日志输出到控制台
appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
# 使用日志系统记录 sql
#appender=com.p6spy.engine.spy.appender.Slf4JLogger
# 设置 p6spy driver 代理
deregisterdrivers=true
# 取消JDBC URL前缀
useprefix=true
# 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
excludecategories=info,debug,result,commit,resultset
# 日期格式gui
dateformat=yyyy-MM-dd HH:mm:ss
# 实际驱动可多个
#driverlist=org.h2.Driver
# 是否开启慢SQL记录
outagedetection=true
# 慢SQL记录标准 2 秒
outagedetectioninterval=2
4.测试
@SpringBootTest
class SpringBootDaoApplicationTests
{
//继承了BaseMapper,所有的方法都来自于父类,我们页可以编写自己的扩展方法
@Autowired
UserMapper userMapper;
//通过id删除
@Test
@Profile({"dev","test"})
public void testDeleteById()
{
User user = userMapper.getUserId(174);
System.out.println(user);
}
}
注意,插件会影响性能,建议开发和测试环境下使用
@Profile注解详解
@Profile注解详解
进阶技巧
1. 使用日志系统记录 sql
1. 上面的样例配置,我们是直接将日志输出到控制台,我们可以修改 appender 配置属性,使用日志系统记录 sql:
2. 再次执行查询,可以看到现在改用日志系统记录 sql 了:
2. 将日志输出到文件
也可以修改 appender 配置属性,将日志输出到文件中:
#日志输出到文件
appender=com.p6spy.engine.spy.appender.FileLogger
# 指定 Log 的文件名 默认 spy.log
logfile=spy.log
# 指定是否每次是增加 Log,设置为 false 则每次都会先进行清空 默认true
append=true
3.自定义日志格式
1. 如果觉得默认的日志格式不合适,我们也可以使用 logMessageFormat 和 customLogMessageFormat 这两个配置参数来自定义日志输出格式:
可用的变量为:
%(connectionId):connection id %(currentTime):当前时间
%(executionTime):执行耗时 %(category):执行分组 %(effectiveSql):提交的 SQL 换行
%(effectiveSqlSingleLine):提交的 SQL 不换行显示 %(sql):执行的真实 SQL 语句,已替换占位
%(sqlSingleLine):执行的真实 SQL 语句,已替换占位不换行显示
6spy.engine.spy.appender.CustomLineFormat
customLogMessageFormat=%(currentTime) |
SQL耗时: %(executionTime) ms |
连接信息: %(category)-%(connectionId) | 执行语句: %(sql)
条件构造器(Wrapper)
这部分建议看官方文档学习
测试一
@Test
void test1() {
//查询name不为空的用户,并且邮箱不为空的,年龄大于等于12
QueryWrapper<User> wapper = new QueryWrapper<>();
wapper.isNotNull("name") //这里推荐使用链式编程
.ge("age", 64);//大于等于
userMapper.selectList(wapper).forEach(System.out::println);
}
测试二
@Test
void test2() {
//查询名字为Tom
QueryWrapper<User> wapper = new QueryWrapper<>();
wapper.eq("name","bbb");
//只查询一个用户
User user = userMapper.selectOne(wapper);
System.out.println(user);
}
测试三—范围查询
//范围查询
@Test
void test3()
{
//查询年龄在20~30岁之间的用户
QueryWrapper<User> wapper = new QueryWrapper<>();
wapper.between("age", 64, 68);//区间
System.out.println(userMapper.selectCount(wapper));//查询结果数
}
测试四—模糊查询
//模糊查询
@Test
void test4() {
//查询名字有
QueryWrapper<User> wapper = new QueryWrapper<>();
wapper.notLike("name","哈")//%e%
.likeRight("name","b");//t%
List<Map<String, Object>> maps = userMapper.selectMaps(wapper);
maps.forEach(System.out::println);
}
测试五----子查询
//子查询
@Test
void test5() {
QueryWrapper<User> wapper = new QueryWrapper<>();
//id在子查询中查出来
wapper.inSql("id","select id from user where id>273");
List<Object> objects = userMapper.selectObjs(wapper);
objects.forEach(System.out::println);
}
测试六—排序
//排序
@Test
void test6() {
QueryWrapper<User> wapper = new QueryWrapper<>();
//通过id进行排序
wapper.orderByDesc("id");
userMapper.selectList(wapper).forEach(System.out::println);
}
代码生成器
AutoGenerator 是 MyBatis-Plus 的代码生成器,通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码,极大的提升了开发效率。
EasyCode介绍
1.1 EasyCode是一个什么东西?
EasyCode是基于IntelliJ IDEA Ultimate版开发的一个代码生成插件,主要通过自定义模板(基于velocity)来生成各种你想要的代码。通常用于生成Entity、Dao、Service、Controller。如果你动手能力强还可以用于生成HTML、JS、PHP等代码。理论上来说只要是与数据有关的代码都是可以生成的。
1.2 原理
基于Mybatis底层强大的逆向工程能力和良好的项目架构
1.3 使用环境
IntelliJ IDEA Ultimate版
1.4 支持的数据库类型
因为是基于Database Tool开发,所有Database Tool支持的数据库都是支持的。
包括如下数据库:
MySQL
SQL Server
Oracle
PostgreSQL
Sqlite
Sybase
Derby
DB2
HSQLDB
H2
当然支持的数据库类型也会随着Database Tool插件的更新同步更新。
1.5 功能说明:
支持多表同时操作
支持同时生成多个模板
支持自定义模板
支持自定义类型映射(支持正则)
支持自定义附加列
支持列附加属性
所有配置项目支持分组模式,在不同项目(或选择不同数据库时),只需要切换对应的分组,所有配置统一变化
1.6 功能对比:
2.EasyCode使用
2.1 下载Easy Code插件
2.2 创建一个SpringBoot项目
2.3 配置数据源
使用Easy Code一定要使用IDEA自带的数据库工具来配置数据源
打开侧边的Database,查看效果
提前准备的数据表
2.4 自定义生成模板
第一次安装EasyCode的时候默认的模板(服务于MyBatis)可以生成下面类型的代码
entity.java
dao.java
service.java
serviceImpl.java
controller.java
mapper.xml
debug.json
2.5 以user表为例,根据你定义的模板生成代码,文章的最后贴出我使用的自定义的模板
选择模板
点击OK之后,就可以看到生成了这些代码
新创建一个分组Lombok,可以在生成实体类的时候使用Lombok注解
实体类层:entity.java
##引入宏定义
$!define
##使用宏定义设置回调(保存位置与文件后缀)
#save("/entity", ".java")
##使用宏定义设置包后缀
#setPackageSuffix("entity")
##使用全局变量实现默认包导入
$!autoImport
import java.io.Serializable;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
##使用宏定义实现类注释信息
#tableComment("实体类")
@AllArgsConstructor
@Data
@Builder
public class $!{tableInfo.name} implements Serializable {
private static final long serialVersionUID = $!tool.serial();
#foreach($column in $tableInfo.fullColumn)
#if(${column.comment})/**
* ${column.comment}
*/#end
private $!{tool.getClsNameByFullName($column.type)} $!{column.name};
#end
}
多个分组的切换
选择好分组后,点击OK,之后在Datebase视图的数据表右键选择EasyCode生成的时候会让你选择当前分组的模板
easycode使用说明推荐两篇文章
EasyCode插件使用详解
保姆级教程
Java开发神器Lombok使用说明推荐两篇文章
Java开发神器Lombok使用说明
详解Lombok中的@Builder用法,强烈推荐看一下本文