主键注解
import java.lang.annotation.Retention;
import java.lang.annotation.Target;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
@Target({ METHOD, FIELD })
@Retention(RUNTIME)
public @interface Id {
Class<?> strategy() default UUIDGenerator.class;
}
public interface IdGenerator {
public Serializable generator();
}
import ObjectId;
import java.io.Serializable;
public class UUIDGenerator implements IdGenerator {
@Override
public Serializable generator() {
return new ObjectId().toString();
}
}
注解解析
import java.io.Serializable;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;
public class PropertySet {
private Set<ProPertyStrategyMapper> propertys = new HashSet<ProPertyStrategyMapper>();
private Class<?> entity;
@SuppressWarnings("unused")
private PropertySet() {
}
public PropertySet(Class<?> entity) {
this.entity = entity;
this.build();
}
public Set<ProPertyStrategyMapper> getPropertys() {
return propertys;
}
public void setPropertys(Set<ProPertyStrategyMapper> propertys) {
this.propertys = propertys;
}
public PropertySet build() {
Field[] fields = entity.getDeclaredFields();
for (Field field : fields) {
if ("serialVersionUID".equals(field.getName()))
continue;
//注解在属性上
if(field.isAnnotationPresent(Id.class)){
Id id = field.getAnnotation(Id.class);
if (id.strategy() == null) {
continue;
}
Class<?> generator = id.strategy();
Object object = null;
try {
object = generator.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!(object instanceof IdGenerator)) {
continue;
}
IdGenerator idGenerator = (IdGenerator) object;
ProPertyStrategyMapper proPertyStrategyMapper = new ProPertyStrategyMapper(field.getName(),
idGenerator);
propertys.add(proPertyStrategyMapper);
break;
}
//注解在方法上
PropertyDescriptor propertyDescriptor = null;
try {
propertyDescriptor = new PropertyDescriptor(field.getName(), entity);
} catch (IntrospectionException e) {
e.printStackTrace();
}
if (propertyDescriptor == null)
continue;
// 获取类的get方法
Method method = propertyDescriptor.getReadMethod();
if (method == null) {
continue;
}
if (method.isAnnotationPresent(Id.class)) {
Id id = method.getAnnotation(Id.class);
if (id.strategy() == null) {
continue;
}
Class<?> generator = id.strategy();
Object object = null;
try {
object = generator.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
if (!(object instanceof IdGenerator)) {
continue;
}
IdGenerator idGenerator = (IdGenerator) object;
ProPertyStrategyMapper proPertyStrategyMapper = new ProPertyStrategyMapper(field.getName(),
idGenerator);
propertys.add(proPertyStrategyMapper);
break;
}
}
return this;
}
}
策略映射
public class ProPertyStrategyMapper {
private String propertyName;
private IdGenerator generator;
public ProPertyStrategyMapper(String propertyName, IdGenerator generator) {
super();
this.propertyName = propertyName;
this.setGenerator(generator);
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public IdGenerator getGenerator() {
return generator;
}
public void setGenerator(IdGenerator generator) {
this.generator = generator;
}
}
拦截器
import ProPertyStrategyMapper;
import PropertySet;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.plugin.*;
import org.springframework.util.ReflectionUtils;
import java.lang.reflect.Field;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
@Intercepts({ @Signature(type = Executor.class, method = "update", args = { MappedStatement.class, Object.class }) })
public class UUIDInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
Object[] args = invocation.getArgs();
if (args == null || args.length != 2 || !(args[0] instanceof MappedStatement)) {
return invocation.proceed();
}
MappedStatement mappedStatement = (MappedStatement) args[0];
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
if (!SqlCommandType.INSERT.equals(sqlCommandType)) {
return invocation.proceed();
}
setDefultProperty(args[1]);
return invocation.proceed();
}
public void setDefultProperty(Object obj) {
// 批量插入
if (obj instanceof Map) {
Map<String, Object> map = (Map<String, Object>) obj;
Set<String> keys = map.keySet();
for (String key : keys) {
List<Object> list = (List<Object>) map.get(key);
for (Object object : list) {
setObjectProperty(object);
}
break;
}
return;
}
setObjectProperty(obj);
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
System.out.println("init UUIDInterceptor");
}
private void setObjectProperty(Object obj) {
PropertySet propertySet = new PropertySet(obj.getClass());
Set<ProPertyStrategyMapper> propers = propertySet.getPropertys();
if (propers == null || propers.isEmpty())
return;
for (ProPertyStrategyMapper pro : propers)
try {
Field findField = ReflectionUtils.findField(obj.getClass(), pro.getPropertyName());
findField.setAccessible(true);
//findField.set(obj, pro.getGenerator().generator());
ReflectionUtils.setField(findField, obj, pro.getGenerator().generator());
} catch (Exception e) {
e.printStackTrace();
}
}
}