您觉得本文档还缺少什么内容?可以自己补充~

数据库相关的配置全部位于mysql.yml

bc:
  mysql:
    ip: 127.0.0.1
    port: 3306
    driverClassName: com.mysql.cj.jdbc.Driver
    database: bc_column
    username: 'root'
    password: 'root'
    url: jdbc:mysql://${bc.mysql.ip}:${bc.mysql.port}/${bc.mysql.database}?serverTimezone=CTT&characterEncoding=utf8&useUnicode=true&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&nullCatalogMeansCurrent=true
  database: # 字段介绍参考 DatabaseProperties
    multiTenantType: COLUMN
    # COLUMN模式中隔离 租户 的列名
    tenantIdColumn: tenant_code
    # 是否不允许写入数据  WriteInterceptor
    isNotWrite: false
    # 是否启用  sql性能规范插件
    isBlockAttack: false
    # 是否启用  sql性能规范插件
    isIllegalSql: false
    # 是否启用分布式事务
    isSeata: false
    # 生产环境请设置p6spy = false
    p6spy: true
    # 分页大小限制
    maxLimit: -1
    # 数据库类型
    dbType: MYSQL
    # 溢出总页数后是否进行处理
    overflow: true
    # 生成 countSql 优化掉 join 现在只支持 left join
    optimizeJoin: true
    # 是否启用数据权限
    isDataScope: true
    # id生成策略
    id-type: HU_TOOL
    hutoolId:
      workerId: 0
      dataCenterId: 0
    cache-id:
      time-bits: 31
      worker-bits: 22
      seq-bits: 10
      epochStr: '2020-09-15'
      boost-power: 3
      padding-factor: 50

