背景:由于在项目中是需要使用联合主键,但是mp本身对联合主键支持非常不友好,现开发一个联合主键
(1)注解定义
在需要使用的实体上加上@MutiId,其中ids表示联合主键的数组
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE, ElementType.ANNOTATION_TYPE})
public @interface MultiId {
String[] ids() default {};
}
(2)查询的时候有联合主键
T getByMutId(@Param("ids") Serializable... ids);
public class SelectByMultiId extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlCustomMethod selectByMultiId = SqlCustomMethod.SELECT_BY_MULTI_ID;
String con = getCon(modelClass);
if (!con.equals("")) {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(selectByMultiId.getSql(),
sqlSelectColumns(tableInfo, false),
tableInfo.getTableName(), con,
tableInfo.getLogicDeleteSql(true, true)), Object.class);
return this.addSelectMappedStatementForTable(mapperClass, selectByMultiId.getMethod(), sqlSource, tableInfo);
}
return null;
}
private String getCon(Class<?> modelClass) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(modelClass);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i)).append(" = #{ids[").append(i).append("]}");
if (i != size - 1) {
keySqlBuilder.append(" and ");
}
}
}
return keySqlBuilder.toString();
}
?
/**
* @param entity 实体类,实际上只会用到里面的主键
* @return 数据库对应的实体
*/
T getByEntityMultiId(T entity);
public class SelectByEntityMultiId extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlCustomMethod selectByEntityMultiId = SqlCustomMethod.SELECT_BY_ENTITY_MULTI_ID;
String con = getCon(modelClass);
if (!con.equals("")) {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(selectByEntityMultiId.getSql(),
sqlSelectColumns(tableInfo, false),
tableInfo.getTableName(), con,
tableInfo.getLogicDeleteSql(true, true)), modelClass);
return this.addSelectMappedStatementForTable(mapperClass, selectByEntityMultiId.getMethod(), sqlSource, tableInfo);
}
return null;
}
private String getCon(Class<?> modelClass) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(modelClass);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
List<String> proList = multiInfo.getProList();
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i)).append(" = #{").append(proList.get(i)).append("}");
if (i != size - 1) {
keySqlBuilder.append(" and ");
}
}
}
return keySqlBuilder.toString();
}
}
(3)删除
public class DeleteByMutId extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlCustomMethod deleteByMultiId = SqlCustomMethod.DELETE_BY_MULTI_ID;
String con = getCon(modelClass);
if (!con.equals("")) {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(deleteByMultiId.getSql(),
tableInfo.getTableName(), con), Object.class);
return this.addSelectMappedStatementForTable(mapperClass, deleteByMultiId.getMethod(), sqlSource, tableInfo);
}
return null;
}
private String getCon(Class<?> modelClass) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(modelClass);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i)).append(" = #{ids[").append(i).append("]}");
if (i != size - 1) {
keySqlBuilder.append(" and ");
}
}
}
return keySqlBuilder.toString();
}
}
(4)更新
public class UpdateByMulId extends AbstractMethod {
@Override
public MappedStatement injectMappedStatement(Class<?> mapperClass, Class<?> modelClass, TableInfo tableInfo) {
SqlCustomMethod updateByMulId = SqlCustomMethod.UPDATE_BY_MUL_ID;
String con = getCon(modelClass);
if (!con.equals("")) {
SqlSource sqlSource = languageDriver.createSqlSource(configuration, String.format(updateByMulId.getSql(),
tableInfo.getTableName(),
sqlSet(tableInfo.isWithLogicDelete(), false, tableInfo, false, null, null),
con), Object.class);
return this.addSelectMappedStatementForTable(mapperClass, updateByMulId.getMethod(), sqlSource, tableInfo);
}
return null;
}
private String getCon(Class<?> modelClass) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(modelClass);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
List<String> proList = multiInfo.getProList();
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i)).append(" = #{").append(proList.get(i)).append("}");
if (i != size - 1) {
keySqlBuilder.append(" and ");
}
}
}
return keySqlBuilder.toString();
}
}
(5)
public enum SqlCustomMethod {
/**
* 删除
*/
DELETE_BY_ENTITY_MULTI_ID("deleteByEntityMultiId", "根据主键删除数据,主键从实体类获取", "<script>\nDELETE FROM %s WHERE %s\n</script>"),
DELETE_BY_MULTI_ID("deleteByMutId", "联合主键删除", "<script>\nDELETE FROM %s WHERE %s\n</script>"),
/**
* 新增
*/
INSERT_BATCH("insertBatch", "批量插入", "<script>\ninsert into %s %s values %s\n</script>"),
/**
* 新增或者更新
*/
SAVE_OR_UPDATE("saveOrUpdate", "自动识别是更新还是插入", "<script>\ninsert into %s %s values %s on conflict%s do update set %s\n</script>"),
/**
* 更新
*/
UPDATE_BATCH("updateBatch", "批量更新", "<script>\n<foreach collection=\"list\" item=\"item\" separator=\";\">\nupdate %s %s where %s %s\n</foreach>\n</script>"),
UPDATE_BY_MUL_ID("updateByMulId", "按主键更新", "<script>\nUPDATE %s %s WHERE %s \n</script>"),
/**
* 查询
*/
SELECT_BY_MULTI_ID("getByMutId", "联合主键查询", "<script>\nselect %s from %s where %s %s\n</script>"),
SELECT_BY_ENTITY_MULTI_ID("getByEntityMultiId", "联合主键查询,主键通过实体类获取", "<script>\nselect %s from %s where %s %s\n</script>");
private final String method;
private final String desc;
private final String sql;
SqlCustomMethod(String method, String desc, String sql) {
this.method = method;
this.desc = desc;
this.sql = sql;
}
public String getMethod() {
return method;
}
public String getDesc() {
return desc;
}
public String getSql() {
return sql;
}
}
public class MultiParseUtils {
public static MultiInfo parseMultiId(Class<?> entity) {
if (entity.isAnnotationPresent(MultiId.class)) {
MultiId annotation = entity.getAnnotation(MultiId.class);
String[] ids = annotation.ids();
MultiInfo multiInfo = new MultiInfo();
List<String> colList = new ArrayList<>();
List<String> proList = new ArrayList<>();
Arrays.stream(ids).forEach(id -> {
colList.add(ConvertUtil.underline(id));
proList.add(id);
});
multiInfo.setColList(colList);
multiInfo.setProList(proList);
multiInfo.setSize(colList.size());
return multiInfo;
}
return null;
}
public static String getByMultiIdsSql(Class<?> entity) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(entity);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
List<String> proList = multiInfo.getProList();
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i)).append(" = #{item.").append(proList.get(i)).append("}");
if (i != size - 1) {
keySqlBuilder.append(" and ");
}
}
}
return keySqlBuilder.toString();
}
public static String getConflictSql(Class<?> entity) {
StringBuilder keySqlBuilder = new StringBuilder();
MultiInfo multiInfo = MultiParseUtils.parseMultiId(entity);
if (multiInfo != null) {
int size = multiInfo.getSize();
List<String> colList = multiInfo.getColList();
keySqlBuilder.append("(");
for (int i = 0; i < size; i++) {
keySqlBuilder.append(colList.get(i));
if (i != size - 1) {
keySqlBuilder.append(",");
}
}
keySqlBuilder.append((")"));
}
return keySqlBuilder.toString();
}
}
|