mybatis抽取基类BaseMapper增删改查的实现

 更新时间:2021年09月15日 10:39:42   作者:YingTao8  
目前项目当中使用mapper.xml文件方式对数据库进行操作,但是每个里边都有增/删/改/查,为了方便开发,把这些公共的代码提取出来,不用当做基类,不用每个Mapper文件都写了,本文就详细的介绍一下实现方法

目前项目当中使用mapper.xml文件方式对数据库进行操作,但是每个里边都有增/删/改/查,为了方便开发,把这些公共的代码提取出来,不用当做基类,不用每个Mapper文件都写了

准备工作:

1:数据库表

CREATE TABLE `t_permission` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '权限ID',
  `type` int(11) NOT NULL COMMENT '权限类型',
  `name` varchar(255) NOT NULL COMMENT '权限名称',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT='权限表';

2:准备实体类

public class TPermissionEntity {
 
 @PrimaryKey //下面步骤2中自定义注解
 private Integer id;//权限ID
 
 private Integer type;//权限类型
 private String name;//权限名称
 
 //省略了get,set方法....
 
}

步骤1:编写工具类Tools:作用:用于驼峰和数据库字段的转换

因为类的名称用的是驼峰命名,所以这里需要转换一下

import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* 驼峰名称和下划线名称的相互转换
*/
public class Tool {
 
 private static Pattern linePattern = Pattern.compile("_(\\w)");
 /** 下划线转驼峰 */
 public static String lineToHump(String str) {
  str = str.toLowerCase();
  Matcher matcher = linePattern.matcher(str);
  StringBuffer sb = new StringBuffer();
  while (matcher.find()) {
   matcher.appendReplacement(sb, matcher.group(1).toUpperCase());
  }
  matcher.appendTail(sb);
  return sb.toString();
 }
 
 private static Pattern humpPattern = Pattern.compile("[A-Z]");
 /** 驼峰转下划线,效率比上面高 */
 public static String humpToLine(String str) {
  Matcher matcher = humpPattern.matcher(str);
  StringBuffer sb = new StringBuffer();
  while (matcher.find()) {
   matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase());
  }
  matcher.appendTail(sb);
  return sb.toString();
 }
 
}

步骤2:自定义两个注解,分别用于类字段的排除和字义主键

@Target({ElementType.FIELD})  
@Retention(RetentionPolicy.RUNTIME) 
public @interface Exclude {
 
}
@Target({ElementType.FIELD})  
@Retention(RetentionPolicy.RUNTIME)  
public @interface PrimaryKey {  
    String value() default "";  
} 

步骤3:自定义动态sql生成类BaseSqlProvider<T>

作用:根据传入的对象动态获取表名和字段名生成动态的sql语句,再执行

@Insert,@Select,@update,@Delete是直接配置SQL语句,而@InsertProvider,@UpdateProvider,@SelectProvider,@DeleteProvider则是通过SQL工厂类及对应的方法生产SQL语句

import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.jdbc.SQL;
import com.example.demo.common.utils.Tool;
 
public class BaseSqlProvider<T> {
 
 @Options
 public String add(T bean) {
 
  SQL sql = new SQL();
 
  Class clazz = bean.getClass();
 
  String tableName = clazz.getSimpleName();
  
  String realTableName = Tool.humpToLine(tableName).replaceAll("_entity", "").substring(1);
  sql.INSERT_INTO(realTableName);
 
  List<Field> fields = getFields(clazz);
  for (Field field : fields) {
 
   field.setAccessible(true);
 
   String column = field.getName();
 
   System.out.println("column:" + Tool.humpToLine(column));
 
   sql.VALUES(Tool.humpToLine(column), String.format("#{" + column + ",jdbcType=VARCHAR}"));
 
  }
 
  return sql.toString();
 }
 
 public String delete(T bean) {
 
  SQL sql = new SQL();
 
  Class clazz = bean.getClass();
 
  String tableName = clazz.getSimpleName();
 
  String realTableName = Tool.humpToLine(tableName).replaceAll("_entity", "").substring(1);
  sql.DELETE_FROM(realTableName);
 
  List<Field> primaryKeyField = getPrimarkKeyFields(clazz);
 
  if (!primaryKeyField.isEmpty()) {
 
   for (Field pkField : primaryKeyField) {
    pkField.setAccessible(true);
    sql.WHERE(pkField.getName() + "=" + String.format("#{" + pkField.getName() + "}"));
   }
 
  } else {
 
   sql.WHERE(" 1= 2");
 
   throw new RuntimeException("对象中未包含PrimaryKey属性");
  }
 
  return sql.toString();
 }
 
