mybatis 自动填充无效_开发小知识-mybatis-plus自动填充与读写分离

mybatis-plus 自动填充

说明

我们在设计表结构的时候,往往会额外添多如下几个字段

create_time【表字段】-- createTime【实体字段】 : 创建时间

update_time【表字段】-- updateTime【实体字段】:更新时间

create_by【表字段】-- createBy 【实体字段】: 创建人

update_by【表字段】--updateBy 【实体字段】:更新人

del_flag【表字段】-- delFlag【实体字段】 : 逻辑删除标识【0:未删除、1:已删除】

在编写实体类【与数据映射】的时候,不能总在每个类上都编写上述几个属性,显得有些冗余,于是我们将这几个属性提取出来

并在对应的属性上标注mybatis-plus的填充注解,那么所有继承BaseEntity的类将会拥有createTime,updateTime属性,继承DefaultEntity的类将会拥有createTime、updateTime、createBy、updateBy、delFlag属性。

至于为什么会设计两个类,是因为有些中间表可能不需要用到createBy、updateBy、delFlag属性,只需要createTime,updateTime属性。

依赖引入

com.baomidou

mybatis-plus-boot-starter

3.3.2

org.projectlombok

lombok

1.18.12

公用实体类定义

package com.cloud.pango.common.core.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;

import com.baomidou.mybatisplus.annotation.TableField;

import lombok.Data;

import lombok.EqualsAndHashCode;

import lombok.ToString;

import java.util.Date;

@Data

@ToString

@EqualsAndHashCode

public class BaseEntity{

@TableField(fill = FieldFill.INSERT)//插入时填充

private Date createTime;

@TableField(fill = FieldFill.INSERT_UPDATE)//插入货更新时填充

private Date updateTime;

}

package com.cloud.pango.common.core.entity;

import com.baomidou.mybatisplus.annotation.FieldFill;

import com.baomidou.mybatisplus.annotation.TableField;

import com.baomidou.mybatisplus.annotation.TableLogic;

import lombok.Data;

import lombok.EqualsAndHashCode;

import lombok.ToString;

@Data

@ToString

@EqualsAndHashCode

public class DefaultEntity extends BaseEntity{

@TableField(fill = FieldFill.INSERT) //插入时填充

private String createBy;

@TableField(fill = FieldFill.INSERT_UPDATE)//插入或更新时填充

private String updateBy;

@TableField(fill = FieldFill.INSERT) //插入时填充

@TableLogic//逻辑删除

private Integer delFlag;

}

自动填充处理

package com.cloud.pango.common.mybatis;

import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;

import lombok.extern.slf4j.Slf4j;

import org.apache.ibatis.reflection.MetaObject;

import org.springframework.beans.factory.annotation.Autowired;

import java.util.Date;

@Slf4j

public class EntityMetaObjectHanlder implements MetaObjectHandler {

private final static String CREATE_TIME = "createTime";

private final static String UPDATE_TIME = "updateTime";

private final static String CREATE_BY = "createBy";

private final static String UPDATE_BY = "updateBy";

private final static String DEL_FLAG = "delFlag";

@Autowired

private MetaObjectOperator metaObjectOperator;

private void setMeta(MetaObject metaObject,String field,Object defaultValue){

if(metaObject.hasGetter(field)){

Object value = metaObject.getValue(field);

if(null != value){

this.setFieldValByName(field,value,metaObject);

}else {

this.setFieldValByName(field,defaultValue,metaObject);

}

}

}

private void setCreateTime(MetaObject metaObject){

setMeta(metaObject,CREATE_TIME,new Date());

}

private void setUpdateTime(MetaObject metaObject){

setMeta(metaObject,UPDATE_TIME,new Date());

}

private void setCreateBy(MetaObject metaObject){

Object createBy = metaObjectOperator.getCreateBy();

if(null == createBy){

return ;

}

setMeta(metaObject,CREATE_BY,createBy);

}

private void setUpdateBy(MetaObject metaObject){

Object updateBy = metaObjectOperator.getUpdateBy();

if(null == updateBy){

return ;

}

setMeta(metaObject,UPDATE_BY,updateBy);

}

private void setDelFlag(MetaObject metaObject){

setMeta(metaObject,DEL_FLAG,0);

}

@Override

public void insertFill(MetaObject metaObject) {

String name = metaObject.getOriginalObject().getClass().getName();

if(log.isDebugEnabled()){

log.debug("{} 自动装配 createTime、updateTime、createBy、updateBy、delFlag",name);

}

setCreateTime(metaObject);

setUpdateTime(metaObject);

setCreateBy(metaObject);

setUpdateBy(metaObject);

setDelFlag(metaObject);

}

@Override

public void updateFill(MetaObject metaObject) {

String name = metaObject.getOriginalObject().getClass().getName();

if(log.isDebugEnabled()){

log.debug("{} 自动装配 updateTime、updateBy",name);

}

setUpdateTime(metaObject);

setUpdateBy(metaObject);

}

}

