1.说明
2.代码
public class BaseServiceImpl<M extends BaseMapper<T>, T> extends ServiceImpl<M,T> implements BaseIService<M,T> {
/**
* 完整更新一个实体,为null的属性也将更新到数据库
* 该方法不会更新model继承来的属性,如需,需要修改反射调用的方法
* @param entity
* @return
*/
public Boolean updateIntact(T entity){
Assert.isTrue(entity!=null ,"实体类为null",true);
UpdateWrapper<T> wrapper=new UpdateWrapper<>();
//限制id
try {
Object id=PropertyUtils.getProperty(entity,"id");
Assert.isTrue( id!=null,"无法从实体类["+entity.getClass().getName()+"]获取的id的值,不能执行更新操作",true);
wrapper.eq("id",id);
} catch (Exception e) {
throw new ErrorException("无法从实体类["+entity.getClass().getName()+"]获取的id的值");
}
//设置要更新的属性和属性值
Map<String,Object> fieldAndValue= ReflectionUtils.getAllFieldAndValue(entity,false);
for(Map.Entry<String,Object> temp:fieldAndValue.entrySet()){
wrapper.set(temp.getKey(),temp.getValue());
}
return super.update(wrapper);
}
/**
* 将指定实体,指定的字段更新为null
* @param entity
* @param field
* @return
*/
public Boolean updateToNull(T entity,String...field){
Assert.isTrue(entity!=null ,"实体类为null",true);
Integer id=null;
try {
id=(Integer) PropertyUtils.getProperty(entity,"id");
Assert.isTrue( id!=null,"无法从实体类["+entity.getClass().getName()+"]获取的id的值,不能执行更新操作",true);
} catch (Exception e) {
throw new ErrorException("无法从实体类["+entity.getClass().getName()+"]获取的id的值");
}
return updateToNull(id,field);
}
/**
* 将指定id的数据的指定字段更新为null
* @param id
* @param field
* @return
*/
public Boolean updateToNull(Integer id,String...field){
Assert.isTrue(id!=null,"未指定要更新数据的id");
UpdateWrapper<T> wrapper=new UpdateWrapper<>();
wrapper.eq("id",id);
//设置要更新的属性和属性值
for(String temp:field){
Assert.isTrue(StringUtils.hasText(temp),"需要指定字段进行更新");
Assert.isTrue(!temp.equals("id"),"不能将id字段设置为null");
wrapper.set(temp,null);
}
return super.update(wrapper);
}
/**
* 判断一个对象里一些属性的值在数据库是否具有唯一性
* @Param entity 实体对象
* @param fields 字段名称
* @return
* @time 2019年10月14日16:30:30
* @author authstr
*/
@Override
public boolean isUnique(T entity, String... fields) {
Assert.isTrue(entity!=null ,"实体类为null",true);
QueryWrapper<T> wrapper = new QueryWrapper<>();
for(int i=0;i<fields.length;i++){
String field=fields[i];
Object value=null;
try {
value=PropertyUtils.getProperty(entity,field);
} catch (Exception e) {
throw new ErrorException("无法通过字段名["+fields+"]从实体类["+entity.getClass().getName()+"]获取值");
}
if(value==null){
throw new ErrorException("通过字段名["+fields+"]从实体类["+entity.getClass().getName()+"]获取的值是null");
}
wrapper.eq(field,value);
}
//判断是否加上id限制
try {
Object id=PropertyUtils.getProperty(entity,"id");
if(id!=null){
wrapper.ne("id",id);
}
} catch (Exception e) {
throw new ErrorException("无法从实体类["+entity.getClass().getName()+"]获取的id的值");
}
int count=super.count(wrapper);
if(count==0) {
return true;
}else{
return false;
}
}
}
/**
* 获取指定对象的所有属性名称和属性值.可以设置为使用属性的get方法获取值
* @param obj 要获取的对象
* @param byMethod 是否使用属性的get方法获取属性值
* @return
*/
public static Map<String,Object> getAllFieldAndValue(Object obj,Boolean byMethod){
Map<String,Object> res=new HashMap<String, Object>();
for (Field field : obj.getClass().getDeclaredFields()) {
Object value=null;
String name=field.getName();
if(byMethod){
value=executeGetMethod(obj,name,true);
}else{
try {
field.setAccessible(true);
value= field.get(obj);
} catch (IllegalAccessException e) {
e.printStackTrace();
throw new ErrorException("无法执行["+name+"]的字段的取值");
}
}
res.put(name, value);
}
return res;
}
/**
* 调用对象中一个属性的get方法
* @param obj 要操作的对象
* @param fieldName 属性名称
* @param isException 获取失败,是否抛出异常
* @return 该get方法的执行结果
* @time 2019年12月12日11:57:17
* @author authstr
*/
public static Object executeGetMethod(Object obj,String fieldName,Boolean isException){
// 构造get方法名称
Object value=null;
String methodName ="get"+ fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1);
try {
Method m = obj.getClass().getMethod(methodName);
//执行
value=m.invoke(obj);
} catch (NoSuchMethodException e) {
e.printStackTrace();
if(isException){
throw new ErrorException("未发现字段["+fieldName+"]的get方法");
}
} catch (Exception e) {
e.printStackTrace();
if(isException){
throw new ErrorException("无法执行["+fieldName+"]的get方法");
}
}
return value;
}
3. 注意点
- 如需要实现更新model继承来的属性,将调用的getAllFieldAndValue方法改成getAllParentFieldAndValue即可.
- getAllParentFieldAndValue方法代码
/**
* 获取指定对象的所有属性名称和属性值,包括为从父类继承来的属性.可以设置为使用属性的get方法获取值
* @param obj 要获取的对象
* @param byMethod 是否使用属性的get方法获取属性值
* @return
*/
public static Map<String,Object> getAllParentFieldAndValue(Object obj,Boolean byMethod){
Map<String,Object> res=new HashMap<String, Object>();
try {
PropertyUtilsBean propertyUtilsBean = new PropertyUtilsBean();
PropertyDescriptor[] descriptors = propertyUtilsBean.getPropertyDescriptors(obj);
for (int i = 0; i < descriptors.length; i++) {
String name = descriptors[i].getName();
if (!"class".equals(name)) {
Object value=null;
if(byMethod){
value=executeGetMethod(obj,name,true);
}else{
value=propertyUtilsBean.getNestedProperty(obj, name);
}
res.put(name, value);
}
}
} catch (Exception e) {
e.printStackTrace();
}
return res;
}
- 在使用该方法进行数据的更新时, mybatic-plus提供的@TableField功能将无法正确生效.因此需要注意更新的字段不要涉及有@TableField注解的字段. 我采取的方法是将有@TableField注解的字段抽到model的父类中,在调用updateIntact方法时默认不对继承的属性进行处理.
网友评论