Springboot整合Dozer深度复制

匿名 (未验证) 提交于 2019-12-03 00:18:01

Dozer

Dozer是一种Java Bean到Java Bean的映射器,递归地将数据从一个对象复制到另一个对象,它是一个强大的,通用的,灵活的,可重用的和可配置的开源映射框架。

常用于:

  • 代码层与层之间javabean转换, 如dao层PO转前端VO
  • 分布式中, DAO层PO转DTO, DO 以及web层DTO转VO

注意的场景:

  • 由于bean之间的深度复制, 在进行一些类似更新, 插入操作时尤其要注意最终接收到PO的一些关键字段如ID是否是真正需要的. 场景: 传入的DTO A为查出的DTO B复制后的, 这时候A里会有B的ID, 在插入A的时候很有可能造成主键冲突.

建议:

  • 不用Dozer最好, Dozer带来的是性能开销.(这是不可能…)
  • 某些特殊操作可以用切面控制特殊字段进行置空操作

pom.xml加入以下依赖

<dependency>     <groupId>net.sf.dozer</groupId>     <artifactId>dozer-spring</artifactId>     <version>5.5.1</version> </dependency> <dependency>     <groupId>net.sf.dozer</groupId>     <artifactId>dozer</artifactId>     <version>5.5.1</version> </dependency>

resource文件夹下新建dozer文件夹, 并新建bean-mappings.xml, global-configuration.xml

  • bean-mappings.xml
<?xml version="1.0" encoding="UTF-8"?> <mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://dozer.sourceforge.net           http://dozer.sourceforge.net/schema/beanmapping.xsd"> </mappings>
  • global-configuration.xml
<?xml version="1.0" encoding="UTF-8"?> <mappings xmlns="http://dozer.sourceforge.net" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"     xsi:schemaLocation="http://dozer.sourceforge.net           http://dozer.sourceforge.net/schema/beanmapping.xsd">     <configuration>         <date-format>yyyy-MM-dd HH:mm:ss</date-format>               <wildcard>true</wildcard>         <trim-strings>false</trim-strings>         <!-- 自定义的枚举与Integer转换器, 下节介绍 -->         <custom-converters>             <converter type="com.dongao.beacon.ds.web.admin.tookit.EnumIntegerBiDirectionalDozerConverter">                 <class-a>java.lang.Enum</class-a>                 <class-b>java.lang.Integer</class-b>             </converter>         </custom-converters>     </configuration> </mappings>

用于SpringBoot寻找DozerBeanMapperFactoryBean的配置
新建DozerMapperConfig.java

public class DozerMapperConfig {      @Bean     public DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean(@Value("classpath*:dozer/*.xml") Resource[] resources) throws Exception {         final DozerBeanMapperFactoryBean dozerBeanMapperFactoryBean = new DozerBeanMapperFactoryBean();         dozerBeanMapperFactoryBean.setMappingFiles(resources);         return dozerBeanMapperFactoryBean;     }  }

建议新建包专门放置Dozer工具

  • 接口定义: 新建IGenerator.java接口
public interface IGenerator {      /**       * @Description: 单个对象的深度复制及类型转换,vo/domain , po      * @param s 数据对象      * @param clz 复制目标类型      * @return      * @author banjuer@outlook.com      * @Time 2018年5月9日 下午3:53:24      */     <T, S> T convert(S s, Class<T> clz);      /**      * @Description: 深度复制结果集(ResultSet为自定义的分页结果集)      * @param s 数据对象      * @param clz 复制目标类型      * @return      * @author banjuer@outlook.com      * @Time 2018年5月9日 下午3:53:24      */      <T, S> ResultSet<T> convert(ResultSet<S> s, Class<T> clz);      /**       * @Description: list深度复制      * @param s 数据对象      * @param clz 复制目标类型      * @return      * @author banjuer@outlook.com      * @Time 2018年5月9日 下午3:54:08      */     <T, S> List<T> convert(List<S> s, Class<T> clz);      /**       * @Description: set深度复制      * @param s 数据对象      * @param clz 复制目标类型      * @return      * @author banjuer@outlook.com      * @Time 2018年5月9日 下午3:54:39      */     <T, S> Set<T> convert(Set<S> s, Class<T> clz);      /**       * @Description: 数组深度复制      * @param s 数据对象      * @param clz 复制目标类型      * @return      * @author banjuer@outlook.com      * @Time 2018年5月9日 下午3:54:57      */     <T, S> T[] convert(S[] s, Class<T> clz);  }
  • IGenerator实现
@Component @Lazy(true) public class EJBGenerator implements IGenerator {      @Autowired     protected Mapper dozerMapper;      public <T, S> T convert(S s, Class<T> clz) {         if (s == null) {             return null;         }         return this.dozerMapper.map(s, clz);     }       public <T, S> ResultSet<T> convert(ResultSet<S> s, Class<T> clz) {      if (s == null) {      return null;      }      ResultSet<T> resultSet = newResultSet<T>();      for (S vs : s.getResult()) {      resultSet.getResult().add(this.dozerMapper.map(vs, clz));      }      resultSet.setTotal(s.getTotal());      resultSet.setExt(s.getExt());      resultSet.setModifyTime(s.getModifyTime());      returnresultSet;      }      public <T, S> List<T> convert(List<S> s, Class<T> clz) {         if (s == null) {             return null;         }         List<T> list = new ArrayList<T>();         for (S vs : s) {             list.add(this.dozerMapper.map(vs, clz));         }         return list;     }      public <T, S> Set<T> convert(Set<S> s, Class<T> clz) {         if (s == null) {             return null;         }         Set<T> set = new HashSet<T>();         for (S vs : s) {             set.add(this.dozerMapper.map(vs, clz));         }         return set;     }      public <T, S> T[] convert(S[] s, Class<T> clz) {         if (s == null) {             return null;         }         @SuppressWarnings("unchecked")         T[] arr = (T[]) Array.newInstance(clz, s.length);         for (int i = 0; i < s.length; i++) {             arr[i] = this.dozerMapper.map(s[i], clz);         }         return arr;     } } 

一般在公共父类中引入, 此处例子为前端公共Controller引入

@Controller public class BaseController  {      @Autowired     protected EJBGenerator ejbGenerator = new EJBGenerator();     protected final Logger logger = LoggerFactory.getLogger(getClass());  }
// 个人信息变更记录session SessionUserDetails userDetails = ejbGenerator.convert(userVo, SessionUserDetails.class);
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!