zoukankan      html  css  js  c++  java
  • Mybatis-plus学习笔记,基于springboot

    1、依赖

    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-boot-starter</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>com.baomidou</groupId>
        <artifactId>mybatis-plus-generator</artifactId>
        <version>3.3.2</version>
    </dependency>
    <dependency>
        <groupId>org.apache.velocity</groupId>
        <artifactId>velocity-engine-core</artifactId>
        <version>2.2</version>
    </dependency>
    

    2、自动生成代码

    public class CodeBuilder {
        public static void main(String[] args) {
            AutoGenerator autoGenerator = new AutoGenerator();
    
            // 数据库表名
            String[] tableList = {
                    ""
            };
    
            // 作者
            String author = "";
            // 数据库乐观锁字段名
            String version = "version";
            // 数据库逻辑删除字段名
            String deleted = "deleted";
            // 数据库表前缀
            String tablePrefix = "";
            // 字段前缀
            String columnPrefix = "";
            // 包名
            String packageName = "";
    
            // JDBC
            String dataBaseUrl = "";
            String dataBaseDriverName = "";
            String dataBaseUsername = "";
            String dataBasePassword = "";
    
            // 自动填充配置
            // 根据自己的表结构修改
            // 创建时间
            TableFill createTime = new TableFill("f_create_time", FieldFill.INSERT);
            // 修改时间
            TableFill updateTime = new TableFill("f_update_time", FieldFill.INSERT_UPDATE);
            // 经办人ID
            TableFill operatorId = new TableFill("f_operator_id", FieldFill.INSERT_UPDATE);
            // 经办人名字
            TableFill operator = new TableFill("f_operator", FieldFill.INSERT_UPDATE);
    
            ArrayList<TableFill> list = new ArrayList<>();
    
            list.add(createTime);
            list.add(updateTime);
            list.add(operatorId);
            list.add(operator);
    
            // 全局配置
            GlobalConfig globalConfig = new GlobalConfig();
            String path = System.getProperty("user.dir");
            globalConfig.setOutputDir(path + "/src/main/java");
            globalConfig.setAuthor(author);
            globalConfig.setOpen(false);
            globalConfig.setServiceName("%sService");
            globalConfig.setControllerName("%sController");
            globalConfig.setEntityName("%sPO");
            globalConfig.setMapperName("%sDao");
            globalConfig.setFileOverride(true);
            globalConfig.setBaseResultMap(true);
            globalConfig.setBaseColumnList(true);
            globalConfig.setActiveRecord(true);
            globalConfig.setSwagger2(true);
            globalConfig.setIdType(IdType.AUTO);
            globalConfig.setDateType(DateType.ONLY_DATE);
            autoGenerator.setGlobalConfig(globalConfig);
    
            // 数据源配置
            DataSourceConfig dataSourceConfig = new DataSourceConfig();
            dataSourceConfig.setUrl(dataBaseUrl);
            dataSourceConfig.setDbType(DbType.MYSQL);
            dataSourceConfig.setDriverName(dataBaseDriverName);
            dataSourceConfig.setUsername(dataBaseUsername);
            dataSourceConfig.setPassword(dataBasePassword);
            autoGenerator.setDataSource(dataSourceConfig);
    
            // 包配置
            PackageConfig packageConfig = new PackageConfig();
            packageConfig.setMapper("dao");
            packageConfig.setController("controller");
            packageConfig.setEntity("entity.po");
            packageConfig.setService("service");
            packageConfig.setParent(packageName);
            autoGenerator.setPackageInfo(packageConfig);
    
            // 策略设置
            StrategyConfig strategy = new StrategyConfig();
            strategy.setInclude(tableList);
            strategy.setNaming(NamingStrategy.underline_to_camel);
            strategy.setColumnNaming(NamingStrategy.underline_to_camel);
            strategy.setEntityLombokModel(true);
            strategy.setRestControllerStyle(true);
            strategy.setControllerMappingHyphenStyle(true);
            strategy.setEntitySerialVersionUID(false);
            strategy.setEntityTableFieldAnnotationEnable(true);
            strategy.setVersionFieldName(version);
            strategy.setLogicDeleteFieldName(deleted);
            strategy.setNaming(NamingStrategy.underline_to_camel);
            strategy.setColumnNaming(NamingStrategy.underline_to_camel);
            strategy.setEntityColumnConstant(true);
            strategy.setChainModel(true);
            strategy.setTablePrefix(tablePrefix);
            strategy.setFieldPrefix(columnPrefix);
    
    
            strategy.setTableFillList(list);
    
            // RestFull 风格
            strategy.setRestControllerStyle(true);
            strategy.setControllerMappingHyphenStyle(true);
    
            autoGenerator.setStrategy(strategy);
    
            autoGenerator.execute();
    
        }
    
    
    }
    
    

    3、springboot注解添加mapperscan

    @MapperScan("com.hong.mapper")//可以写在MybatisplusConfig中
    

    4、注解

    @TableName

    • 表名注解

      属性 类型 必须指定 默认值 描述
      value String "" 表名
      schema String "" schema
      keepGlobalPrefix boolean false 是否保持使用全局的 tablePrefix 的值(如果设置了全局 tablePrefix 且自行设置了 value 的值)
      resultMap String "" xml 中 resultMap 的 id
      autoResultMap boolean false 是否自动构建 resultMap 并使用(如果设置 resultMap 则不会进行 resultMap 的自动构建并注入)

    @TableId

    • 主键注解

      属性 类型 必须指定 默认值 描述
      value String "" 主键字段名
      type Enum IdType.NONE 主键类型
    • IdType

      描述
      AUTO 数据库ID自增
      NONE 无状态,该类型为未设置主键类型(注解里等于跟随全局,全局里约等于 INPUT)
      INPUT insert前自行set主键值
      ASSIGN_ID 分配ID(主键类型为Number(Long和Integer)或String)(since 3.3.0),使用接口IdentifierGenerator的方法nextId(默认实现类为DefaultIdentifierGenerator雪花算法)

    @TableField

    • 字段注解

      属性 类型 必须指定 默认值 描述
      value String "" 数据库字段名
      el String "" 映射为原生 #{ ... } 逻辑,相当于写在 xml 里的 #{ ... } 部分
      exist boolean true 是否为数据库表字段
      condition String "" 字段 where 实体查询比较条件,有值设置则按设置的值为准,没有则为默认全局的 %s=#{%s},参考
      update String "" 字段 update set 部分注入, 例如:update="%s+1":表示更新时会set version=version+1(该属性优先级高于 el 属性)
      insertStrategy Enum N DEFAULT 举例:NOT_NULL: insert into table_a(column) values (#{columnProperty})
      updateStrategy Enum N DEFAULT 举例:IGNORED: update table_a set column=#{columnProperty}
      whereStrategy Enum N DEFAULT 举例:NOT_EMPTY: where column=#{columnProperty}
      fill Enum FieldFill.DEFAULT 字段自动填充策略
      select boolean true 是否进行 select 查询
      keepGlobalFormat boolean false 是否保持使用全局的 format 进行处理
      jdbcType JdbcType JdbcType.UNDEFINED JDBC类型 (该默认值不代表会按照该值生效)
      typeHandler Class<? extends TypeHandler> UnknownTypeHandler.class 类型处理器 (该默认值不代表会按照该值生效)
      numericScale String "" 指定小数点后保留的位数

    @Version

    • 乐观锁

    @TableLogic

    • 逻辑删除注解

      属性 类型 必须指定 默认值 描述
      value String "" 逻辑未删除值
      delval String "" 逻辑删除值

    5、配置插件

    1、日志(控制台输出)

    #配置日志输出
    mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
    

    2、自动填充策略

    • 数据库添加对应字段

      • create_time

      • update_time

      • datetime 类型

    • 对应属性需要加上注解

          @TableField(fill = FieldFill.INSERT)
          private Date creatTime;
      
          @TableField(fill = FieldFill.INSERT_UPDATE)
          private Date updateTime;
      
    • 编写MybatisPlusConfig类

      @Configuration
      public class MybatisPlusConfig {
      
      
          /**
           * 注册字段自动填充
           *
           * @return
           */
          @Bean
          public MetaObjectHandler getMetaObjectHandler() {
      
              return new MetaObjectHandler() {
                  @Override
                  public void insertFill(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);
                  }
              };
          }
      
          /**
           * 乐观锁插件
           *
           * @return
           */
          @Bean
          public OptimisticLockerInterceptor getOptimisticLockerInterceptor() {
              return new OptimisticLockerInterceptor();
          }
      
          /**
           * 分页插件
           *
           * @return
           */
          @Bean
          public PaginationInterceptor paginationInterceptor() {
              return new PaginationInterceptor();
          }
      
      }
      
      

    3、乐观锁version

    • 数据库添加对应字段,默认值为1

      • version
    • 实体类添加对应注解

          @Version
          private Integer version;
      

    4、逻辑删除

    • 解释:在逻辑上实现删除,实际上数据库没有被删除,但是普通用户查询不到,只有管理员能查询

    • 在数据库添加对应字段,默认0为没有删除,1为逻辑删除

      • deleted
    • 实体类中添加对应注解

          @TableLogic
          private Integer deleted;
      

    5、分页

    • 查询测试

          @Test
          void selectPageTest() {
              //参数一:当前页
              //参数二:页面大小
              Page<TUser> objectPage = new Page<>(1,2);
              tUserMapper.selectPage(objectPage,null);
              objectPage.getRecords().forEach(System.out::println);
          }
      

    6、性能分析插件(P6spy)

    • 导入依赖

      <dependency>
          <groupId>p6spy</groupId>
          <artifactId>p6spy</artifactId>
          <version>3.9.0</version>
      </dependency>
      
    • 接着编辑 application.properties 文件,更换数据库连接驱动:

      #数据库信息配置
      spring.datasource.username=
      spring.datasource.password=
      spring.datasource.url=jdbc:p6spy:mysql:
      spring.datasource.driver-class-name=com.p6spy.engine.spy.P6SpyDriver
      
    • 最后创建 spy.properties 配置文件即可

      #3.2.1以上使用
      modulelist=com.baomidou.mybatisplus.extension.p6spy.MybatisPlusLogFactory,com.p6spy.engine.outage.P6OutageFactory
      # 自定义日志打印
      logMessageFormat=com.baomidou.mybatisplus.extension.p6spy.P6SpyLogger
      #日志输出到控制台
      appender=com.baomidou.mybatisplus.extension.p6spy.StdoutLogger
      # 使用日志系统记录 sql
      #appender=com.p6spy.engine.spy.appender.Slf4JLogger
      # 设置 p6spy driver 代理
      deregisterdrivers=true
      # 取消JDBC URL前缀
      useprefix=true
      # 配置记录 Log 例外,可去掉的结果集有error,info,batch,debug,statement,commit,rollback,result,resultset.
      excludecategories=info,debug,result,commit,resultset
      # 日期格式
      dateformat=yyyy-MM-dd HH:mm:ss
      # 实际驱动可多个
      #driverlist=org.h2.Driver
      # 是否开启慢SQL记录
      outagedetection=true
      # 慢SQL记录标准 2 秒
      outagedetectioninterval=2
      

    7、多数据源

    • 导入依赖
    <dependency>
      <groupId>com.baomidou</groupId>
      <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
      <version>3.2.0</version>
    </dependency>
    
    • 数据源配置文件
    spring:
      datasource:
        dynamic:
          primary: master #设置默认的数据源或者数据源组,默认值即为master
          strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
          datasource:
            master:
              url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
            slave_1:
              url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
              username: root
              password: 123456
              driver-class-name: com.mysql.jdbc.Driver
            slave_2:
              url: ENC(xxxxx) # 内置加密,使用请查看详细文档
              username: ENC(xxxxx)
              password: ENC(xxxxx)
              driver-class-name: com.mysql.jdbc.Driver
              schema: db/schema.sql # 配置则生效,自动初始化表结构
              data: db/data.sql # 配置则生效,自动初始化数据
              continue-on-error: true # 默认true,初始化失败是否继续
              separator: ";" # sql默认分号分隔符
              
           #......省略
           #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
    
    • 使用@DS注解切换数据源
    @Service
    @DS("slave")
    public class UserServiceImpl implements UserService {
    
      @Autowired
      private JdbcTemplate jdbcTemplate;
    
      public List selectAll() {
        return  jdbcTemplate.queryForList("select * from user");
      }
      
      @Override
      @DS("slave_1")
      public List selectByCondition() {
        return  jdbcTemplate.queryForList("select * from user where age >10");
      }
    }
    

    6、CRUD(service层)

    save

    // 插入一条记录(选择字段,策略插入)
    boolean save(T entity);
    // 插入(批量)
    boolean saveBatch(Collection<T> entityList);
    // 插入(批量)
    boolean saveBatch(Collection<T> entityList, int batchSize);
    

    remove

    // 根据 entity 条件,删除记录
    boolean remove(Wrapper<T> queryWrapper);
    // 根据 ID 删除
    boolean removeById(Serializable id);
    // 根据 columnMap 条件,删除记录
    boolean removeByMap(Map<String, Object> columnMap);
    // 删除(根据ID 批量删除)
    boolean removeByIds(Collection<? extends Serializable> idList);
    

    update

    // 根据 UpdateWrapper 条件,更新记录 需要设置sqlset
    boolean update(Wrapper<T> updateWrapper);
    // 根据 whereEntity 条件,更新记录
    boolean update(T entity, Wrapper<T> updateWrapper);
    // 根据 ID 选择修改
    boolean updateById(T entity);
    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList);
    // 根据ID 批量更新
    boolean updateBatchById(Collection<T> entityList, int batchSize);
    

    get

    // 根据 ID 查询
    T getById(Serializable id);
    // 根据 Wrapper,查询一条记录。结果集,如果是多个会抛出异常,随机取一条加上限制条件 wrapper.last("LIMIT 1")
    T getOne(Wrapper<T> queryWrapper);
    // 根据 Wrapper,查询一条记录
    T getOne(Wrapper<T> queryWrapper, boolean throwEx);
    // 根据 Wrapper,查询一条记录
    Map<String, Object> getMap(Wrapper<T> queryWrapper);
    // 根据 Wrapper,查询一条记录
    <V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);
    

    7、整合redis使用二级缓存

    • 编写application.properties配置文件,引入redis地址
    spring.redis.host=127.0.0.1
    spring.redis.port=6379
    spring.redis.database=0
    
    • 编写MybatisRedisConfig配置文件
      • 引入StringRedisTemplate防止数据在redis中显示乱码
      • 传入redis时转为JSON字符串,从redis中获得时解析JSON字符串
    package com.hong.config;
    
    import com.alibaba.fastjson.JSON;
    import com.alibaba.fastjson.JSONArray;
    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.cache.Cache;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.redis.core.RedisCallback;
    
    import org.springframework.data.redis.core.RedisTemplate;
    import org.springframework.data.redis.core.StringRedisTemplate;
    import org.springframework.data.redis.core.ValueOperations;
    import org.springframework.data.redis.serializer.RedisSerializer;
    import org.springframework.data.redis.serializer.StringRedisSerializer;
    
    import java.util.concurrent.TimeUnit;
    import java.util.concurrent.locks.ReadWriteLock;
    import java.util.concurrent.locks.ReentrantReadWriteLock;
    
    
    @Slf4j
    public class MybatisRedisConfig implements Cache {
        //失效时间
        private static final long EXPIRE_TIME_IN_MINUTES = 30;
        private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
        // cache instance id
        private final String id;
        //redis操作工具类
    
        @Autowired
        private StringRedisTemplate redisTemplate;
    
    
        public MybatisRedisConfig(String id) {
            if (id == null) {
                throw new IllegalArgumentException("Cache instances require an ID");
            }
            this.id = id;
        }
    
    
        @Override
        public String getId() {
            return id;
        }
    
        @Override
        @SuppressWarnings("unchecked")
        public void putObject(Object key, Object value) {
            this.redisTemplate.opsForValue().set(key.toString(), JSON.toJSONString(value), EXPIRE_TIME_IN_MINUTES, TimeUnit.MINUTES);
            log.info("Put query result to redis");
        }
    
        /**
         * Get cached query result from redis
         *
         * @param key
         * @return
         */
        @Override
        public Object getObject(Object key) {
            log.info("Get cached query result from redis");
            if (this.redisTemplate == null) {
                this.redisTemplate = SpringContextUtil.getBean("stringRedisTemplate");
            }
            return JSON.parse(this.redisTemplate.opsForValue().get(key.toString()));
        }
    
        /**
         * Remove cached query result from redis
         *
         * @param key
         * @return
         */
        @Override
        @SuppressWarnings("unchecked")
        public Object removeObject(Object key) {
            this.redisTemplate.delete(key.toString());
            log.info("Remove cached query result from redis");
            return null;
        }
    
        /**
         * Clears this cache instance
         */
        @Override
        public void clear() {
            this.redisTemplate.execute((RedisCallback) connection -> {
                connection.flushDb();
                return null;
            });
            log.info("Clear all the cached query result from redis");
        }
    
        @Override
        public int getSize() {
            return 0;
        }
    
        @Override
        public ReadWriteLock getReadWriteLock() {
            return readWriteLock;
        }
    
    }
    
    
    • 在mapper上加上注解
    @CacheNamespace(implementation = MybatisRedisConfig.class,eviction = MybatisRedisConfig.class)
    
  • 相关阅读:
    Bundle Adjustment
    BFL ekf imu and odom
    RNN
    深度学习的数学(笔记)
    BP 神经网络
    PCA
    SVM
    KNN
    Kmeans
    决策树
  • 原文地址:https://www.cnblogs.com/wzh7/p/13577325.html
Copyright © 2011-2022 走看看