- MyBatis-Plus(简称 MP)是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生
愿景:
简单来说,Mybatis用来简化JDBC,不用再去写JDBC代码和手动设置参数以及获取结果集;而Mybatis-Plus简化了Mybatis,不用再去写简单的crud的mapper映射配置文件
可以进入Mybatis-Plus官网了解更多详细知识,自主学习
创建springboot项目并引入Mybatis-Plus测试相关依赖:
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.0.5version>
dependency>
application.yml配置:
#连接数据库
spring:
datasource:
username: root
password: 123456
url: jdbc:mysql:///mybatis-plus?characterEncoding=UTF-8&serverTimezone=GMT%2b8
driver-class-name: com.mysql.cj.jdbc.Driver
#控制台打印sql语句
logging:
level:
com.baidu.mybatisplus.mapper: debug
实体类:
@Data //lombok自动生成set/get,以及toString等方法
@AllArgsConstructor
@NoArgsConstructor
public class User implements Serializable {
private Long id;
private String name;
private Integer age;
private String email;
}
持久层Mapper:
@Repository
public interface UserMapper extends BaseMapper<User> {
}
- 持久层接口只需继承BaseMapper ,就可以实现基本的crud操作,并不需要配置mybatis中的映射文件,SQL语句
再在springboot启动类加上注解扫描mapper包就可以测试了@MapperScan(“com.baidu.mybatisplus.mapper”)
测试:
@Autowired
UserMapper userMapper;
@Test
void contextLoads() {
List<User> users = userMapper.selectList(null);
users.forEach(System.out::println);//遍历users
}
- 只需要继承一个BaseMapper,就拥有crud方法,岂不是美哉?
//测试插入数据
@Test
public void testInsert(){
User user = new User();
user.setName("老徐");
user.setAge(3);
user.setEmail("[email protected]");
userMapper.insert(user); // 没有设置id,但是id自动生成了
System.out.println(user);
}
结果:
- 为什么我们没有设置主键,他还是生成了,并且特别长?
- Mybatis-Plus默认生成主键,并且默认使用雪花算法生成全局唯一id
我们可以在实体类上添加注解设置主键生成策略
/**
* AUTO(0), 数据库id自增
* NONE(1), 未设置主键
* INPUT(2), 手动输入
* ID_WORKER(3), 默认的,全局唯一id
* UUID(4), 全局唯一id:uuid
* ID_WORKER_STR(5); ID_WORKER 字符串表示法
*/
@TableId(type = IdType.AUTO)
private Long id;
在实际开发中,往往会在数据库中添加create_time,update_time,用来记录向数据库中插入和更新时的时间,所以就用到了自动填充策略
handler/MyMetaObjectHandler:
@Slf4j
@Component
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);
}
}
实体类字段:
@TableField(fill = FieldFill.INSERT) //插入时自动填充字段
private Date createTime;
@TableField(fill = FieldFill.INSERT_UPDATE) //插入和更新时插入字段
private Date updateTime;
//测试更新数据
@Test
public void testUpdate(){
User user = new User();
user.setId(5L);
user.setName("王老五");
user.setAge(22);
userMapper.updateById(user);
}
//测试查询数据
@Test
public void testSelect(){
User user = userMapper.selectById(8L);
System.out.println(user);
//批量查询
/* List users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3));
for (User user:users){
System.out.println(user);
}*/
//复杂条件查询可以使用map
/* Map map = new HashMap<>();
map.put("name","徐浩");
List users = userMapper.selectByMap(map);
users.forEach(System.out::println);*/
//分页查询
/*Page page = new Page<>(1,5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);*/
}
- Mybatis-Plus有分页插件,有了分页插件,就不会像以前分页查询那么麻烦
config/MybatisPlusConfig:
@EnableTransactionManagement
@Configuration
@MapperScan("com.baidu.mybatisplus.mapper")//从启动类上移动到这来
public class MybatisPlusConfig {
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
测试:
//分页查询
Page<User> page = new Page<>(1,5);
userMapper.selectPage(page, null);
page.getRecords().forEach(System.out::println);
- 物理删除是从数据库真正删除数据记录,而在开发过程中,更多使用的是逻辑删除,那什么是逻辑删除呢?
- 逻辑删除就是不真正的从数据库删除记录,而是通过修改数据库的一个deleted字段,从而使该数据失效
config/MybatisPlusConfig:
@EnableTransactionManagement
@Configuration
@MapperScan("com.baidu.mybatisplus.mapper")
public class MybatisPlusConfig {
//分页插件
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
//逻辑删除组件
@Bean
public ISqlInjector sqlInjector(){
return new LogicSqlInjector();
}
}
application.yml:
#设置逻辑删除值
mybatis-plus:
global-config:
db-config:
logic-delete-value: 1 #删除后的值
logic-not-delete-value: 0 #未删除的值
实体类字段:
@TableLogic //逻辑删除
private Integer deleted;
测试:
先查询某个用户:
@Test
public void testSelect(){
User user = userMapper.selectById(1L);
System.out.println(user);
}
//测试删除数据
@Test
public void testDelete(){
userMapper.deleteById(1L);
}
- 逻辑删除实际上一个更新的语句
官网的例子很多且详细,可以去官网详细了解,我测试几个方法给大家演示一下,注意观察打印的SQL语句
//测试比较的
@Test
public void testEq(){
//查询名字是小王,年龄大于5岁的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.eq("name","小王")
.ge("age",5);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
//测试between
@Test
public void testBetween(){
//查询年龄在20-30之间的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.between("age",20,30);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
//测试like模糊查询
@Test
public void testLike(){
//查询email为t开头的,名字中含有a
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.likeRight("email","t") // t%
.like("name","a"); // %a%
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
//测试Null的判断
@Test
public void testNull(){
//查询email不为空,年龄大于20的
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper
.isNotNull("email")
.ge("age",20);
List<User> users = userMapper.selectList(wrapper);
users.forEach(System.out::println);
}
更多的方法自行去官网学习~~~
总而言之:Mybatis-Plus不仅帮助我们封装了简单的crud方法,还有很多好用的插件,总之大大简化了我们的开发过程!