数据库读写分离

在分布式纵横的年代,人们想方设法提高应用程序的性能,将数据库拆分为读写分离模式【主从复制】是一项提供性能的一种方案。

当然这种方案只针对对数据一致性没那么高要求的程序【弱一致性】。因为在主数据库同步给从数据库时候有可能会出现一些额外情况,如网络原因等,导致主从数据库数据不一致。

本案例采用动态数据源及mybatis-plus来实现读写分离

引入依赖

com.baomidou

mybatis-plus-boot-starter

3.3.2

org.projectlombok

lombok

1.18.12

com.baomidou

dynamic-datasource-spring-boot-starter

3.1.1

配置application.yml文件

配置名为master的主数据库【用于写操作】及名为slave的从数据库【读操作】

spring:

datasource:

dynamic:

druid: # 全局druid参数,绝大部分值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)

# 连接池的配置信息

# 初始化大小,最小,最大

initial-size: 5

min-idle: 5

maxActive: 20

# 配置获取连接等待超时的时间

maxWait: 60000

# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒

timeBetweenEvictionRunsMillis: 60000

# 配置一个连接在池中最小生存的时间,单位是毫秒

minEvictableIdleTimeMillis: 300000

validationQuery: SELECT 1 FROM DUAL

testWhileIdle: true

testOnBorrow: false

testOnReturn: false

# 打开PSCache,并且指定每个连接上PSCache的大小

poolPreparedStatements: true

maxPoolPreparedStatementPerConnectionSize: 20

# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙

filters: stat,wall,slf4j

# 通过connectProperties属性来打开mergeSql功能;慢SQL记录

connectionProperties: druid.stat.mergeSql\=true;druid.stat.slowSqlMillis\=5000

datasource:

master:

