MybatisPlus入门(上)+https://developer.aliyun.com/article/1492260
自动填充
创建时间、修改时间、这些个操作都是自动化完成的,我们不希望手动更新!
阿里巴巴开发手册:所有的数据库表:gmt_create、gmt_modified 几乎所有表都要配置上,且是自动化的。
方式一:数据库级别(工作中不允许操作数据库)
1、在表中新增字段 create_time、update_time
2、再次测试插入方式,需要把实体类进行同步
private Date createTime; private Date updateTime;
3、再次更新,查看结果, 代码未更新,数据库自动发生更新
方式二:代码级别
1、删除数据库的默认值、更新操作!
2、实体类字段属性上增加注解。
package com.jay.mybatisplus.pojo; import com.baomidou.mybatisplus.annotation.FieldFill; import com.baomidou.mybatisplus.annotation.IdType; import com.baomidou.mybatisplus.annotation.TableField; import com.baomidou.mybatisplus.annotation.TableId; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; import org.apache.ibatis.annotations.Insert; import java.util.Date; /** * @author : Jay * @description : 用户 * @date : 2021-09-24 11:26 **/ @Data @AllArgsConstructor @NoArgsConstructor public class User { @TableId(type = IdType.AUTO) private Long id; private String name; private Integer age; private String email; /** * 新增时填充创建时间 */ @TableField(fill = FieldFill.INSERT) private Date createTime; /** * 更新或第一次新增时填充更新时间 */ @TableField(fill = FieldFill.INSERT_UPDATE) private Date updateTime; }
3、编写处理器来处理这个注解即可!
package com.jay.mybatisplus.handler; import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler; import lombok.extern.slf4j.Slf4j; import org.apache.ibatis.reflection.MetaObject; import org.springframework.stereotype.Component; import java.time.LocalDateTime; /** * @author : Jay * @description : 自动填充处理器 * @date : 2021-09-24 14:15 **/ @Slf4j @Component public class MyMetaObjectHandler implements MetaObjectHandler { /** * 插入时的填充策略 * @param metaObject 数据对象 */ @Override public void insertFill(MetaObject metaObject) { log.info("start insert fill..."); this.setFieldValByName("createTime", LocalDateTime.now(), metaObject); this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); } /** * 更新时的填充策略 * @param metaObject */ @Override public void updateFill(MetaObject metaObject) { log.info("start update fill..."); this.setFieldValByName("updateTime", LocalDateTime.now(), metaObject); } }
乐观锁
当要更新一条记录的时候,希望这条记录没有被别人更新
乐观锁实现方式:
- 取出记录时,获取当前version
- 更新时,带上这个version
- 执行更新时, set version = newVersion where version = oldVersion
- 如果version不对,就更新失败
举例:
1、先查询,获取当前的版本号 version = 1 -- A用户 update user set name = "jay", version = version + 1 where id = 2 and version = 1; -- B用户 的线程抢先完成,这个时候version=2,会导致A修改失败! update user set name = "jay", version = version + 1 where id = 2 and version = 1;
测试乐观锁插件
1、增加乐观锁字段
2、实体类加对应的字段
/** * 乐观锁version注解 */ @Version private Integer version;
3、注册组件
package com.jay.mybatisplus.config; import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor; import org.mybatis.spring.annotation.MapperScan; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.transaction.annotation.EnableTransactionManagement; /** * @author : Jay * @description : 配置累 * @date : 2021-09-24 14:45 **/ //从启动类迁移到mybatisPlus的配置类 @MapperScan("com.jay.mybatisplus.mapper") //开启事务 @EnableTransactionManagement @Configuration public class MyBatisPlusConfig { /** * 注册乐观锁 */ @Bean public OptimisticLockerInterceptor optimisticLockerInterceptor() { return new OptimisticLockerInterceptor(); } }
4、测试日志及结果
正常的成功:
@Test void testOptimisticSuccess() { //1-查询用户信息 User user = userMapper.selectById(1); //2-修改用户信息 user.setName("Jay123"); user.setAge(220); userMapper.updateById(user); }
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@44af588b] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@1870234754 wrapping com.mysql.cj.jdbc.ConnectionImpl@332bcab0] will not be managed by Spring ==> Preparing: SELECT id,name,age,email,version,create_time,update_time FROM user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email, version, create_time, update_time <== Row: 1, Jone, 18, test1@baomidou.com, 1, 2021-09-24 13:49:18, null <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@44af588b] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f9fc8bd] was not registered for synchronization because synchronization is not active 2021-09-24 14:57:26.557 INFO 2774 --- [ main] c.j.m.handler.MyMetaObjectHandler : start update fill... JDBC Connection [HikariProxyConnection@365201320 wrapping com.mysql.cj.jdbc.ConnectionImpl@332bcab0] will not be managed by Spring ==> Preparing: UPDATE user SET name=?, age=?, email=?, version=?, create_time=?, update_time=? WHERE id=? AND version=? ==> Parameters: Jay123(String), 220(Integer), test1@baomidou.com(String), 2(Integer), 2021-09-24 13:49:18.0(Timestamp), 2021-09-24 14:57:26.557(Timestamp), 1(Long), 1(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@7f9fc8bd]
失败的情况:
@Test void testOptimisticFail() { //用户1查询用户信息 User user = userMapper.selectById(1); user.setName("Jay"); user.setAge(230); //用户2查询用户信息 User user1 = userMapper.selectById(1); user1.setName("lpp"); user1.setAge(220); //用户2修改用户信息 userMapper.updateById(user1); //用户1更新用户信息 userMapper.updateById(user); }
Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3d19d85] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@858507952 wrapping com.mysql.cj.jdbc.ConnectionImpl@633cc6b5] will not be managed by Spring ==> Preparing: SELECT id,name,age,email,version,create_time,update_time FROM user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email, version, create_time, update_time <== Row: 1, Jay123, 220, test1@baomidou.com, 2, 2021-09-24 13:49:18, 2021-09-24 14:57:27 <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3d19d85] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@75e09567] was not registered for synchronization because synchronization is not active JDBC Connection [HikariProxyConnection@708004780 wrapping com.mysql.cj.jdbc.ConnectionImpl@633cc6b5] will not be managed by Spring ==> Preparing: SELECT id,name,age,email,version,create_time,update_time FROM user WHERE id=? ==> Parameters: 1(Integer) <== Columns: id, name, age, email, version, create_time, update_time <== Row: 1, Jay123, 220, test1@baomidou.com, 2, 2021-09-24 13:49:18, 2021-09-24 14:57:27 <== Total: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@75e09567] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ddeaa5f] was not registered for synchronization because synchronization is not active 2021-09-24 15:04:20.322 INFO 2817 --- [ main] c.j.m.handler.MyMetaObjectHandler : start update fill... JDBC Connection [HikariProxyConnection@1208702946 wrapping com.mysql.cj.jdbc.ConnectionImpl@633cc6b5] will not be managed by Spring ==> Preparing: UPDATE user SET name=?, age=?, email=?, version=?, create_time=?, update_time=? WHERE id=? AND version=? ==> Parameters: lpp(String), 220(Integer), test1@baomidou.com(String), 3(Integer), 2021-09-24 13:49:18.0(Timestamp), 2021-09-24 15:04:20.322(Timestamp), 1(Long), 2(Integer) <== Updates: 1 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@3ddeaa5f] Creating a new SqlSession SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@443faa85] was not registered for synchronization because synchronization is not active 2021-09-24 15:04:20.330 INFO 2817 --- [ main] c.j.m.handler.MyMetaObjectHandler : start update fill... JDBC Connection [HikariProxyConnection@518290846 wrapping com.mysql.cj.jdbc.ConnectionImpl@633cc6b5] will not be managed by Spring ==> Preparing: UPDATE user SET name=?, age=?, email=?, version=?, create_time=?, update_time=? WHERE id=? AND version=? ==> Parameters: 刘平平(String), 230(Integer), test1@baomidou.com(String), 3(Integer), 2021-09-24 13:49:18.0(Timestamp), 2021-09-24 15:04:20.33(Timestamp), 1(Long), 2(Integer) <== Updates: 0 Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@443faa85] 2021-09-24 15:04:20.349 INFO 2817 --- [extShutdownHook] o.s.s.concurrent.ThreadPoolTaskExecutor : Shutting down ExecutorService 'applicationTaskExecutor' 2021-09-24 15:04:20.350 INFO 2817 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated... 2021-09-24 15:04:20.363 INFO 2817 --- [extShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed. Process finished with exit code 0
查询操作
/** * 普通查询 */ @Test void selectById(){ User user = userMapper.selectById(1); System.out.println(user); } /** * 批量查询 */ @Test void selectByList(){ List<User> users = userMapper.selectBatchIds(Arrays.asList(1, 2, 3)); users.forEach(System.out::println); } /** * 多条件查询 */ @Test void selectByMap(){ Map<String, Object> map = new HashMap<>(); map.put("name","断言"); map.put("age",24); List<User> users = userMapper.selectByMap(map); users.forEach(System.out::println); }
分页查询
分页的通常方式
1、原始的limit进行分页。
2、pageHelper第三方插件。
3、MP其实也内置来分页插件!
MybatisPlus入门(下)+https://developer.aliyun.com/article/1492264