 private List<Field> getPrimarkKeyFields(Class clazz) {
 
  List<Field> primaryKeyField = new ArrayList<>();
  List<Field> fields = getFields(clazz);
  for (Field field : fields) {
   field.setAccessible(true);
   PrimaryKey key = field.getAnnotation(PrimaryKey.class);
   if (key != null) {
    primaryKeyField.add(field);
   }
 
  }
  return primaryKeyField;
 }
 
 private List<Field> getFields(Class clazz) {
 
  List<Field> fieldList = new ArrayList<>();
  Field[] fields = clazz.getDeclaredFields();
  for (Field field : fields) {
   field.setAccessible(true);
   Exclude key = field.getAnnotation(Exclude.class);
   if (key == null) {
    fieldList.add(field);
   }
 
  }
  return fieldList;
 }
 
 public String get(T bean) {
 
  SQL sql = new SQL();
 
  Class clazz = bean.getClass();
 
  String tableName = clazz.getSimpleName();
 
  String realTableName = Tool.humpToLine(tableName).replaceAll("_entity", "").substring(1);
  sql.SELECT("*").FROM(realTableName);
 
  List<Field> primaryKeyField = getPrimarkKeyFields(clazz);
 
  if (!primaryKeyField.isEmpty()) {
 
   for (Field pkField : primaryKeyField) {
    pkField.setAccessible(true);
    sql.WHERE(pkField.getName() + "=" + String.format("#{" + pkField.getName() + "}"));
    
   }
  } else {
 
   sql.WHERE(" 1= 2");
 
   throw new RuntimeException("对象中未包含PrimaryKey属性");
  }
  System.out.println("getSql:"+sql.toString());
  return sql.toString();
 }
 
 public String update(T bean) {
 
  SQL sql = new SQL();
 
  Class clazz = bean.getClass();
 
  String tableName = clazz.getSimpleName();
 
  String realTableName = Tool.humpToLine(tableName).replaceAll("_entity", "").substring(1);
  sql.UPDATE(realTableName);
 
  List<Field> fields = getFields(clazz);
  for (Field field : fields) {
 
   field.setAccessible(true);
 
   String column = field.getName();
 
   if (column.equals("id")) {
    continue;
   }
 
   System.out.println(Tool.humpToLine(column));
 
   sql.SET(Tool.humpToLine(column) + "=" + String.format("#{" + column + ",jdbcType=VARCHAR}"));
  }
 
  List<Field> primaryKeyField = getPrimarkKeyFields(clazz);
 
  if (!primaryKeyField.isEmpty()) {
 
   for (Field pkField : primaryKeyField) {
    pkField.setAccessible(true);
    sql.WHERE(pkField.getName() + "=" + String.format("#{" + pkField.getName() + "}"));
   }
 
  } else {
 
   sql.WHERE(" 1= 2");
 
   throw new RuntimeException("对象中未包含PrimaryKey属性");
  }
  System.out.println("updateSql:"+sql.toString());
  return sql.toString();
 
 } 
}

步骤4:编写BaseMapper基类接口

public interface BaseMapper<T> {
 
        //新增一条数据
 @InsertProvider(method = "add",type=BaseSqlProvider.class)
 @Options(useGeneratedKeys=true)
 public int add(T bean);
 
        //根据主键删除一条数据
 @DeleteProvider(method = "delete",type=BaseSqlProvider.class)
 public int delete(T bean);
 
        //根据主键获取一条数据
 @SelectProvider(method = "get",type=BaseSqlProvider.class)
 public T get(T bean);
 
        //修改一条数据
 @UpdateProvider(method = "update",type=BaseSqlProvider.class)
 public int update(T bean);
 
}

说明:@InsertProvider注解中的type指明自定义的SQL工厂类,method是工厂类里对应的方法,方法返回的是对方的sql语句

到这里基类以及它的配置就完成了,接下来,可以使用了

举例:

编写一个TPermissionMapper接口,实现BaseMapper类,并传入一个泛型参数,此时这个TPermissionMapper接口已经具备了,BaseMapper中基本的增/删/改/查功能.同时TPermissionMapper还可以再写自己独有的方法和mapper.xml文件对功能进行扩展

public interface TPermissionMapper extends BaseMapper<TPermissionEntity>{
 
