python h5网站开发,python语言基础,国内最新军事新闻,wordpress 提速插件目录 一、Mybatis插件简介#x1f959;二、工程创建及前期准备工作#x1f96b;实现代码配置文件 三、插件核心代码实现#x1f357;四、测试#x1f953; 一、Mybatis插件简介#x1f959;
Mybatis插件运行原理及自定义插件_简述mybatis的插件运行原理,以及如何编写一个… 目录 一、Mybatis插件简介二、工程创建及前期准备工作实现代码配置文件 三、插件核心代码实现四、测试 一、Mybatis插件简介
Mybatis插件运行原理及自定义插件_简述mybatis的插件运行原理,以及如何编写一个插件-CSDN博客
MyBatis 是一款优秀的持久层框架它简化了数据库操作过程提供了强大的 SQL 映射功能。MyBatis 插件是用来扩展 MyBatis 框架功能的工具可以通过插件来定制和增强 MyBatis 的功能。
MyBatis 插件可以用来实现一些自定义的功能比如拦截 SQL 语句、修改 SQL 语句、添加新的功能等。通过插件我们可以在 MyBatis 框架的各个阶段进行干预和扩展从而实现更灵活、更强大的功能。
通常情况下编写一个 MyBatis 插件需要实现 MyBatis 提供的接口并在配置文件中注册插件。Mybatis只支持针对ParameterHandler、ResultSetHandler、StatementHandler、Executor这4种接口
总的来说MyBatis 插件是一种扩展机制可以让我们更好地定制和增强 MyBatis 框架的功能使得我们能够更好地适应各种不同的业务需求。
二、工程创建及前期准备工作
以下都为前期准备工作可直接略过插件核心实现代码在第三节 创建test数据库
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS 0;
DROP TABLE IF EXISTS user;
CREATE TABLE user (id int NOT NULL AUTO_INCREMENT,username varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,password varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,create_time datetime NULL DEFAULT NULL,update_time datetime NULL DEFAULT NULL,PRIMARY KEY (id) USING BTREE
) ENGINE InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci ROW_FORMAT Dynamic;SET FOREIGN_KEY_CHECKS 1;
实现代码
本实验省略了Controller和Service
User.java
package com.example.mybatisplugin.entity;import com.example.mybatisplugin.anno.FiledFill;import java.io.Serial;
import java.time.LocalDateTime;
import java.util.Date;
import java.io.Serializable;/*** (User)实体类** author makejava* since 2024-03-11 14:41:35*/
public class User implements Serializable {Serialprivate static final long serialVersionUID 813676794892349198L;private Integer id;private String username;private String password;FiledFill(fill FiledFill.FillType.INSERT)private Date createTime;FiledFill(fill FiledFill.FillType.INSERT_UPDATE)private Date updateTime;//省略了getter和setter方法Overridepublic String toString() {return User{ id id , username username \ , password password \ , createTime createTime , updateTime updateTime };}
}
其中FiledFill注解是自定义注解文章后面会写到可暂时不用添加
UserDao.java
Mapper
public interface UserDao {/*** 新增数据** param user 实例对象* return 影响行数*/int insert(User user);/*** 修改数据** param user 实例对象* return 影响行数*/int update(User user);}UserDao.xml
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.mybatisplugin.dao.UserDaoresultMap typecom.example.mybatisplugin.entity.User idUserMapresult propertyid columnid jdbcTypeINTEGER/result propertyusername columnusername jdbcTypeVARCHAR/result propertypassword columnpassword jdbcTypeVARCHAR/result propertycreateTime columncreate_time jdbcTypeTIMESTAMP/result propertyupdateTime columnupdate_time jdbcTypeTIMESTAMP//resultMap!--新增所有列--insert idinsert keyPropertyid useGeneratedKeystrueinsert into user(username,password,create_time,update_time)values (#{username},#{password},#{createTime},#{updateTime})/insert!--通过主键修改数据--update idupdateupdate usersetif testusername ! null and username ! username #{username},/ifif testpassword ! null and password ! password #{password},/ifif testcreateTime ! nullcreate_time #{createTime},/ifif testupdateTime ! nullupdate_time #{updateTime},/if/setwhere id #{id}/update
/mapper配置文件
application.yaml 数据库密码记得改成自己的
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: *****url: jdbc:mysql://localhost:3306/test?useUnicodetruecharacterEncodingUTF-8useSSLfalseserverTimezoneAsia/Shanghai
server:port: 8080
mybatis:config-location: classpath:mybatis-config.xmlmapper-locations: classpath:mapper/*.xmlmybatis-config.xml
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configuration PUBLIC-//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!-- 设置驼峰标识 --setting namemapUnderscoreToCamelCase valuetrue/!-- 打印SQL语句 --setting namelogImpl valueSTDOUT_LOGGING//settings
/configuration三、插件核心代码实现
自定义注解FiledFill
package com.example.mybatisplugin.anno;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;/*** Author YZK* Date 2024/3/11*/
Target(ElementType.FIELD)
Retention(RetentionPolicy.RUNTIME)
public interface FiledFill {enum FillType {INSERT, INSERT_UPDATE,}FillType fill();
}插件核心代码
package com.example.mybatisplugin.plugin;import com.example.mybatisplugin.anno.FiledFill;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Signature;import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;/*** Author YZK* Date 2024/3/11* Desc*/
Intercepts({Signature(type Executor.class,method update,args {MappedStatement.class, Object.class})})
public class MybatisAutoFill implements Interceptor {private static final Logger LOGGER Logger.getLogger(MybatisAutoFill.class.getName());public Object intercept(Invocation invocation) throws Throwable {MappedStatement mappedStatement (MappedStatement) invocation.getArgs()[0];//获取操作类型INSERT和UPDATESqlCommandType sqlCommandType mappedStatement.getSqlCommandType();//拿到SQL中传入的对象Object obj invocation.getArgs()[1];//获取其字节对象Class? clazz obj.getClass();//获取User类声明的所有字段Field[] fields clazz.getDeclaredFields();//通过区分SQL的操作来进行不同的字段填充if (sqlCommandType SqlCommandType.INSERT) {//是INSERT操作的话就同时填充createTime和updateTime字段fillInsertFields(obj, fields);} else if (sqlCommandType SqlCommandType.UPDATE) {//是updateTime字段的话就只填充updateTime字段fillUpdateFields(obj, fields);}return invocation.proceed();}private void fillInsertFields(Object obj, Field[] fields) {Arrays.stream(fields)//过滤出所有带有FiledFill注解的字段.filter(field - field.isAnnotationPresent(FiledFill.class)).forEach(field - {try {//对字段进行填充setFieldValue(obj, field);} catch (IllegalAccessException e) {LOGGER.log(Level.SEVERE, 字段填充错误, e);}});}private void fillUpdateFields(Object obj, Field[] fields) {Arrays.stream(fields)//过滤出所有带有FiledFill注解的字段以及注解值为INSERT_UPDATE的字段.filter(field - field.isAnnotationPresent(FiledFill.class) field.getAnnotation(FiledFill.class).fill() FiledFill.FillType.INSERT_UPDATE).forEach(field - {try {//对字段进行填充setFieldValue(obj, field);} catch (IllegalAccessException e) {LOGGER.log(Level.SEVERE, 字段填充错误, e);}});}private void setFieldValue(Object obj, Field field) throws IllegalAccessException {//填充字段field.setAccessible(true);field.set(obj, new Date());}
}mybatis-condig.xml配置文件中进行配置将自定义的插件注册
?xml version1.0 encodingUTF-8 ?
!DOCTYPE configuration PUBLIC-//mybatis.org//DTD Config 3.0//ENhttp://mybatis.org/dtd/mybatis-3-config.dtd
configurationsettings!-- 设置驼峰标识 --setting namemapUnderscoreToCamelCase valuetrue/!-- 打印SQL语句 --setting namelogImpl valueSTDOUT_LOGGING//settingspluginsplugin interceptorcom.example.mybatisplugin.plugin.MybatisAutoFill//plugins
/configuration
四、测试 插入操作 Test
void contextLoads() {User user new User();user.setUsername(笑的像个child);user.setPassword(123456);userDao.insert(user);
}控制台打印的SQL 进行插入操作时create_time和update_time字段被同时填充 更新操作 Testvoid contextLoads() {User user new User();user.setId(33);user.setUsername(笑的像个child);user.setPassword(12345678);userDao.update(user);}控制台打印的SQL 进行更新时操作时update_time字段被填充
进行删除操作时如果是硬删除则记录被删除软删除时同样是更新操作字段也会被自动填充。
本插件还有许多需要完善的地方只是自动填充的简单实现如有需要可以自己完善。