業(yè)務(wù)中存在大量的request -> domin -> response的類型轉(zhuǎn)換
由于懶,不想寫這么多參數(shù)賦值损同,所以有了以下
為了方便寫一個(gè)反射方法
public static <F, T> T reflectionAttr(F f, Class<T> t) {
try {
Field[] fields1 = f.getClass().getDeclaredFields();
T t1 = t.getDeclaredConstructor().newInstance();
Field[] fields2 = t1.getClass().getDeclaredFields();
for (Field f1 : fields1) {
for (Field f2 : fields2) {
if (f1.getName().equals(f2.getName())) {
handler(f1, f2, f, t1);
}
}
}
return t1;
} catch (Exception e) {
LOGGER.error(e.getMessage());
}
return null;
}
private static <F, T> void handler(Field f1, Field f2, F f, T t1) throws Exception {
Class<?> type = f1.getType();
if (type.isEnum()) {
//處理枚舉
Object[] enumConstants = f2.getType().getEnumConstants();
for (Object ob : enumConstants) {
if (ob.toString().equals(f1.get(f).toString())) {
f2.set(t1, ob);
}
}
} else if (type == ObjectId.class) {
//處理objectId
f2.set(t1, f1.get(f).toString());
} else {
f2.set(t1, f1.get(f));
}
}
優(yōu)勢(shì):所有類中參數(shù)名一樣的值都可以直接賦值
缺點(diǎn):由于使用反射+大量for循環(huán) 在重復(fù)百萬次時(shí)速度差10-20倍
考慮其它方案:
代碼生成:通過模板生成對(duì)應(yīng)的方法
核心組件velocity
流程:
1.創(chuàng)建模板
2.加載模塊
3.加載數(shù)據(jù)
4.生成代碼
記一個(gè)經(jīng)驗(yàn):******
在創(chuàng)建模板后茂卦,生成的代碼的存在對(duì)不齊的問題组哩。即处渣,如何按自己的想法創(chuàng)建格式規(guī)范的代碼而咆;
在經(jīng)過10多次調(diào)試之后~~
理論上來說,你在模板里怎么寫就會(huì)生成對(duì)應(yīng)格式的代碼
但是在使用for循環(huán)悠瞬,if判斷時(shí)涯捻,要了解到,這些特殊字符前的符號(hào)也是站位的障癌,而這些也是造成對(duì)不齊最大的原因,盡可能將for,if頂格寫康辑,需要追加的字符串前需要多少空格或者tab就直接加即可轿亮;
下面是一個(gè)包含增刪改查的service模板
/**
* @author ${author}
*/
public class ${className}Service {
@Inject
Repository<${className}> ${classname}Repository;
public Create${className}Response create(Create${className}Request request) {
${className} ${classname} = new ${className}();
#foreach ($column in $columns)#if($column.attrType == "LocalDateTime")
${classname}.${column.attrname} = LocalDateTime.now();
#elseif($column.attrType == "LocalDate")
${classname}.${column.attrname} = LocalDate.now();
#elseif($column.extra == "auto_increment")
#elseif($column.dataType=="enum")
${classname}.${column.attrname} = Enum.valueOf(${column.attrName}.class, request.${column.attrname}.toString());
#else
${classname}.${column.attrname} = request.${column.attrname};
#end
#end
${classname}.id = ${classname}Repository.insert(${classname}).orElseThrow(() -> new RuntimeException("create ${classname} failed"));
Create${className}Response create${className}Response = new Create${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
create${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
create${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
return create${className}Response;
}
private ${className} get(Long id) {
return ${classname}Repository.get(id).orElseThrow(() -> new NotFoundException("${classname} not found"));
}
public Update${className}Response update(Long id, Update${className}Request request) {
${className} ${classname} = get(id);
#foreach ($column in $columns)#if($column.attrname.indexOf("created")!=-1)
#elseif($column.attrType == "LocalDate")
${classname}.${column.attrname} = LocalDate.now();
#elseif($column.extra == "auto_increment")
#elseif($column.attrType == "LocalDateTime")
${classname}.${column.attrname} = LocalDateTime.now();
#elseif($column.dataType=="enum")
${classname}.${column.attrname} = Enum.valueOf(${column.attrName}.class, request.${column.attrname}.toString());
#else
${classname}.${column.attrname} = request.${column.attrname};
#end
#end
${classname}Repository.update(${classname});
Update${className}Response update${className}Response = new Update${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
update${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
update${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
return update${className}Response;
}
public Get${className}Response getView(Long id) {
${className} ${classname} = get(id);
Get${className}Response get${className}Response = new Get${className}Response();
#foreach ($column in $columns)#if($column.dataType=="enum")
get${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
get${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
return get${className}Response;
}
public Search${className}Response search(Search${className}Request request) {
Query<${className}> query = ${classname}Repository.select();
query.skip(request.skip);
query.limit(request.limit);
Search${className}Response search${className}Response = new Search${className}Response();
search${className}Response.total = query.count();
search${className}Response.${tableName} = query.fetch()
.stream().map(${classname} -> {
Search${className}Response.${className} search${className} = new Search${className}Response.${className}();
#foreach ($column in $columns)#if($column.dataType=="enum")
Search${className}Response.${column.attrname} = Enum.valueOf(${column.attrName}View.class, ${classname}.${column.attrname}.toString());
#else
Search${className}Response.${column.attrname} = ${classname}.${column.attrname};
#end
#end
return search${className};
}).collect(Collectors.toList());
return search${className}Response;
}
public void delete(Long id) {
get(id);
${classname}Repository.delete(id);
}
}
經(jīng)驗(yàn)2:剛開始調(diào)試模板的,總要重啟項(xiàng)目才能重新加載励七,在idea中加如jrebel插件后,每次改完模板奔缠,點(diǎn)擊build即可,不用重啟項(xiàng)目校哎,加快調(diào)式速度