您的位置:首页 > 移动开发

do not repeat yourself:使用反射配合mybais mapper,300行代码搞定逻辑相似对象增删查改

2014-07-30 13:59 239 查看
主要代码:

public class ReflectUtils {

private static final Logger logger = LoggerFactory.getLogger(ReflectUtils.class);

private ReflectUtils(){

}

private static ConcurrentHashMap<String,Class> clazzMap = new ConcurrentHashMap<>();

private static ConcurrentHashMap<String,Method> methodMap = new ConcurrentHashMap<>();

public static Class getClazz(String className) throws ClassNotFoundException {

Class clazz = clazzMap.get(className);

if(clazz == null){

clazz = Class.forName(className);

clazzMap.put(className, clazz);

}

return clazz;

}

public static Method getMethod(Class clazz, String methodName, Class... args) {

String methodMapKey = getMethodMapKey(clazz.getName(), methodName, args);

Method method = methodMap.get(methodMapKey);

if(method == null){

try{

method = clazz.getMethod(methodName, args);

}catch (NoSuchMethodException ex){

logger.info("{} don't hava a [{}] method", clazz.getSimpleName(), methodName);

}

if(method != null){

methodMap.put(methodMapKey, method);

}

}

return method;

}

public static String getMethodMapKey(String className,String methodName, Class... args){

if(args==null || args.length==0){

return className+methodName;

}else {

StringBuffer methodMapKey = new StringBuffer(className).append('.').append(methodName);

for(Class clazz : args){

methodMapKey.append('_').append(clazz.toString());

}

return methodMapKey.toString();

}

}

}

public class MapperInvoker {

private static final Logger logger = LoggerFactory.getLogger(MapperInvoker.class);

private MapperInvoker(){

}

public static List<Object> selectByExample(Class objClazz, Object selectExample) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

String objClazzName = objClazz.getName();

Class mapperClazz = getMapperClazz(objClazzName);

Class selectExampleClazz = ReflectUtils.getClazz(objClazzName + "Example");//selectExample可能为null,不能用selectExample.getClass()

Method selectMethod = ReflectUtils.getMethod(mapperClazz, "selectByExample", selectExampleClazz);

List<Object> list = (List<Object>)selectMethod.invoke(GameServerGuiceFactory.getInstance(mapperClazz), selectExampleClazz.cast(selectExample));

logger.info("load {} list OK,list size={}",objClazz.getSimpleName(),list.size());

return list;

}

public static Object insertSelective(Object instance) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class instanceClazz = instance.getClass();

Class mapperClazz = getMapperClazz(instanceClazz.getName());

Method insertMethod = ReflectUtils.getMethod(mapperClazz, "insertSelective", instanceClazz);

insertMethod.invoke(GameServerGuiceFactory.getInstance(mapperClazz), instance);

return instance;

}

public static int deleteByPrimaryKey(Class itemClazz,Long id) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class mapperClazz = getMapperClazz(itemClazz.getName());

Method deleteByPrimaryKeyMethod = ReflectUtils.getMethod(mapperClazz, "deleteByPrimaryKey", Long.TYPE);

return (int)deleteByPrimaryKeyMethod.invoke(GameServerGuiceFactory.getInstance(mapperClazz), id);

}

public static int updateByPrimaryKeySelective(Object instance) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {

Class instanceClazz = instance.getClass();

Class mapperClazz = getMapperClazz(instanceClazz.getName());

Method updateMethod = ReflectUtils.getMethod(mapperClazz, "updateByPrimaryKeySelective", instanceClazz);

return (int)updateMethod.invoke(GameServerGuiceFactory.getInstance(mapperClazz), instance);

}

private static Class getMapperClazz(String objClazzName) throws ClassNotFoundException {

return ReflectUtils.getClazz(objClazzName + "Mapper");

}

}

客户端代码范例:

//加载缓存

private static ImmutableMap<Class,ImmutableMap<Integer,Object>> clazz2Id2DtInstanceMap;

public synchronized void loadClazz2Id2DtInstanceMap() throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {

Pattern dtClassPattern = Pattern.compile(DtGlobalParam.class.getPackage().getName()+"\\.Dt.+Mapper");

ImmutableMap.Builder<Class,ImmutableMap<Integer,Object>> mapBuilder = ImmutableMap.builder();

for(Key<?> key : GameServerGuiceFactory.getBindings().keySet()){

Class clazz = key.getTypeLiteral().getRawType();

String clazzName = clazz.getName();

if(dtClassPattern.matcher(clazzName).matches()){

Class objClazz = Class.forName(clazzName.replace("Mapper",""));

ImmutableMap<Integer,Object> id2DtInstanceMap = loadId2DtInstanceMap(objClazz);

if(id2DtInstanceMap!=null){

mapBuilder.put(objClazz,id2DtInstanceMap);

}

}

}

clazz2Id2DtInstanceMap = mapBuilder.build();

}

//依据类型、id获取缓存对象

public <T> T getDtInstance(Class clazz,Integer id){

return (T)clazz2Id2DtInstanceMap.get(clazz).get(id);

}

//依据类型获取缓存对象列表

public ImmutableMap<Integer,Object> getDtInstanceMap(Class clazz){

return clazz2Id2DtInstanceMap.get(clazz);

}

文档待整理...

do not repeat yourself:使用反射配合mybais mapper,300行代码搞定逻辑相似对象增删查改。

适用场景:逻辑配置数据管理;缓存数据增删查改等等。

应用该库,大大降低适用场景下程序工作量,且保证程序风格简洁易读,不用维护大量逻辑类似代码,降低bug率。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: