MybatisPlus

前言
在Mybatis笔记里就的辅助插件里就提到了MybatisPlus,这个就是Mybatis的升级版,并且融合和很多的插件,封装了所有简单的CURD操作,这里是使用的springboot整合,不是ssm,笔记全部来自B站大神【狂神说】,感谢

引入插件,这个依赖自带了mybatis,所以只需要这个就行,原来如果有mybatis依赖全删了,不会有什么影响的

<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>

配置文件,这里是整个笔记的配置

# 表示当前的模式,相当于node的env
spring.profiles.active=dev

# 链接数据库
spring.datasource.username=xxx
spring.datasource.password=xxx
spring.datasource.url=jdbc:mysql://localhost:3306/【name】?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# mybatis配置,扫描文件这里不写,写在注解里
# 基础日记配置
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 配置的缓存的全局开关,默认不缓存
# mybatis-plus.configuration.cache-enabled=true
# 逻辑删除的配置
mybatis-plus.global-config.db-config.logic-delete-value=1
mybatis-plus.global-config.db-config.logic-not-delete-value=0

建表和Bean

  • 需要的字段有【主键id,name,age,email】
  • 还有几个真正的企业表都需要有的字段【乐观锁version(int),逻辑删除deleted(int,并且默认值设置成 0),创建时间createTime(datatime),更新时间updateTime(datatime)】
  • bean类
@TableName("t_user")
public class User {
     
    // 表明数据库中的主键
    // 这样在插入的时候就不用自己去set一个了
    // 如果不打算自动生成,可以把type改成NONE
       // AUTO : 数据库ID自增,需要给数据库设置自增
       // INPUT : 用户输入ID
       // ID_WORKER : 全局唯一ID,雪花算法
       // UUID : 全局唯一ID
       // NONE : 该类型为未设置主键类型
    @TableId(type = IdType.AUTO)
    private Long id;
    private String name;
    private Integer age;
    private String email;

    @Version //乐观锁Version注解
    private Integer version;

    @TableLogic //逻辑删除
    private Integer deleted;

    // 字段添加填充内容
    @TableField(fill = FieldFill.INSERT)
    private Date createTime;

    @TableField(fill = FieldFill.INSERT_UPDATE)
    private Date updateTime;
}

配置乐观锁,分页,逻辑删除,sql效率计算的插件,固定写法

@EnableTransactionManagement
@Configuration // 配置类
public class MyBatisPlusConfig {

    // 注册乐观锁插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }

    // 分页插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return  new PaginationInterceptor();
    }

    // 逻辑删除组件!
    @Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }

    /**
     * SQL执行效率插件
     */
    @Bean
    @Profile({"dev","test"})// 设置 dev test 环境开启,保证我们的效率
    public PerformanceInterceptor performanceInterceptor() {
        PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
        performanceInterceptor.setMaxTime(100); //ms 设置sql执行的最大时间,如果超过了则不执行
        performanceInterceptor.setFormat(true);
        return performanceInterceptor;
    }
}

配置自动填充创建时间和更新时间功能

