暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

MybatisPlus的几个用法

百四乌托邦 2021-03-03
1967
近期的几个spring boot项目中使用了mybatis plus框架,发现这个框架特别强大,这里记录一下使用的几个功能,以便后续项目中使用时查阅。
一、作为持久层

使用mybatis plus作为持久层框架,在原来mybatis的基础上只做了增强,没有任何修改,所以在原来使用mybatis的项目中可以无影响的引入mybatis plus。使用方法如下

  1. maven项目导入依赖(目前没用过gradle)

      <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>mybatis-plus</artifactId>
      <version>3.4.2</version>
      </dependency>
    • application.yml中配置mybatis plus

        spring:
        datasource:
        # 配置数据源
        driver-class-name: com.mysql.cj.jdbc.Driver
        # 使用druid连接池
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://localhost:3306/medical?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
        username: root
        password: root
          mybatis-plus:
          global-config:
          db-config:
          id-type: auto
          field-strategy: not_empty
          table-underline: true
          db-type: mysql
          logic-delete-value: 1 # 逻辑已删除值(默认为 1)
          logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
          mapper-locations: classpath:/mapper/*.xml
          configuration:
          map-underscore-to-camel-case: false
            br
          • config中配置mybatis plus的分页插件以及sql语句打印


              @EnableTransactionManagement
              @Configuration
              public class MybatisPlusConfig {
              /**
              * 分页插件
              */
              @Bean
              public PaginationInterceptor paginationInterceptor() {
              return new PaginationInterceptor();
              }


              /**
              * 打印 sql
              */
              @Bean
              public PerformanceInterceptor performanceInterceptor() {
              PerformanceInterceptor performanceInterceptor = new PerformanceInterceptor();
              //格式化sql语句
              Properties properties = new Properties();
              properties.setProperty("format", "true");
              performanceInterceptor.setProperties(properties);
              return performanceInterceptor;
              }
              }
            • 使用mybatis plus的api

            • Bean给注解@TableName("tableName")

            • mapper继承BaseMapper<T>

            • service继承Iservice<T>

            • serviceImpl 继承ServiceImpl<M,T>,实现上面的service

            •  常用的增删查改为:save(),remove(),getOne(),list(),update()等


            二、作为mysql的二级缓存


            mybatis plus也可以结合redis作为mysql的二级缓存,大大提升了数据的查询速率。当查询数据时优先从redis中查找,修改数据时,先更新数据库的内容,然后将数据库的内容再复制到redis中。但是有个Bug,就是当有分页查询的时候不生效,无法从redis中分页查找数据,所以当分页查询时放弃从缓存中查找,直接从数据库中查找即可。本文中不记录redis的使用方法了,mybatis plus的设置步骤如下。
            1. mybatis plus开启二级缓存

                mybatis-plus.configuration.cache-enabled=true
              • config中配置mybatis plus

                  import com.baomidou.mybatisplus.extension.plugins.OptimisticLockerInterceptor;
                  import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor;
                  import com.fasterxml.jackson.annotation.JsonAutoDetect;
                  import com.fasterxml.jackson.annotation.PropertyAccessor;
                  import com.fasterxml.jackson.databind.DeserializationFeature;
                  import com.fasterxml.jackson.databind.ObjectMapper;
                  import org.springframework.context.annotation.Bean;
                  import org.springframework.context.annotation.Configuration;
                  import org.springframework.data.redis.connection.RedisConnectionFactory;
                  import org.springframework.data.redis.core.RedisTemplate;
                  import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
                  import org.springframework.data.redis.serializer.RedisSerializer;
                  import org.springframework.data.redis.serializer.StringRedisSerializer;
                  import org.springframework.transaction.annotation.EnableTransactionManagement;


                  @EnableTransactionManagement
                  @Configuration
                  public class MybatisPlusConfig {


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


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


                  @Bean(value = "redisTemplate")
                  public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory connectionFactory) {
                  RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();
                  redisTemplate.setConnectionFactory(connectionFactory);
                  //Use Jackson 2Json RedisSerializer to serialize and deserialize the value of redis (default JDK serialization)
                  Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(
                  Object.class);
                  ObjectMapper objectMapper = new ObjectMapper();
                  objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
                  //将类名称序列化到json串中
                  objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
                  //设置输入时忽略JSON字符串中存在而Java对象实际没有的属性
                  objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
                  jackson2JsonRedisSerializer.setObjectMapper(objectMapper);


                  //Use String RedisSerializer to serialize and deserialize the key value of redis
                  RedisSerializer redisSerializer = new StringRedisSerializer();
                  //key
                  redisTemplate.setKeySerializer(redisSerializer);
                  redisTemplate.setHashKeySerializer(redisSerializer);
                  //value
                  redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
                  redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer);


                  redisTemplate.afterPropertiesSet();
                  return redisTemplate;


                      }
                  }
                • 增加一个获取缓存数据的类

                    import com.qsm.core.common.utils.SpringUtil;
                    import java.util.Set;
                    import java.util.concurrent.locks.ReadWriteLock;
                    import java.util.concurrent.locks.ReentrantReadWriteLock;
                    import lombok.extern.slf4j.Slf4j;
                    import org.apache.ibatis.cache.Cache;
                    import org.springframework.data.redis.connection.RedisServerCommands;
                    import org.springframework.data.redis.core.RedisCallback;
                    import org.springframework.data.redis.core.RedisTemplate;
                    import org.springframework.util.CollectionUtils;


                    /**
                    * @author wuyanlong
                    */
                    @Slf4j
                    public class MybatisRedisCache implements Cache {




                    /**
                    * 读写锁
                    */
                    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);


                    /**
                    * 这里使用了redis缓存,使用springboot自动注入
                    */
                    private RedisTemplate<String, Object> redisTemplate;


                    private String id;


                    public MybatisRedisCache(final String id) {
                    if (id == null) {
                    throw new IllegalArgumentException("Cache instances require an ID");
                    }
                    this.id = id;
                    }


                    @Override
                    public String getId() {
                    return this.id;
                    }


                    @Override
                    public void putObject(Object key, Object value) {
                    if (redisTemplate == null) {
                    //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                    redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
                    }
                    if (value != null) {
                    if (key.toString().contains("selectPage")) {
                    return;
                    }
                    redisTemplate.opsForValue().set(key.toString(), value);
                    }
                    }


                    @Override
                    public Object getObject(Object key) {
                    if (redisTemplate == null) {
                    //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                    redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
                    }
                    try {
                    if (key != null) {
                    if (key.toString().contains("selectPage")) {
                    return null;
                    }
                    return redisTemplate.opsForValue().get(key.toString());
                    }
                    } catch (Exception e) {
                    e.printStackTrace();
                    log.error("缓存出错 ");
                    }
                    return null;
                    }


                    @Override
                    public Object removeObject(Object key) {
                    if (redisTemplate == null) {
                    //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                    redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
                    }
                    if (key != null) {
                    redisTemplate.delete(key.toString());
                    }
                    return null;
                    }


                    @Override
                    public void clear() {
                    log.debug("清空缓存");
                    if (redisTemplate == null) {
                    redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
                    }
                    Set<String> keys = redisTemplate.keys("*:" + this.id + "*");
                    if (!CollectionUtils.isEmpty(keys)) {
                    redisTemplate.delete(keys);
                    }
                    }


                    @Override
                    public int getSize() {
                    if (redisTemplate == null) {
                    //由于启动期间注入失败,只能运行期间注入,这段代码可以删除
                    redisTemplate = (RedisTemplate<String, Object>) SpringUtil.getBean("redisTemplate");
                    }
                    Long size = redisTemplate.execute((RedisCallback<Long>) RedisServerCommands::dbSize);
                    return size.intValue();
                    }


                    @Override
                    public ReadWriteLock getReadWriteLock() {
                    return this.readWriteLock;
                    }
                    }
                  • 获取redis操作bean,交给spring来管理

                      import org.springframework.beans.BeansException;
                      import org.springframework.context.ApplicationContext;
                      import org.springframework.context.ApplicationContextAware;
                      import org.springframework.stereotype.Component;


                      @Component
                      public class SpringUtil implements ApplicationContextAware {


                      private static ApplicationContext applicationContext;


                      @Override
                      public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
                      SpringUtil.applicationContext = applicationContext;
                      }


                      public static Object getBean(String name) {
                      return applicationContext.getBean(name);
                      }


                      public static <T> T getBean(String name, Class<T> clazz) {
                      return applicationContext.getBean(name, clazz);
                      }


                      public static <T> T getBean(Class<T> clazz) {
                      return applicationContext.getBean(clazz);
                      }
                      }


                    • mapper上加上@CacheNamespace的注解

                        import com.baomidou.mybatisplus.core.mapper.BaseMapper;
                        import com.qsm.core.common.config.MybatisRedisCache;
                        import com.qsm.core.entity.pojo.Aboutus;
                        import org.apache.ibatis.annotations.CacheNamespace;
                        import org.apache.ibatis.annotations.Mapper;


                        @Mapper
                        @CacheNamespace(implementation = MybatisRedisCache.class, eviction = MybatisRedisCache.class)
                        public interface AboutusMapper extends BaseMapper<Aboutus> {
                        }


                      文章转载自百四乌托邦,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                      评论