1.一款 IDEA 插件帮你优雅转化 DTO、源码VO、源码BO、源码PO、源码DO
2.还在用BeanUtils拷贝对象?MapStruct才是源码王者!附源码
3.再见 BeanUtils !
4.Bean复制的源码phpwind 论坛源码几种框架性能比较:BeanUtils、PropertyUtils、源码BeanCopier
5.对象属性拷贝,源码到底谁更厉害?
6.Hibernateå
ä½ç¨è¯¦è§£
一款 IDEA 插件帮你优雅转化 DTO、源码VO、源码BO、源码PO、源码DO
在Java开发中,源码POJO(Plain Old Java Object)的源码使用场景多种多样,通常会根据业务需求分化为VO(View Object)、源码BO(Business Object)、PO(Persistent Object)、DTO(Data Transfer Object)和DO(Domain Object)。
VO,作为表示层对象,主要负责前端展示的数据,例如,接口返回给前端的数据会经过转换为VO。在接口层,DTO通常会被转化为VO以供前台展示。
BO则是业务层的对象,它在服务内部使用,用于对象聚合和业务处理。例如,从DTO中提取数据后,转化为BO进行处理,再转回DTO传递到接口层。
PO,即持久对象,存储数据库中的数据,主要用于数据存储,不涉及业务逻辑。当从数据库获取数据后,会转化为PO,官方twrp源码再进一步转为DTO传递到服务层。
DTO作为服务间通信的数据载体,它可以在不同层服务间(如接口、服务、数据库等)进行数据传递,实现解耦。
DO在不同的开发规范中有着不同的解释:在阿里巴巴的开发手册中,DO等同于PO;而在DDD(领域驱动设计)中,DO与BO的概念相似,代表业务逻辑的核心对象。
针对这些繁琐的转化过程,插件Simple Object Copy提供了便捷的解决方案。使用该插件,无需手写复杂的映射代码,可以一键生成转换代码,即使是复杂对象,也能轻松处理。比如,市面上的其他工具如Spring BeanUtils、Cglib BeanCopier等,虽然功能强大,但需引入额外依赖,代码侵入性强,而Simple Object Copy则避免了这些问题,提供更直观的编码提示,使得代码更清晰,减少出错可能。
如果你需要在IDEA中使用Simple Object Copy,可以在市场插件搜索中找到它,与其他插件如generateAllSetter配合使用,提升开发效率。
还在用BeanUtils拷贝对象?MapStruct才是王者!附源码
MapStruct 是一个强大的 Java 代码生成工具,专用于简化 JavaBean 类型之间的映射实现,尤其在多层应用中实体类与数据传输对象(DTO)之间映射的场景中发挥巨大优势。与传统的手工实现映射相比,MapStruct 通过生成高性能且易于理解的映射代码,显著提高了开发效率,降低了错误率。商城源码上线 MapStruct 的核心特点包括: 自动代码生成:MapStruct 作为编译器插件,在编译时自动为映射接口生成映射代码,实现对象属性的快速映射。 性能优化:生成的映射代码基于普通方法调用,高效且类型安全,支持快速开发和错误检查。 约定优于配置:默认提供了丰富的映射规则,减少配置复杂性,但允许用户自定义实现特殊映射行为。 以下是 MapStruct 的基本使用流程: 引入依赖:确保在项目中正确配置 MapStruct 与 Lombok 的版本兼容性。 定义实体类和 DTO 类:创建需要映射的对象。 创建映射接口:定义映射方法,约定映射规则。 生成映射代码:编译项目,MapStruct 会自动生成实现类,包含所有定义的映射逻辑。 使用映射接口:在客户端代码中注入映射接口,调用映射方法完成对象间的转换。 除了基础用法,MapStruct 还提供了更高级的特性: @Mapper 注解:用于标记映射接口,激活代码生成。 @Mapping 属性:用于配置映射规则,支持多种映射策略,如通过源属性、表达式或常量。 @Mappings、@MappingTarget 等注解:支持更复杂、动态的映射逻辑,如更新已有对象的属性。 扩展功能:如支持多个对象映射至单个对象等高级用法。 MapStruct 与传统拷贝方法的对比显示,它在处理大数据量时具有显著的性能优势。在性能测试中,MapStruct 的表现优于其他常见拷贝工具,如 Apache BeanUtils、cglib 等。在实际应用中,选择 MapStruct 作为对象映射工具,js 源码之家尤其在需要处理大量数据时,能够显著提升系统性能,优化资源利用。再见 BeanUtils !
在开发和维护过程中,分层设计是常用的一种策略,通过VO(View Object)、BO(Business Object)、PO(Presentation Object)以及DTO(Data Transfer Object)等数据对象在不同层之间传递信息,避免了频繁的属性拷贝操作。传统方法如手动逐个属性赋值或使用IDE插件虽能提高效率,但存在低效、容易出错等问题。为解决这些问题,出现了多种属性拷贝工具,包括 Bean Copier(如 Apache BeanUtils、Spring BeanUtils 和 cglib BeanCopier)和 MapStruct。 Bean Copier提供了几种解决方案,如 Apache BeanUtils 和 Spring BeanUtils,它们使用反射来实现属性拷贝。Apache BeanUtils效率较低且在阿里Java开发规范中被禁止使用,Spring BeanUtils在性能方面有所优化,但仍然存在类型不匹配或属性重命名时拷贝失败的问题。cglib BeanCopier则使用动态技术替代反射,运行效率相对较高,但功能有限,不支持深拷贝和复杂场景。 在此背景下,MapStruct作为一种基于Java注解处理器的映射工具,提供了高性能、类型安全和功能丰富的映射功能。它通过生成类型安全且高性能的映射器,在编译期间优化了属性拷贝过程,使得开发效率和代码可维护性大幅提升。 MapStruct具备以下优点:高性能:MapStruct使用普通方法赋值,而非反射,从而在编译期间生成类,使用原生的oa源码程序set方法进行赋值,性能与手写set方法基本一致。
类型安全:MapStruct在编译时生成映射代码,能够提前发现类型、名称不匹配等问题,避免运行时错误。
功能丰富:MapStruct支持深拷贝、指定各种拷贝行为,以及集合拷贝等复杂场景。
使用简单:用户仅需定义接口和拷贝行为,MapStruct会在编译期自动生成实现类。
下面是一个使用MapStruct的示例。假设我们有SourceData和TargetData类,且存在一个需要映射的类TestData。首先,导入MapStruct相关包,并定义Mapper接口。接口中包含映射方法,如将SourceData对象映射到TargetData对象。通过使用@Mapper注解和@Mapping注解,定义了源字段和目标字段之间的映射关系。默认情况下,MapStruct实现的是浅拷贝,但可以很容易地通过使用@DeepClone注解实现深拷贝。 此外,MapStruct支持类型转换、忽略字段、与Lombok集成等功能,进一步增强了其灵活性和实用性。通过与Lombok集成,可以简化代码编写,同时保持MapStruct的性能和类型安全优势。 总结而言,MapStruct提供了一种高效、安全且功能丰富的映射解决方案,适用于处理属性拷贝、深拷贝以及各种复杂映射场景。在实际应用中,MapStruct能够显著提升开发效率,简化代码维护,并确保运行时的性能。不过,由于需要引入额外的MapStruct包,对于只有少量拷贝需求的项目,手动编写代码可能是更合适的选择。然而,对于涉及大量数据映射和复杂场景的项目,MapStruct无疑是一个值得推荐的工具。Bean复制的几种框架性能比较:BeanUtils、PropertyUtils、BeanCopier
在深入理解Bean复制框架性能的过程中,作为新员工的我,阅读代码时发现了几种实现值复制的方式,包括Apache的BeanUtils和PropertyUtils,Spring的BeanUtils,以及Cglib的BeanCopier。为了探究性能差异的真实性,我决定进行一次全面的性能测试。此次测试在Eclipse环境中进行,利用策略模式编写测试代码,对四种方式进行了三次测试。
测试对象是一个FromBean和一个ToBean,它们除了类名称不同,其他部分代码基本一致,以减少代码重复。策略模式下的接口声明以及使用的测试类进行了详细的编写,确保了测试的准确性和有效性。
最终结果揭示了Cglib的BeanCopier性能最优,无论是面对1万次的大量测试,还是次的少量测试,性能都接近于零损耗。相比之下,Spring的性能在大量测试时表现出色,但在少量测试时则略逊于PropertyUtils。PropertyUtils的性能相对稳定,呈现出线性增长的趋势。
然而,Cglib在测试过程中先进行了实例的缓存,这一特性显著提高了其性能。若去除了缓存,性能会略有差异,但整体表现依然出色。有趣的是,在测试中发现,当进行1万次测试时,Cglib的性能相较于次测试有所提升,而且在反转1万次测试中,耗时最少,多次测试结果也呈现出相同趋势。
从整体表现来看,Cglib的BeanCopier性能表现最为突出,无论是在大量测试还是少量测试中,其性能均处于领先地位。同时,Spring的性能在大量测试时相对较好,但在少量测试时不如PropertyUtils。PropertyUtils的性能相对稳定,表现出线性增长的趋势。
此次性能测试的结果揭示了不同Bean复制框架在性能上的差异,为实际项目选择合适的框架提供了参考。后续,我将撰写更多文章,详细探讨每种方式的使用差异,并深入探讨导致这些性能差异的内在原因。
对象属性拷贝,到底谁更厉害?
日常编程中,我们常需处理对象属性的复制。当属性数量较少时,手动使用set/get方法即可。然而,面对属性数量众多的场景,这种方法不仅耗时,且机械性操作易让人感到乏味。因此,开发者们引入了通用的对象属性复制工具,以提高效率与减少重复编程工作。本文将探讨几种常用的对象属性复制工具,并通过实践与性能对比,给出选择建议。
首先,我们定义一个`UserInfo`类作为复制案例。接下来,我们将介绍几种常用工具及其使用方式和性能对比。
**Apache BeanUtils** 是早期广为使用的对象复制工具。使用简单,需导入`commons-beanutils`包,然后利用`BeanUtils`工具进行复制。然而,其底层设计复杂,过度使用反射和校验,导致性能不佳,故在阿里巴巴开发手册中被建议避免使用。
**Spring BeanUtils** 与 Apache BeanUtils 类似,同样方便使用,但性能表现更优。主要原因是 Spring 并未在复制操作中进行过度校验,且内部使用了缓存机制,加速了转换过程。值得注意的是,Apache BeanUtils 和 Spring BeanUtils 的类名和方法虽然相似,但参数顺序不同,直接替换存在风险。
**Cglib BeanCopier** 则通过字节码技术动态生成代理类,实现对象复制。使用相对复杂,需导入`cglib`包,通过`BeanCopier`工具进行复制。Cglib 的性能优于 Apache 和 Spring 的 BeanUtils,尤其在重复使用代理类时表现更佳。同时,Spring 提供的`BeanCopier`实际上是 Cglib 的封装,用于保证 Spring 框架的稳定性。
**MapStruct** 与前述工具不同,它在编译期间生成对象复制逻辑,提供更快的复制速度。使用 MapStruct 需导入相关包,定义复制接口,并在代码中调用接口。这使得 MapStruct 无需在运行时进行额外处理,极大地提高了性能。
进行性能对比测试后,我们发现 MapStruct 的复制速度最快,而 Apache BeanUtils 性能最差。选择工具时,需综合考虑项目需求、性能要求和开发团队习惯。
本文总结了几种对象属性复制工具的使用方式与性能特点,并给出选择建议。对于需要深拷贝的场景,可考虑使用对象序列化和反序列化技术。如有任何疑问或补充意见,欢迎读者在评论区分享。
本文内容难免有不完善之处,期待读者的指正与讨论。更多相关内容,请参考相关技术博客。
Hibernateå ä½ç¨è¯¦è§£
ããHibernateä¸å ±å æ¬äº 个jarå 令人ç¼è±ç¼ä¹± æ¬æå°è¯¦ç»è®²è§£Hibernateæ¯ä¸ªjarå çä½ç¨ 便äºä½ å¨åºç¨ä¸æ ¹æ®èªå·±çéè¦è¿è¡åèããä¸è½½Hibernate ä¾å¦ 稳å®çæ¬ è§£å缩 å¯ä»¥çå°ä¸ä¸ªhibernate jarålibç®å½ä¸æ 个jarå
ããhibernate jar:
ããHibernateçåº æ²¡æä»ä¹å¯è¯´ç å¿ é¡»ä½¿ç¨çjarå
ããcglib a *** jar:
ããCGLIBåº Hibernateç¨å®æ¥å®ç°POåèç çå¨æçæ éå¸¸æ ¸å¿çåº å¿ é¡»ä½¿ç¨çjarå
ããdom j jar:
ããdom jæ¯ä¸ä¸ªJavaçXML API 类似äºjdom ç¨æ¥è¯»åXMLæ件ç dom jæ¯ä¸ä¸ªé常é常ä¼ç§çJava XML API å ·ææ§è½ä¼å¼ åè½å¼ºå¤§åæ端æç¨ä½¿ç¨çç¹ç¹ åæ¶å®ä¹æ¯ä¸ä¸ªå¼æ¾æºä»£ç ç软件 å¯ä»¥å¨SourceFeä¸æ¾å°å® å¨IBM developerWorksä¸é¢å¯ä»¥æ¾å°ä¸ç¯æç« å¯¹ä¸»æµçJava XML APIè¿è¡çæ§è½ åè½åæç¨æ§çè¯æµ dom jæ 论å¨é£ä¸ªæ¹é¢é½æ¯é常åºè²ç ææ©å¨å°è¿ä¸¤å¹´ä¹åå°±å¼å§ä½¿ç¨dom j ç´å°ç°å¨ å¦ä»ä½ å¯ä»¥çå°è¶æ¥è¶å¤çJava软件é½å¨ä½¿ç¨dom jæ¥è¯»åXML ç¹å«å¼å¾ä¸æçæ¯è¿SunçJAXMä¹å¨ç¨dom j è¿æ¯å¿ 须使ç¨çjarå Hibernateç¨å®æ¥è¯»åé ç½®æ件
ããodmg jar:
ããODMGæ¯ä¸ä¸ªORMçè§è Hibernateå®ç°äºODMGè§è è¿æ¯ä¸ä¸ªæ ¸å¿çåº å¿ é¡»ä½¿ç¨çjarå
ããmons collections jar
ããApache Commonså ä¸çä¸ä¸ª å å«äºä¸äºApacheå¼åçéåç±» åè½æ¯java util *强大 å¿ é¡»ä½¿ç¨çjarå
ããmons beanutils jar
ããApache Commonså ä¸çä¸ä¸ª å å«äºä¸äºBeanå·¥å ·ç±»ç±» å¿ é¡»ä½¿ç¨çjarå
ããmons lang jar:
ããApache Commonså ä¸çä¸ä¸ª å å«äºä¸äºæ°æ®ç±»åå·¥å ·ç±» æ¯java lang *çæ©å± å¿ é¡»ä½¿ç¨çjarå
ããmons logging jar:
ããApache Commonså ä¸çä¸ä¸ª å å«äºæ¥å¿åè½ å¿ é¡»ä½¿ç¨çjarå è¿ä¸ªå æ¬èº«å å«äºä¸ä¸ªSimple Logger ä½æ¯åè½å¾å¼± å¨è¿è¡çæ¶åå®ä¼å å¨CLASSPATHæ¾log j å¦ææ 就使ç¨log j å¦æ没æ å°±æ¾JDK 带çjava util logging å¦æä¹æ¾ä¸å°å°±ç¨Simple Logger mons logging jarçåºç°æ¯ä¸ä¸ªåå²ççéççéæ¾ å½åApacheæå游说Sunælog jå å ¥JDK ç¶èJDK 项ç®å°ç»å·²ç»æ¥è¿åå¸JDK 产åçæ¶é´äº å æ¤æç»äºApacheçè¦æ± 使ç¨èªå·±çjava util logging è¿ä¸ªå çåè½æ¯log jå·®çå¾è¿ æ§è½ä¹ä¸è¬
ããåæ¥Apacheå°±å¼ååºæ¥äºmons logging jarç¨æ¥å ¼å®¹ä¸¤ä¸ªlogger å æ¤ç¨mons logging jaråçlogç¨åº åºå±çLoggeræ¯å¯ä»¥åæ¢ç ä½ å¯ä»¥éæ©log j java util loggingæè å®èªå¸¦çSimple Logger ä¸è¿æä»ç¶å¼ºç建议使ç¨log j å 为log jæ§è½å¾é« logè¾åºä¿¡æ¯æ¶é´å ä¹çäºSystem out èå¤çä¸æ¡logå¹³ååªéè¦ us ä½ å¯ä»¥å¨Hibernateçsrcç®å½ä¸æ¾å°Hibernateå·²ç»ä¸ºä½ åå¤å¥½äºçlog jçé ç½®æ件 ä½ åªéè¦å°Apache ç½ç«å»ä¸è½½log jå°±å¯ä»¥äº mons logging jarä¹æ¯å¿ é¡»çjarå
ãã使ç¨Hibernateå¿ é¡»çjarå å°±æ¯ä»¥ä¸çè¿å 个 å©ä¸çé½æ¯å¯éç
ããant jar:
ããAntç¼è¯å·¥å ·çjarå ç¨æ¥ç¼è¯Hibernateæºä»£ç ç å¦æä½ ä¸åå¤ä¿®æ¹åç¼è¯Hibernateæºä»£ç é£ä¹å°±æ²¡æä»ä¹ç¨ å¯éçjarå
ããoptional jar
ããAntçä¸ä¸ªè¾ å©å
ããc p jar
ããC POæ¯ä¸ä¸ªæ°æ®åºè¿æ¥æ± Hibernateå¯ä»¥é 置为使ç¨C POè¿æ¥æ± å¦æä½ åå¤ç¨è¿ä¸ªè¿æ¥æ± å°±éè¦è¿ä¸ªjarå
ããproxool jar
ããä¹æ¯ä¸ä¸ªè¿æ¥æ± åä¸
ããmons pool jar mons dbcp jar:
ããDBCPæ°æ®åºè¿æ¥æ± ApacheçJakartaç»ç»å¼åç Tomcat çè¿æ¥æ± ä¹æ¯DBCP
ããå®é ä¸Hibernateèªå·±ä¹å®ç°äºä¸ä¸ªé常é常ç®åçæ°æ®åºè¿æ¥æ± å ä¸ä¸é¢ 个 ä½ å®é ä¸å¯ä»¥å¨Hibernateä¸éæ© ç§ä¸åçæ°æ®åºè¿æ¥æ± éæ©åªä¸ä¸ªç个人çå好 ä¸è¿DBCPå¯è½æ´éç¨ä¸äº å¦å¤å¼ºè°ä¸ç¹ å¦æå¨EJBä¸ä½¿ç¨Hibernate ä¸å®è¦ç¨App Serverçè¿æ¥æ± ä¸è¦ç¨ä»¥ä¸ ç§è¿æ¥æ± å¦å容å¨ç®¡çäºå¡ä¸èµ·ä½ç¨
ããconnector jar:
ããJCA è§è å¦æä½ å¨App Serverä¸æHibernateé 置为Connectorçè¯ å°±éè¦è¿ä¸ªjar ä¸è¿å®é ä¸ä¸è¬App Serverè¯å®ä¼å¸¦ä¸è¿ä¸ªå æ以å®é ä¸æ¯å¤ä½çå
ããjaas jar:
ããJAASæ¯ç¨æ¥è¿è¡æééªè¯ç å·²ç»å å«å¨JDK éé¢äº æ以å®é ä¸æ¯å¤ä½çå
ããjcs jar
ããå¦æä½ åå¤å¨Hibernateä¸ä½¿ç¨JCSçè¯ é£ä¹å¿ é¡»å æ¬å® å¦åå°±ä¸ç¨
ããjdbc _ stdext jar:
ããJDBC çæ©å±å ä¸è¬æ¥è¯´æ°æ®åºè¿æ¥æ± ä¼ç¨ä¸å® ä¸è¿App Serveré½ä¼å¸¦ä¸ æ以ä¹æ¯å¤ä½ç
ããjta jar
ããJTAè§è å½Hibernate使ç¨JTAçæ¶åéè¦ ä¸è¿App Serveré½ä¼å¸¦ä¸ æ以ä¹æ¯å¤ä½ç
ããjunit jar:
ããJunitå å½ä½ è¿è¡Hibernateèªå¸¦çæµè¯ä»£ç çæ¶åéè¦ å¦åå°±ä¸ç¨
ããxalan jar xerces jar xml apis jar:
lishixinzhi/Article/program/Java/ky//生产中BeanUtils为什么,不推荐使用
不推荐使用 BeanUtils 的主要理由包括性能问题和类型安全问题。内部曾遇到过使用 BeanUtils 进行属性拷贝时性能较差的情况。对比下,使用 Spring 的 BeanUtils 性能显著提升。然而,Spring 的 BeanUtils 在属性拷贝过程中可能存在类型转换问题。运行示例时会遇到类型转换异常,导致拷贝后的对象属性类型不正确。打断点检查后发现,即使未直接报错,类型问题依然存在。此问题在运行时才真正显现。
另一种情况是使用 CGlib 进行属性拷贝,同样会遇到类型转换不一致的问题。问题在运行时暴露,而非编译期,增加了调试难度。相比之下,MapStruct 可以成功将 A 类型的 List 转换为 B 类型的 List。编译生成的 Converter 实现类自动处理了类型转换,避免了运行时的类型错误。但这种自动转换也可能引入副作用,例如在属性类型不匹配时导致异常,如使用 MapStruct 处理非数字类型会导致 NumberFormatException,使用 CGlib 则可能将对应属性映射为 null。
另一个关键问题是 Java 泛型的特性。泛型在编译期检查类型,在运行时被擦除,导致编译期不易察觉的类型不一致问题。自定义转换类或使用 MapStruct 的注解处理器可以在编译阶段检查类型匹配性,避免运行时错误。但这种自动化转换可能导致代码难以阅读和理解,增加了维护成本。通过使用 IDEA 插件自动生成转换类,可以在编码阶段发现类型不匹配的问题,提升代码质量。
总结而言,虽然属性映射工具如 BeanUtils、MapStruct 和 CGlib 提供了方便的属性拷贝和转换功能,但由于性能问题、类型安全问题以及自动转换可能带来的副作用,推荐谨慎使用这些工具。对于属性类型不匹配的情况,建议自定义转换类,并利用 IDE 插件辅助生成转换代码,以提高代码的健壮性和可维护性。通过在编译阶段就能发现和解决类型问题,可以有效提升开发效率和应用质量。