@Component // 一定不要忘记把处理器加到IOC容器中!
public class MyMetaObjectHandler implements MetaObjectHandler {
    // 插入时的填充策略
    @Override
    public void insertFill(MetaObject metaObject) {
        // setFieldValByName(String fieldName, Object fieldVal, MetaObject metaObject
        this.setFieldValByName("createTime",new Date(),metaObject);
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    // 更新时的填充策略
    @Override
    public void updateFill(MetaObject metaObject) {
        this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

一个空白的dao接口,因为继承了BaseMapper下的所有简单CURD操作,所以什么都不用写,如果有特别的多表操作等等,可以在这个类里自定义,但是要注意方法名不能重名,还要记得传入<Bean泛型>

@Repository // 代表持久层
public interface UserMapper extends BaseMapper<User> {
    // 所有的CRUD操作都已经编写完成了
    // 你不需要像以前的配置一大堆文件了!
}

springboot入口和mapper扫描

@SpringBootApplication
@MapperScan("com.mbp.mapper")
public class MybatisPlusApplication {
    public static void main(String[] args) {
        SpringApplication.run(MybatisPlusApplication.class, args);
    }
}

开始使用

@Autowired
private UserMapper userMapper;

@Test
void contextLoads() {
    // 参数是一个 Wrapper ,条件构造器,这里我们先不用 null
    // 查询全部用户
    List<User> users = userMapper.selectList(null);
    users.forEach(System.out::println);
}

// 测试插入
@Test
public void testInsert(){
    User user = new User();
    user.setName("狂神说Java");
    user.setAge(3);
    user.setEmail("24736743@qq.com");

    int result = userMapper.insert(user); // 帮我们自动生成id
    System.out.println(result); // 受影响的行数
    System.out.println(user); // 发现,id会自动回填
}

// 测试更新
@Test
public void testUpdate(){
    User user = new User();
    // 通过条件自动拼接动态sql
    user.setId(1240620674645544965L);
    user.setName("关注公众号:狂神说");
    user.setAge(20);
    // 注意:updateById 但是参数是一个 对象!
    int i = userMapper.updateById(user);
    System.out.println(i);
}

// 测试乐观锁成功!
@Test
public void testOptimisticLocker(){
    // 1、查询用户信息
    User user = userMapper.selectById(1L);
    // 2、修改用户信息
    user.setName("kuangshen");
    user.setEmail("24736743@qq.com");
    // 3、执行更新操作
    userMapper.updateById(user);
}


// 测试乐观锁失败!多线程下
@Test
public void testOptimisticLocker2(){

    // 线程 1
    User user = userMapper.selectById(1L);
    user.setName("kuangshen111");
    user.setEmail("24736743@qq.com");

    // 模拟另外一个线程执行了插队操作
    User user2 = userMapper.selectById(1L);
    user2.setName("kuangshen222");
    user2.setEmail("24736743@qq.com");
    userMapper.updateById(user2);

    // 自旋锁来多次尝试提交!
    userMapper.updateById(user); // 如果没有乐观锁就会覆盖插队线程的值!
}

// 测试查询
@Test
public void testSelectById(){
    User user = userMapper.selectById(1L);
    System.out.println(user);
}

// 测试批量查询!
@Test
public void testSelectByBatchId(){
    List<User> users = userMapper.selectBatchIds(Arrays.asList(id1, id2...));
    users.forEach(System.out::println);
}

// 按条件查询之一使用map操作
@Test
public void testSelectByBatchIds(){
    HashMap<String, Object> map = new HashMap<>();
    // 自定义要查询
    map.put("name","狂神说Java");
    map.put("age",3);

    List<User> users = userMapper.selectByMap(map);
    users.forEach(System.out::println);
}

// 测试分页查询
@Test
public void testPage(){
    //  参数一:当前页
    //  参数二:页面大小
    //  使用了分页插件之后,所有的分页操作也变得简单的!
    Page<User> page = new Page<>(2,5);
    userMapper.selectPage(page,null);

    page.getRecords().forEach(System.out::println);
    System.out.println(page.getTotal());
}


// 测试删除
@Test
public void testDeleteById(){
    userMapper.deleteById(1L);
}

// 通过id批量删除
@Test
public void testDeleteBatchId(){
userMapper.deleteBatchIds(Arrays.asList(id1,id2...));
}

// 通过map删除
@Test
public void testDeleteMap(){
    HashMap<String, Object> map = new HashMap<>();
    map.put("name","狂神说Java");
    userMapper.deleteByMap(map);
}

复杂搜索,可以看到上面的删除和搜索是传的Map,Map适合于多条件全匹配搜索,如果需要判断大于小于就做不了了

@Autowired
private UserMapper userMapper;

@Test
void contextLoads() {
    // 查询name不为空的用户,并且邮箱不为空的用户,年龄大于等于12
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper
            .isNotNull("name")
            .isNotNull("email")
            .ge("age",12);
    userMapper.selectList(wrapper).forEach(System.out::println); // 和我们刚才学习的map对比一下
}

@Test
void test2(){
    // 查询名字狂神说
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.eq("name","狂神说");
    User user = userMapper.selectOne(wrapper); // 查询一个数据,出现多个结果使用List 或者 Map
    System.out.println(user);
}

@Test
void test3(){
    // 查询年龄在 20 ~ 30 岁之间的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    wrapper.between("age",20,30); // 区间
    Integer count = userMapper.selectCount(wrapper);// 查询结果数
    System.out.println(count);
}

// 模糊查询
@Test
void test4(){
    // 查询年龄在 20 ~ 30 岁之间的用户
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    // 左和右  t%
    wrapper
            .notLike("name","e")
            .likeRight("email","t");

    List<Map<String, Object>> maps = userMapper.selectMaps(wrapper);
    maps.forEach(System.out::println);
}

// 模糊查询
@Test
void test5(){

    QueryWrapper<User> wrapper = new QueryWrapper<>();
    // id 在子查询中查出来
    wrapper.inSql("id","select id from user where id<3");

    List<Object> objects = userMapper.selectObjs(wrapper);
    objects.forEach(System.out::println);
}

//测试六
@Test
void test6(){
    QueryWrapper<User> wrapper = new QueryWrapper<>();
    // 通过id进行排序
    wrapper.orderByAsc("id");

    List<User> users = userMapper.selectList(wrapper);
    users.forEach(System.out::println);
}

使用MybatisPlus一下子开发速度快了10倍,又快有快乐,MybatisPlus也自带了逆向生成代码的工具,但手写还是容易控制,需要的自行百度

分库分表

  • 把自增的表ID改成雪花算法ID
  • 其他的查看【Mybatis多数据源】笔记就行
原文地址:https://www.cnblogs.com/pengdt/p/13523315.html