• 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多数据源】笔记就行
  • 相关阅读:
    阿里云遇到的坑:CentOS7防火墙(Firewalld),你关了吗?
    阿里云学生机——Mysql配置---教小白入门篇
    关于Javac编译器的那点事(一)
    B树,B+树,B*树简介
    ArrayList动态扩容机制
    满二叉树和完全二叉树
    nginx实践(二)之静态资源web服务(浏览器缓存场景)
    http之cdn介绍
    http之理解304
    nginx实践(一)之静态资源web服务
  • 原文地址:https://www.cnblogs.com/pengdt/p/13523315.html
Copyright © 2020-2023  润新知