mybatis抽取基類BaseMapper增刪改查的實(shí)現(xiàn)
目前項(xiàng)目當(dāng)中使用mapper.xml文件方式對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作,但是每個(gè)里邊都有增/刪/改/查,為了方便開發(fā),把這些公共的代碼提取出來,不用當(dāng)做基類,不用每個(gè)Mapper文件都寫了
準(zhǔn)備工作:
1:數(shù)據(jù)庫(kù)表
CREATE TABLE `t_permission` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '權(quán)限ID', `type` int(11) NOT NULL COMMENT '權(quán)限類型', `name` varchar(255) NOT NULL COMMENT '權(quán)限名稱', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT='權(quán)限表';
2:準(zhǔn)備實(shí)體類
public class TPermissionEntity { @PrimaryKey //下面步驟2中自定義注解 private Integer id;//權(quán)限ID private Integer type;//權(quán)限類型 private String name;//權(quán)限名稱 //省略了get,set方法.... }
步驟1:編寫工具類Tools:作用:用于駝峰和數(shù)據(jù)庫(kù)字段的轉(zhuǎn)換
因?yàn)轭惖拿Q用的是駝峰命名,所以這里需要轉(zhuǎn)換一下
import java.util.regex.Matcher; import java.util.regex.Pattern; /* * 駝峰名稱和下劃線名稱的相互轉(zhuǎn)換 */ public class Tool { private static Pattern linePattern = Pattern.compile("_(\\w)"); /** 下劃線轉(zhuǎn)駝峰 */ 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]"); /** 駝峰轉(zhuǎn)下劃線,效率比上面高 */ 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:自定義兩個(gè)注解,分別用于類字段的排除和字義主鍵
@Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface Exclude { } @Target({ElementType.FIELD}) @Retention(RetentionPolicy.RUNTIME) public @interface PrimaryKey { String value() default ""; }
步驟3:自定義動(dòng)態(tài)sql生成類BaseSqlProvider<T>
作用:根據(jù)傳入的對(duì)象動(dòng)態(tài)獲取表名和字段名生成動(dòng)態(tài)的sql語句,再執(zhí)行
@Insert,@Select,@update,@Delete是直接配置SQL語句,而@InsertProvider,@UpdateProvider,@SelectProvider,@DeleteProvider則是通過SQL工廠類及對(duì)應(yīng)的方法生產(chǎn)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("對(duì)象中未包含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("對(duì)象中未包含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("對(duì)象中未包含PrimaryKey屬性"); } System.out.println("updateSql:"+sql.toString()); return sql.toString(); } }
步驟4:編寫B(tài)aseMapper基類接口
public interface BaseMapper<T> { //新增一條數(shù)據(jù) @InsertProvider(method = "add",type=BaseSqlProvider.class) @Options(useGeneratedKeys=true) public int add(T bean); //根據(jù)主鍵刪除一條數(shù)據(jù) @DeleteProvider(method = "delete",type=BaseSqlProvider.class) public int delete(T bean); //根據(jù)主鍵獲取一條數(shù)據(jù) @SelectProvider(method = "get",type=BaseSqlProvider.class) public T get(T bean); //修改一條數(shù)據(jù) @UpdateProvider(method = "update",type=BaseSqlProvider.class) public int update(T bean); }
說明:@InsertProvider注解中的type指明自定義的SQL工廠類,method是工廠類里對(duì)應(yīng)的方法,方法返回的是對(duì)方的sql語句
到這里基類以及它的配置就完成了,接下來,可以使用了
舉例:
編寫一個(gè)TPermissionMapper接口,實(shí)現(xiàn)BaseMapper類,并傳入一個(gè)泛型參數(shù),此時(shí)這個(gè)TPermissionMapper接口已經(jīng)具備了,BaseMapper中基本的增/刪/改/查功能.同時(shí)TPermissionMapper還可以再寫自己獨(dú)有的方法和mapper.xml文件對(duì)功能進(jìn)行擴(kuò)展
public interface TPermissionMapper extends BaseMapper<TPermissionEntity>{ //List<TPermissionEntity> queryByPage(); }
在controller當(dāng)中的應(yīng)用:
@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; } }
到此這篇關(guān)于mybatis抽取基類BaseMapper增刪改查的實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)mybatis BaseMapper增刪改查內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Mybatis-Plus接口BaseMapper與Services使用詳解
- MybatisPlus?BaseMapper?實(shí)現(xiàn)對(duì)數(shù)據(jù)庫(kù)增刪改查源碼
- Mapper層繼承BaseMapper<T>需要引入的pom依賴方式
- 淺談Mybatis Plus的BaseMapper的方法是如何注入的
- mybatis-plus中BaseMapper入門使用
- MybatisPlus BaseMapper 中的方法全部 Invalid bound statement (not found Error處理)
- Mybatis-Plus BaseMapper的用法詳解
- BaseMapper接口的使用方法
相關(guān)文章
基于SpringBoot實(shí)現(xiàn)動(dòng)態(tài)配置數(shù)據(jù)庫(kù)的加載
這篇文章主要介紹了Spring?Boot?如何動(dòng)態(tài)配置數(shù)據(jù)庫(kù)的加載,現(xiàn)項(xiàng)目有一個(gè)需求,期望通過在application.yml配置文件中設(shè)置一個(gè)開關(guān),來決定是否加載數(shù)據(jù)庫(kù),文中通過代碼示例講解的非常詳細(xì),需要的朋友可以參考下2024-10-10MyBatis如何實(shí)現(xiàn)多表查詢(多對(duì)一、一對(duì)多)
這篇文章主要給大家介紹了關(guān)于MyBatis如何實(shí)現(xiàn)多表查詢(多對(duì)一、一對(duì)多)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-05-05詳解SpringBoot上傳圖片到阿里云的OSS對(duì)象存儲(chǔ)中
這篇文章主要介紹了SpringBoot上傳圖片到阿里云的OSS對(duì)象存儲(chǔ)中,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10Spring Boot 配置 Quartz 定時(shí)任務(wù)的方法
這篇文章主要介紹了Spring Boot 配置 Quartz 定時(shí)任務(wù)的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-09-09Java語言中flush()函數(shù)作用及使用方法詳解
這篇文章主要介紹了Java語言中flush函數(shù)作用及使用方法詳解,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-01-01