 //List<TPermissionEntity> queryByPage();
 
}

在controller当中的应用:

@Controller
public class LoginController {
 
 @Autowired
 private TPermissionMapper tPermissionMapper;
 
        //新增
 @ResponseBody
 @RequestMapping(value = "/add")
 public Integer add() {
  TPermissionEntity permissionEntiry = new TPermissionEntity();
  permissionEntiry.setName("test");
  permissionEntiry.setType(3);
  Integer num = tPermissionMapper.add(permissionEntiry);
  return num;
 }
 
        //修改
 @ResponseBody
 @RequestMapping(value = "/update")
 public Integer update() {
  TPermissionEntity permissionEntiry = new TPermissionEntity();
  permissionEntiry.setId(23);
  permissionEntiry.setName("test");
  permissionEntiry.setType(3);
  Integer num = tPermissionMapper.update(permissionEntiry);
  return num;
 }
 
        //查询
 @ResponseBody
 @RequestMapping(value = "/query")
 public TPermissionEntity query() {
  TPermissionEntity tPermissionEntity = new TPermissionEntity();
  tPermissionEntity.setId(23);
  tPermissionEntity= (TPermissionEntity) tPermissionMapper.get(tPermissionEntity);
  return tPermissionEntity;
 }
 
        //删除
 @ResponseBody
 @RequestMapping(value = "/delete")
 public Integer delete() {
  TPermissionEntity permissionEntiry = new TPermissionEntity();
  permissionEntiry.setId(22);
  Integer num = tPermissionMapper.delete(permissionEntiry);
  return num;
 }
}

到此这篇关于mybatis抽取基类BaseMapper增删改查的实现的文章就介绍到这了,更多相关mybatis BaseMapper增删改查内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 基于SpringBoot实现动态配置数据库的加载

    基于SpringBoot实现动态配置数据库的加载

    这篇文章主要介绍了Spring Boot 如何动态配置数据库的加载,现项目有一个需求,期望通过在application.yml配置文件中设置一个开关,来决定是否加载数据库,文中通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-10-10
  • MyBatis如何实现多表查询(多对一、一对多)

    MyBatis如何实现多表查询(多对一、一对多)

    这篇文章主要给大家介绍了关于MyBatis如何实现多表查询(多对一、一对多)的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-05-05
  • 详解SpringBoot上传图片到阿里云的OSS对象存储中

    详解SpringBoot上传图片到阿里云的OSS对象存储中

    这篇文章主要介绍了SpringBoot上传图片到阿里云的OSS对象存储中,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2020-10-10
  • maven配置文件pom增加变量取版本号方式

    maven配置文件pom增加变量取版本号方式

    这篇文章主要介绍了maven配置文件pom增加变量取版本号方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-12-12
  • 详解JAVA 常量池

    详解JAVA 常量池

    这篇文章主要介绍了JAVA 常量池的相关资料,文中讲解非常详细,示例代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下
    2020-07-07
  • Spring Boot 配置 Quartz 定时任务的方法

    Spring Boot 配置 Quartz 定时任务的方法

    这篇文章主要介绍了Spring Boot 配置 Quartz 定时任务的方法,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-09-09
  • Java语言中flush()函数作用及使用方法详解

    Java语言中flush()函数作用及使用方法详解

    这篇文章主要介绍了Java语言中flush函数作用及使用方法详解,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • 利用Java手写阻塞队列的示例代码

    利用Java手写阻塞队列的示例代码

    在我们平时编程的时候一个很重要的工具就是容器,在本篇文章当中主要给大家介绍阻塞队列的原理,并且在了解原理之后自己动手实现一个低配版的阻塞队列,感兴趣的可以尝试一下
    2022-08-08
  • Java 8 新特性终极版指南详解

    Java 8 新特性终极版指南详解

    Java 8已经公布有一段时间了,种种迹象表明Java 8是一个有重大改变的发行版。本文给大家介绍Java 8 新特性终极版指南详解,需要的朋友参考下
    2016-03-03
  • Java使用Graphics2D绘制SVG和PNG的方法

    Java使用Graphics2D绘制SVG和PNG的方法

    Java提供了许多图形处理类和方法,如Graphics2D、AffineTransform、Stroke等,这些都可以用于绘制SVG图像,Graphics2D是Java中用于绘制2D图形的类,本文给大家介绍如何使用Graphics2D绘制SVG和PNG,需要的朋友可以参考下
    2023-06-06

最新评论