Implementation of mybatis Extraction Base Class BaseMapper Addition Deletion and Modification
- 2021-11-13 07:40:37
- OfStack
At present, the project uses mapper. xml files to operate the database, but each of them has added/deleted/changed/checked. In order to facilitate development, these common codes are extracted, not used as base classes, and each Mapper file is not written
Preparations:
1: Database tables
CREATE TABLE `t_permission` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT ' Authority ID',
`type` int(11) NOT NULL COMMENT ' Permission type ',
`name` varchar(255) NOT NULL COMMENT ' Permission name ',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=24 DEFAULT CHARSET=utf8 COMMENT=' Permission table ';
2: Prepare Entity Classes
public class TPermissionEntity {
@PrimaryKey // The following steps 2 Custom annotations in
private Integer id;// Authority ID
private Integer type;// Permission type
private String name;// Permission name
// Omitted get,set Method ....
}
Step 1: Write the tool class Tools: Used for conversion of hump and database fields
Because the name of the class is named by hump, it is necessary to convert 1 here
import java.util.regex.Matcher;
import java.util.regex.Pattern;
/*
* Conversion between hump name and underline name
*/
public class Tool {
private static Pattern linePattern = Pattern.compile("_(\\w)");
/** Underline to hump */
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]");
/** Hump turn underline , The efficiency is higher than above */
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();
}
}
Step 2: Customize two annotations for class field exclusion and literal primary key
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Exclude {
}
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface PrimaryKey {
String value() default "";
}
Step 3: Customize the dynamic sql generation class BaseSqlProvider < T >
Function: Dynamic sql statement is generated by dynamically obtaining table name and field name according to the passed-in object, and then executing
@ Insert, @ Select, @ update, @ Delete directly configure SQL statements, while @ InsertProvider, @ UpdateProvider, @ SelectProvider, @ DeleteProvider produce SQL statements through SQL factory classes and corresponding methods
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(" Object does not contain the PrimaryKey Attribute ");
}
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(" Object does not contain the PrimaryKey Attribute ");
}
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(" Object does not contain the PrimaryKey Attribute ");
}
System.out.println("updateSql:"+sql.toString());
return sql.toString();
}
}
Step 4: Write the BaseMapper base class interface
public interface BaseMapper<T> {
// Add 1 Bar data
@InsertProvider(method = "add",type=BaseSqlProvider.class)
@Options(useGeneratedKeys=true)
public int add(T bean);
// Delete by primary key 1 Bar data
@DeleteProvider(method = "delete",type=BaseSqlProvider.class)
public int delete(T bean);
// Obtain according to primary key 1 Bar data
@SelectProvider(method = "get",type=BaseSqlProvider.class)
public T get(T bean);
// Modify 1 Bar data
@UpdateProvider(method = "update",type=BaseSqlProvider.class)
public int update(T bean);
}
Explanation: type in the @ InsertProvider annotation indicates the custom SQL factory class, method is the corresponding method in the factory class, and the method returns the sql statement of the other party
At this point, the base class and its configuration are completed. Next, you can use
Examples:
Write an TPermissionMapper interface, implement BaseMapper class, and pass in a generic parameter, this TPermissionMapper interface has already had, BaseMapper basic add/delete/change/check function. At the same time, TPermissionMapper can also write its own unique method and mapper. xml file to expand the function
public interface TPermissionMapper extends BaseMapper<TPermissionEntity>{
//List<TPermissionEntity> queryByPage();
}
Application in controller:
@Controller
public class LoginController {
@Autowired
private TPermissionMapper tPermissionMapper;
// Add
@ResponseBody
@RequestMapping(value = "/add")
public Integer add() {
TPermissionEntity permissionEntiry = new TPermissionEntity();
permissionEntiry.setName("test");
permissionEntiry.setType(3);
Integer num = tPermissionMapper.add(permissionEntiry);
return num;
}
// Modify
@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;
}
// Query
@ResponseBody
@RequestMapping(value = "/query")
public TPermissionEntity query() {
TPermissionEntity tPermissionEntity = new TPermissionEntity();
tPermissionEntity.setId(23);
tPermissionEntity= (TPermissionEntity) tPermissionMapper.get(tPermissionEntity);
return tPermissionEntity;
}
// Delete
@ResponseBody
@RequestMapping(value = "/delete")
public Integer delete() {
TPermissionEntity permissionEntiry = new TPermissionEntity();
permissionEntiry.setId(22);
Integer num = tPermissionMapper.delete(permissionEntiry);
return num;
}
}