标签:比较 length arraylist osi tar list repos eof xtend
在上篇博客中:SpringBoot系列——Spring-Data-JPA:https://www.cnblogs.com/huanzi-qch/p/9970545.html,我们实现了单表的基础get、save(插入/更新)、list、page、delete接口,但是这样每个单表都要写着一套代码,重复而繁杂,那能不能写成一套通用common代码,每个单表去继承从而实现这套基础接口呢?同时,我们应该用Vo去接收、传输数据,实体负责与数据库表映射。
Vo与实体转换
/** * 实体转换工具 */ public class FastCopy { /** * 类型转换:实体Vo <->实体 例如:UserVo <-> User * 支持一级复杂对象复制 */ public static <T> T copy(Object src, Class<T> targetType) { T target = null; try { target = targetType.newInstance(); BeanWrapper targetBean = new BeanWrapperImpl(target); BeanMap srcBean = new BeanMap(src); for (Object key : srcBean.keySet()) { try { String srcPropertyName = key + ""; Object srcPropertyVal = srcBean.get(key); //&& StringUtils.isEmpty(targetBean.getPropertyValue(srcPropertyName)) if (!StringUtils.isEmpty(srcPropertyVal) && !"class".equals(srcPropertyName)) { Class srcPropertyType = srcBean.getType(srcPropertyName); Class targetPropertyType = targetBean.getPropertyType(srcPropertyName); if (targetPropertyType != null) { if (srcPropertyType == targetPropertyType) { targetBean.setPropertyValue(srcPropertyName, srcPropertyVal); } else { Object targetPropertyVal = targetPropertyType.newInstance(); BeanUtils.copyProperties(srcPropertyVal, targetPropertyVal); targetBean.setPropertyValue(srcPropertyName, targetPropertyVal); BeanWrapper targetBean2 = new BeanWrapperImpl(targetPropertyVal); BeanMap srcBean2 = new BeanMap(srcPropertyVal); srcBean2.keySet().forEach((srcPropertyName2) -> { Class srcPropertyType2 = srcBean2.getType((String) srcPropertyName2); Class targetPropertyType2 = targetBean2.getPropertyType((String) srcPropertyName2); if (targetPropertyType2 != null && srcPropertyType2 != targetPropertyType2 && srcBean2.get(srcPropertyName2) != null && !"class".equals(srcPropertyName2)) { Object targetPropertyVal2 = null; try { targetPropertyVal2 = targetPropertyType2.newInstance(); } catch (Exception e) { e.printStackTrace(); } BeanUtils.copyProperties(srcBean2.get(srcPropertyName2), targetPropertyVal2); targetBean2.setPropertyValue((String) srcPropertyName2, targetPropertyVal2); } }); } } } } catch (Exception e) { e.printStackTrace(); } } } catch (Exception e) { e.printStackTrace(); } return target; } /** * 类型转换:实体Vo <->实体 例如:List<UserVo> <-> List<User> */ public static <T> List<T> copyList(List srcList, Class<T> targetType) { List<T> newList = new ArrayList<>(); for (Object entity : srcList) { newList.add(copy(entity, targetType)); } return newList; } /** * 获取/过滤对象的空属性 */ public static String[] getNullProperties(Object src) { BeanWrapper srcBean = new BeanWrapperImpl(src); //1.获取Bean Set<String> properties = new HashSet<>(); //3.获取Bean的空属性 for (PropertyDescriptor p : srcBean.getPropertyDescriptors()) { String propertyName = p.getName(); Object srcValue = srcBean.getPropertyValue(propertyName); if (StringUtils.isEmpty(srcValue)) { srcBean.setPropertyValue(propertyName, null); properties.add(propertyName); } } String[] result = new String[properties.size()]; return properties.toArray(result); } /** * 获取对象的非空属性 */ public static Map<String, Object> getNotNullProperties(Object src) { BeanWrapper srcBean = new BeanWrapperImpl(src); //1.获取Bean PropertyDescriptor[] pds = srcBean.getPropertyDescriptors(); //2.获取Bean的属性描述 Map<String, Object> properties = new LinkedHashMap<>(); //3.获取Bean的非空属性 for (PropertyDescriptor p : pds) { String key = p.getName(); Object value = srcBean.getPropertyValue(key); if (!StringUtils.isEmpty(value) && !"class".equals(key)) { properties.put(key, value); } } return properties; } /** * 将Object数组转为实体类VO */ public static <V> List<V> getEntityVo(List<Object[]> propertyArrayList, Class<V> voClass) { List<V> list = new ArrayList<>(); try { if (propertyArrayList != null) { for (Object[] propertyArray : propertyArrayList) { V vo = voClass.newInstance(); Field[] fields = vo.getClass().getDeclaredFields(); for (int i = 0; i < propertyArray.length; i++) { Field voField = fields[i]; Object queryVal = propertyArray[i]; if (voField.getType() == String.class && queryVal instanceof BigDecimal) { queryVal = String.valueOf(queryVal); } voField.setAccessible(true);//获取授权 voField.set(vo, queryVal); } list.add(vo); } } } catch (Exception e) { throw new RuntimeException(e); } return list; } }
通用service、repository
/** * 通用Service * * @param <V> 实体类Vo * @param <E> 实体类 * @param <T> id主键类型 */ public interface CommonService<V, E,T> { Result<PageInfo<V>> page(V entityVo); Result<List<V>> list(V entityVo); Result<V> get(T id); Result<V> save(V entityVo); Result<T> delete(T id); }
/** * 通用Service实现类 * * @param <V> 实体类Vo * @param <E> 实体类 * @param <T> id主键类型 */ public class CommonServiceImpl<V, E, T> implements CommonService<V, E, T> { private Class<V> entityVoClass;//实体类Vo private Class<E> entityClass;//实体类 @Autowired private CommonRepository<E, T> commonRepository;//注入实体类仓库 CommonServiceImpl() { Type[] types = ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments(); this.entityVoClass = (Class<V>) types[0]; this.entityClass = (Class<E>) types[1]; } @Override public Result<PageInfo<V>> page(V entityVo) { //实体类缺失分页信息 if (!(entityVo instanceof PageCondition)) { throw new RuntimeException("实体类" + entityClass.getName() + "未继承PageCondition。"); } PageCondition pageCondition = (PageCondition) entityVo; Page<E> page = commonRepository.findAll(Example.of(FastCopy.copy(entityVo, entityClass)), pageCondition.getPageable()); return Result.of(PageInfo.of(page, entityVoClass)); } @Override public Result<List<V>> list(V entityVo) { List<E> entityList = commonRepository.findAll(Example.of(FastCopy.copy(entityVo, entityClass))); List<V> entityModelList = FastCopy.copyList(entityList, entityVoClass); return Result.of(entityModelList); } @Override public Result<V> get(T id) { Optional<E> optionalE = commonRepository.findById(id); if (!optionalE.isPresent()) { throw new RuntimeException("ID不存在!"); } return Result.of(FastCopy.copy(optionalE.get(), entityVoClass)); } @Override public Result<V> save(V entityVo) { E e = commonRepository.save(FastCopy.copy(entityVo, entityClass)); return Result.of(FastCopy.copy(e, entityVoClass)); } @Override public Result<T> delete(T id) { commonRepository.deleteById(id); return Result.of(id); } }
/** * 通用Repository * * @param <E> 实体类 * @param <T> id主键类型 */ @NoRepositoryBean public interface CommonRepository<E,T> extends JpaRepository<E,T>, JpaSpecificationExecutor<E> { }
单表继承通用代码,实现get、save(插入/更新)、list、page、delete接口
Vo
/** * 用户类Vo */ @Data public class UserVo extends PageCondition implements Serializable { private Integer id; private String username; private String password; private Date created; private String descriptionId; //机架类型信息 private DescriptionVo description; }
/** * 用户描述类Vo */ @Data public class DescriptionVo implements Serializable { private Integer id; private String userId; private String description; }
controller、service、repository
@RestController @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @RequestMapping("/getAllUser") public ModelAndView getAllUser(){ Result result=userService.getAllUser(); ModelAndView mv=new ModelAndView(); mv.addObject("userList",result.getData()); mv.setViewName("index.html"); return mv; } /* CRUD、分页、排序 */ @RequestMapping("page") public Result<PageInfo<UserVo>> page(UserVo entityVo) { return userService.page(entityVo); } @RequestMapping("list") public Result<List<UserVo>> list(UserVo entityVo) { return userService.list(entityVo); } @RequestMapping("get/{id}") public Result<UserVo> get(@PathVariable("id") Integer id) { return userService.get(id); } @RequestMapping("save") public Result<UserVo> save(UserVo entityVo) { return userService.save(entityVo); } @RequestMapping("delete/{id}") public Result<Integer> delete(@PathVariable("id") Integer id) { return userService.delete(id); } }
public interface UserService extends CommonService<UserVo, User,Integer>{ Result getAllUser(); }
@Service public class UserServiceImpl extends CommonServiceImpl<UserVo, User,Integer> implements UserService { @Autowired private UserRepository userRepository; @Override public Result getAllUser() { List<User> userList = userRepository.getAllUser(); if(userList != null && userList.size()>0){ ArrayList<UserVo> userVos = new ArrayList<>(); for(User user : userList){ userVos.add(FastCopy.copy(user, UserVo.class)); } return Result.of(userVos); }else { return Result.of(userList,false,"获取失败!"); } } }
@Repository public interface UserRepository extends CommonRepository<User, Integer> { @Query(value = "from User") //HQL // @Query(value = "select * from tb_user",nativeQuery = true)//原生SQL List<User> getAllUser(); }
经测试,所有的接口都可以使用,数据传输正常,因为传输的Vo,分页信息跟杂七杂八的字段、数据都在Vo,所有看起来会比较杂。更新接口依旧跟上一篇的一样,接收到的是什么就保存什么。
单表的增删改查接口,直接继承这一套通用代码即可实现,无需再重复编写,大大提升开发效率。
SpringBoot系列——Spring-Data-JPA(升级版)
标签:比较 length arraylist osi tar list repos eof xtend
原文地址:https://www.cnblogs.com/huanzi-qch/p/9984261.html