url: ${MYSQL_URL:jdbc:mysql://localhost:3306/master?characterEncoding=UTF-8&useUnicode=true&useSSL=false}

username: ${MYSQL_USER:root}

password: ${MYSQL_PASS:123456}

driver-class-name: com.mysql.cj.jdbc.Driver

slave:

url: ${MYSQL_URL:jdbc:mysql://localhost:3306/slave?characterEncoding=UTF-8&useUnicode=true&useSSL=false}

username: ${MYSQL_USER:root}

password: ${MYSQL_PASS:123456}

driver-class-name: com.mysql.cj.jdbc.Driver

程序使用读写分离

显式使用

只需在对应的方法上加上@DS注解并指明对应的数据源即可

package com.cloud.pango.uc.service.impl;

import com.baomidou.dynamic.datasource.annotation.DS;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import com.cloud.pango.uc.demo.DemoEntity;

import com.cloud.pango.uc.mapper.DemoMapper;

import com.cloud.pango.uc.service.DemoService;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

@Service

public class DemoServiceImpl extends ServiceImpl implements DemoService {

@DS("master")//标明使用master数据源

@Override

public Boolean insert(DemoEntity demo) {

save(demo);

return true;

}

@DS("slave")//标明使用slave数据源

@Override

public DemoEntity findById(String id){

DemoEntity demo = getById(id);

return demo;

}

}

隐式使用

在未使用注解时,使用mybatis-plus拦截器,将读请求转移到slave数据源处理,将写请求转移到master数据源处理

package com.cloud.pango.uc.common;

import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;

import lombok.extern.slf4j.Slf4j;

import org.apache.commons.lang3.StringUtils;

import org.apache.ibatis.executor.Executor;

import org.apache.ibatis.mapping.MappedStatement;

import org.apache.ibatis.mapping.SqlCommandType;

import org.apache.ibatis.plugin.*;

import org.apache.ibatis.session.ResultHandler;

import org.apache.ibatis.session.RowBounds;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Properties;

@Intercepts({

@Signature(type = Executor.class, method = "update", args = {

MappedStatement.class, Object.class }),

@Signature(type = Executor.class, method = "query", args = {

MappedStatement.class, Object.class, RowBounds.class,

ResultHandler.class }) })

@Slf4j

@Component

public class DynamicInterceptor implements Interceptor {

private static final String MASTER = "master";

private static final String SLAVE = "slave";

@Override

public Object intercept(Invocation invocation) throws Throwable {

boolean synchronizationActive = TransactionSynchronizationManager.isSynchronizationActive();

if(!synchronizationActive) {

Object[] objects = invocation.getArgs();

MappedStatement ms = (MappedStatement) objects[0];

String currentDataSource = DynamicDataSourceContextHolder.peek();

if(StringUtils.isEmpty(currentDataSource)){

if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)) {

DynamicDataSourceContextHolder.push(SLAVE);

}else{

DynamicDataSourceContextHolder.push(MASTER);

}

Object proceed = invocation.proceed();

DynamicDataSourceContextHolder.clear();

return proceed;

}

}

return invocation.proceed();

}

@Override

public Object plugin(Object target) {

if (target instanceof Executor) {

return Plugin.wrap(target, this);

} else {

return target;

}

}

@Override

public void setProperties(Properties properties) {

}

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/502683.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2020年周数和日期对应表_2020年雅思考试报名截止日期、准考证打印日期和成绩单寄送日期...

2020年雅思考试报名截止日期、准考证打印日期和成绩单寄送日期考试日期类别口试预定 开始日期*报名截止日期准考证 打印日期成绩单 寄送日期*04/01/2020A14/12/201916/12/201925/12/201917/01/202011/01/2020A+G21/12/201923/12/201901/01/202031/01/202016/01/2020…

飞行摇杆设置_HORI皇牌空战7最新飞行摇杆抢先开箱 设计出色布局合理

《皇牌空战7》即将于1月17日发售PS4/Xbox One版,2月1日发售PC版。近日,我们在本作发售之前收到了HORI为《皇牌空战7》量身设计制造的最新一代飞行摇杆。随着《皇牌空战7》即将到来,我们在此为大家做一个简单的先行开箱评测介绍,为…

2021计算机技术调剂,2021年华南师范大学计算机技术考研调剂信息

招生信息学校名称:华南师范大学学校省份:广东学校层次:211;一流学科;学院名称:专业名称:计算机技术专业代码:专业类型:None招生类别:None调剂招收人数:5专业及招生详情研…

latex subfigure_latex-图片插入

作为一个新手入门latex写作,在已有的期刊模板下,我认为不需要每个命令都知道它的参数。我们需要做的就是在最短的时间内完成论文,重点在内容上,而不是说我latex用的很棒。这里,我只给出我平时常用的两种作图方式&#…

为什么只有奇次谐波_治理变频器产生谐波的应用

变频器运行对电网所产生的高分量谐波电流极大的影响了电网质量,使同电网中的用电设备不能正常使用。根据相关的政策法规本文阐述了变频器产生谐波电流的几种治理方案优缺点,结合实际案例重点分析了有源滤波器(APF)在治理变频器产生…

1964年诞生的第一代电子计算机,世界第一台电子计算机诞生的年份是?

满意答案sxh1122014.01.21采纳率:57% 等级:12已帮助:8464人.第一台电子计算机阿塔纳索夫-贝瑞计算机(Atanasoff-Berry Computer,简称ABC)是世界上第一台电子计算机,为艾奥瓦州立大学的约翰文森特阿塔纳索夫(John Vi…

jsp项目开发案例_Laravel中使用swoole项目实战开发案例一 (建立swoole和前端通信)

Laravel中使用swoole项目实战开发案例二(后端主动分场景给界面推送消息)工欲善其事,必先利其器。在正式开发之前我们检查好需要安装的拓展,不要开发中发现这些问题,打断思路影响我们的开发效率。安装 swoole 拓展包安装 redis 拓展包安装 lar…

android 环形时间显示_使用Arduino构建OLED显示屏与Android手机接口的智能手表

背景知识视频教程Arduino 训练营:通过项目学习​viadean.com通过制作Arduino UNO FM收音机接收器学习Arduino I2C​viadean.com通过构建实际应用程序来掌握Arduino - 国外课栈​viadean.com我们大多数人都熟悉162点阵液晶显示器,它在许多项目中用于向用户…

计算机的安全设置在哪儿,电脑防火墙在哪里设置

随着微软系统的更新,现在的Windows 10系统对于网络防护非常的安全,但是有的朋友电脑需要测试一些软件,就需要关闭电脑的防火墙,但是不懂怎么设置电脑防火墙,不用担心下面就让小编教你电脑防火墙在哪设置吧。下面电脑防…

python的加减乘除运算_python实现四则运算

https://gitee.com/szh123/four_arithmetic_implementation.git 1.需求分析: 实现四则运算题目及答案生成,控制生成题目的个数,题目中数值不超过10且有分数存在并用真分数表示。 可以生成10000道题 运算符不超过3个 题目不能出现重复即不能经…

python的内置函数string_Python错误:内置函数或方法对象没有属性“StringIO”

我只想下载一张图片。然后上传到Amazon S3。但它不起作用。在builtin_function_or_method object has no attribute StringIOTraceback (most recent call last):File "flickrDump.py", line 16, in imgpath s3.upload_thumbnail(thumbnail_nametools.randomString(…

微众银行软件测试笔试题,微众银行4月8日笔试题目及部分代码

AC,大致思路就是算一下该字符串能组成的最大回文长度,然后按差值奇偶性输出胜利者,本来以为“最优策略”的删除任意一个字符会很复杂,但是试了下就过了。import java.util.Scanner;public class Main {public static void main(St…

python 多进程 多核_go/node/python 多进程与多核cpu

node node单线程,没有并发,但是可以利用cluster进行多cpu的利用。cluster是基于child_process的封装,帮你做了创建子进程,负载均衡,IPC的封装。 const cluster require(cluster); const http require(http); if (clu…

水晶底是什么材质_蓝宝石水晶镜面,贵是有道理的!

表友们在选择手表的时候,常常会在意机芯、性能等,但是你第一眼爱上的往往是它的外观。在手表上,有一样部件,你总是最先看到,占据着你视线的C位,但是你却总是忽略它。这个部分就是表镜,这个重要却…

str计算机中代表什么,STR到底是待机还是休眠

1。为什么需要待机、休眠尽管电脑硬件运行速度越来越快,但操作系统的体积也在不断膨胀,使得电脑开、关机时,启动、关闭的程序越来越多,花费时间也越来越漫长。因此如何让电脑能够快速启动、一开机就进入Windows,就成为…

科骏达导航端口测试软件,不用端口检测工具也可以知道机器端口,波特,分辨率...

该楼层疑似违规已被系统折叠 隐藏此楼查看此楼1. 富威: COM2/48002. 索菱、索莱特: COM3/96003. 凯振: COM2/96004. 路特仕、图音: COM2/96005. 卡仕达、科骏达: COM1/9600或COM6/48006. 欧华: COM2/96007.…

dedecms 漏洞_dedescan一款织梦漏洞扫描器

dedescan是一款可以扫描所有已公开的dedecms漏洞的扫描器。... ... ... ... ... ... …

post获取重定向的链接 python_欧美音乐网站Python爬虫项目实战

爬虫项目实战0x01 目标分析最近发现一个比较好的欧美音乐下载网站,可以下载大部分高质量欧美音乐。该爬虫项目要实现自动化批量获取用户想要下载的音乐。本文从网站分析、爬虫设计、代码实现三个方面出发,系统介绍该爬虫项目。项目完整代码在Github中可以…

中国志愿者服务器注册,如何注册成为志愿者?中国志愿服务网注册流程

西宁市团员、团干、青年志愿者个人和组织网上注册方式为“志愿汇”和“全国志愿服务信息系统(www.chinavolunteer.cn)”两个网站平台双线注册。志愿者注册流程基本操作指引一、PC电脑端操作注:本篇内容较多,建议先“收藏”文章或点击底部“在看”。1、PC…

iview 级联选择组件_iviewui级联选择 如何自定义?

export default {data () {return {value2: [jiangsu, suzhou, zhuozhengyuan],data: [{value: beijing,label: 北京,children: [{value: gugong,label: 故宫},{value: tiantan,label: 天坛},{value: wangfujing,label: 王府井}]}, {value: jiangsu,label: 江苏,children: [{va…