# mysql 通用配置
spring:
  autoconfigure:
    exclude: org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  datasource:
    dynamic:
      enabled: false  # 这里一定要写成false,无论是什么模式
    druid:
      enable: true
      # 从这里开始(druid)
      username: ${bc.mysql.username}
      password: ${bc.mysql.password}
      driver-class-name: ${bc.mysql.driverClassName}
      url: jdbc:mysql://${bc.mysql.ip}:${bc.mysql.port}/${bc.mysql.database}?serverTimezone=CTT&characterEncoding=utf8&useUnicode=true&useSSL=false&autoReconnect=true&zeroDateTimeBehavior=convertToNull&allowMultiQueries=true&nullCatalogMeansCurrent=true
      db-type: mysql
      initialSize: 10  #初始的数据源链接数
      minIdle: 10   # 最小连接池数量
      maxActive: 200  # 最大连接池数量
      max-wait: 60000   # 获取连接时最大等待时间,单位毫秒。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降,如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
      pool-prepared-statements: true  # 是否缓存preparedStatement,也就是PSCache。PSCache对支持游标的数据库性能提升巨大,比如说oracle。在mysql下建议关闭。
      max-pool-prepared-statement-per-connection-size: 20   # 要启用PSCache,必须配置大于0,当大于0时,poolPreparedStatements自动触发修改为true。在Druid中,不会存在Oracle下PSCache占用内存过多的问题,可以把这个数值配置大一些,比如说100
      validation-query: SELECT 'x'   # 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。
      test-on-borrow: false  # 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。
      test-on-return: false  # 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能
      test-while-idle: true # 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。
      time-between-eviction-runs-millis: 60000  #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      min-evictable-idle-time-millis: 300000    #配置一个连接在池中最小生存的时间,单位是毫秒
      filters: stat,wall     # 属性类型是字符串,通过别名的方式配置扩展插件,常用的插件有:   监控统计用的filter:stat 、 日志用的filter:log4j  、  防御sql注入的filter:wall
      filter:
        wall:
          enabled: true
          config:
            commentAllow: true
            multiStatementAllow: true
            noneBaseStatementAllow: true
      # 从这里结束(druid)

      # 以下的2段配置,同时适用于所有模式
      web-stat-filter:  # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter
        enabled: true
        url-pattern: /*
        exclusions: "*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*"
        session-stat-max-count: 1000
        profile-enable: true
        session-stat-enable: false
      stat-view-servlet:  #展示Druid的统计信息,StatViewServlet的用途包括:1.提供监控信息展示的html页面2.提供监控信息的JSON API
        enabled: true
        url-pattern: /druid/*   #根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html例如:http://127.0.0.1:9000/druid/index.html
        reset-enable: true    #允许清空统计数据
        login-username: bc
        login-password: bc
        allow: ''

禁止在控制台打印sql

bc:
  database:
    # 生产环境请设置p6spy = false
    p6spy: true

调整在控制台打印的sql参数或格式

public class TenantP6SpyLogger implements MessageFormattingStrategy {
    public static final String REGX = "[\\s]+";

    @Override
    public String formatMessage(int connectionId, String now, long elapsed, String category,
                                String prepared, String sql, String url) {
        return StringUtils.isNotBlank(sql) ?
                StrUtil.format(" tenant: {} userId: {} \n Consume Time:{} ms {} \n url: {} \n Execute SQL:{} \n",
                        ContextUtil.getTenant(), ContextUtil.getUserId(), elapsed, now, url, sql.replaceAll(REGX, StringPool.SPACE)) :
                StringPool.EMPTY;
    }
}

使用自定义sql时,如何优雅的写模糊查询参数

  • xml中自定义sql:

    select * from user where 1=1 
    and name like #{keyword, typeHandler=fullLike}     
    and account like #{keyword, typeHandler=leftLike}
    and describe like #{keyword, typeHandler=rightLike}
    
  • 实际sql:

    select * from user where 1=1  and name like '%张三%'  and account like '%bc'   and describe  like '工作%'
    
  • 原理:

    FullLikeTypeHandler、LeftLikeTypeHandler、RightLikeTypeHandler

id、createdDate、createdBy、lastModifiedBy、lastModifiedDate 等字段如何自动填充 ?

  • 原理:
    • 实现元对象处理器接口:BcMetaObjectHandler
    • 注解填充字段@TableField(.. fill = FieldFill.INSERT)生成器策略部分也可以配置!
public class User {

    // 注意!这里需要标记为填充字段
    @TableField(.. fill = FieldFill.INSERT)
    private String fillField;

    ....
}

集群部署如何配置雪花id规则? 为什么id为重复?

bc:
  database: 
    id-type: HU_TOOL   # HU_TOOL、 DEFAULT、CACHE
    hutoolId:
      workerId: 0                          
      dataCenterId: 0
    cache-id:
      time-bits: 31
      worker-bits: 22
      seq-bits: 10
      epochStr: '2020-09-15'
      boost-power: 3
      padding-factor: 50

雪花id生成类型有3种: HU_TOOL、DEFAULT、CACHE

  • HU_TOOL: 使用hutool 提供的雪花生成算法,集群部署时,需要保证每个节点读取到的 bc.database.hutoolId.workerIdbc.database.hutoolId.dataCenterId 不一样,否则可能会造成id重复问题
  • DEFAULT:UidGenerator通过借用未来时间来解决sequence天然存在的并发限制。
  • CACHE( 推荐使用 ):采用RingBuffer来缓存已生成的UID, 并行化UID的生产和消费, 同时对CacheLine补齐,避免了由RingBuffer带来的硬件级「伪共享」问题 。

其中 DEFAULT、CACHE 依赖于 worker_node 表, 工作原理是: 每次启动项目时,自增一条数据,使用自增id 作为雪花id的 workerId ,避免了集群部署时,动态扩展和缩减节点,需要手动配置不同的workerId 的问题。 而CACHE模式,是在DEFAULT模式的基础上做了缓存,性能更好。 所以集群部署,尤其是需要动态扩容时,强烈建议使用 CACHE 模式。

如何在 SuperMapper 中,增加方法

  1. 在SuperMapper中定义方法接口,如:

    /**
      * 全量修改所有字段
      * @param entity 实体
      * @return 修改数量
      */
      int updateAllById(@Param(Constants.ENTITY) T entity);
    
  2. 定义 updateAllById 方法的动态sql. (具体的实现代码位于: AlwaysUpdateSomeColumnById )

@NoArgsConstructor
public class UpdateAllById extends AlwaysUpdateSomeColumnById {

    public UpdateAllById(Predicate<TableFieldInfo> predicate) {
        super(predicate);
    }

    @Override
    public String getMethod(SqlMethod sqlMethod) {
        // 自定义 mapper 方法名
        return "updateAllById";
    }
}
  1. 注入 UpdateAllById
public class BcSqlInjector extends DefaultSqlInjector {
    @Override
    public List<AbstractMethod> getMethodList(Class<?> mapperClass, TableInfo tableInfo) {
        List<AbstractMethod> methodList = super.getMethodList(mapperClass, tableInfo);


        methodList.add(new UpdateAllById(field -> !ArrayUtil.containsAny(new String[]{
                SuperEntity.CREATE_TIME_COLUMN, SuperEntity.CREATED_BY_COLUMN
        }, field.getColumn())));
        return methodList;
    }
}
  1. 配置 BcSqlInjector
@Bean
@ConditionalOnMissingBean
public BcSqlInjector getMySqlInjector() {
    return new BcSqlInjector();
}

results matching ""

    No results matching ""