`
步青龙
  • 浏览: 298169 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
博客专栏
72ba33fb-eefe-3de1-bd65-82a6e579265d
Java面试
浏览量:0
社区版块
存档分类
最新评论

DTO和POJO纠结

 
阅读更多

DTO:数据传输对象

好处,给被调用方包装数据,有些数据你希望开发者可以看到的数据,可控数据,总结为数据隐藏和数据封装

比如做AA模块的只可以看到那些,而且bean的属性甚至可以与ORM中的对象不同名称(一般都是相同的),AA前台模块只可以看到要查询的数据,不会把不该看到的数据提供过去,如审核人,审核内容等。对于后台管理模块可以看到,这样的DTO的作用就可以明显看到了。另外如果一个table要显示数据很复杂,可能来自不同的Hessian调用,这样DTO 可以满足需求,DTO可以给开发提供比普通Bean更多的数据,同时DTO也可以对开发者隐藏数据。

DTO的不好,先看:

原文链接是  http://www.iteye.com/topic/1013803

我也纠结DTO和POJO之间的转换。服务端是纯粹的做数据调用服务,从客户端项目请求,到服务端项目接受请求并操作,但是在服务端项目中remoting service层传递过来的是DTO对象,而要保存的是POJO对象。

DTO和POJO唯一的区别是类型不一样,DTO是序列化的,而POJO不是。这样转换有几个地方我觉得不可忍的:第一要写很多的转换代码,第二要生成很多的对象,第三如果表结构变了,POJO,DTO和转换的代码都得进行修改。多N的对象可以不考虑,性能可以不考虑,作为开发,不想麻烦,set一大堆,如果表结构中N多的属性那何时了,虽然有现成的工具可用,像BeanUtil,但是加上这个东西,又对性能是一个挑战。

Martin Flower和Spring作者对次有相反的看法。真的没好的办法解决这个问题吗?

在每个Remoting Service中写这样的代码不是很蛋疼吗? 

 

	public XXX  dtoToDomain(XXXDto xdto){
		XXX  x= new XXX  ();
		x.setId(xdto.getId()); 
		// 等等
		return x;
	}

  然后还有对客户端提供数据的时候还要domainToDto操作。 

 

	
	static String dtoPath = "com.xxx.remoting.dto.AADto";
	static String domainPath = "com.xxx.domain.AA";
	
	public static void main(String[] args) {
		try {
			String[] dtoNames = dtoPath.split("\\.");
			String dtoName = dtoNames[dtoNames.length - 1];			
			String smallDtoName = toHeadLow(dtoName);
			
			String[] damainNames = domainPath.split("\\.");
			String domainName = damainNames[damainNames.length - 1];			
			String smallDamainName = toHeadLow(domainName);		
			
			Class dtoClass = Class.forName(dtoPath);
	
			
			
			/**
			 * dto转domain
			 * @param memberAddressDto
			 * @return
			 */
			
			System.out.printf("/**\r\n");
			System.out.printf(" * dto转domain\r\n");
			System.out.printf(" * @param " + smallDtoName +"\r\n");
			System.out.printf(" * @return\r\n");
			System.out.printf("*/\r\n");
			
			System.out.printf("public " + domainName + " " + smallDtoName +  "To" + domainName + "(" + dtoName + " " +  smallDtoName + ") {\r\n");
			System.out.printf("\tif (" + smallDtoName + " == null)\r\n");
			System.out.printf("\t\treturn null;\r\n");
			System.out.printf( "\t" + domainName + " " + smallDamainName + " = new " + domainName + "();\r\n");		
			for (Method method : dtoClass.getMethods()) {
				String name = method.getName();	
				if (name.equals("getClass"))
					continue;
				if (name.startsWith("get")) {
					String property = name.substring(3);
					System.out.printf("\t" + smallDamainName + ".set" + property + "(" + smallDtoName + "." + name + "());\r\n");
				}
			}	
			System.out.printf("\treturn " + smallDamainName + ";\r\n");
			System.out.printf("} \r\n\r\n");
			
			
			System.out.printf("/**\r\n");
			System.out.printf(" * domain转dto\r\n");
			System.out.printf(" * @param " + smallDamainName +"\r\n");
			System.out.printf(" * @return\r\n");
			System.out.printf("*/\r\n");
			System.out.printf("public " + dtoName + " " + smallDamainName +  "To" + dtoName + "(" + domainName + " " +  smallDamainName + ") {\r\n");
			System.out.printf("\tif (" + smallDamainName + " == null)\r\n");
			System.out.printf("\t\treturn null;\r\n");
			System.out.printf("\t" + dtoName + " " + smallDtoName + " = new " + dtoName + "();\r\n");
			for (Method method : dtoClass.getMethods()) {
				String name = method.getName();		
				if (name.equals("getClass"))
					continue;
				if (name.startsWith("get")) {
					String property = name.substring(3);
					System.out.printf("\t" + smallDtoName + ".set" + property + "(" + smallDamainName + "." + name + "());\r\n");
				}
			}
			System.out.printf("\treturn " + smallDtoName + ";\r\n");
			System.out.printf("} \r\n");
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	
	public static String toHeadLow(String data) {
		return String.valueOf(Character.toLowerCase(data.charAt(0))) + data.substring(1);
	}
 

 

我的想法是让POJO实现序列化,这样就没必要用POJO对象了 直接保存DTO对象。对象转换也不需要了。

 

为了接着这样一个频繁的操作我们可以自己写一个类路劲做为参数通过反射机制,生成这些代码。

 

今天遇到一个诧异的问题,客户端项目的DTO传递到服务端项目的时候就Decimal类型的的属性值都变为了0了,郁闷我!

问题在BigDecimal类型的应该使用BigDecimalDeserializer,
在basic没有BigDecimal的deserializer,需要使用customer根据类名查找
public Deserializer getCustomDeserializer(Class cl)
Class serClass = Class.forName(cl.getName() + "HessianDeserializer",
                                       false, cl.getClassLoader());

结果类名错误拼错导致找不到相应的反序列化类

我准备在公共项目中的DTO的BigDecimal中改为String类型,到了服务端就进行类型转换,这样就解决问题了,但是是投机取巧,不可取。

这是hessian的一个bug,解决此bug的方法:

 在 hessian.jar 的 META-INF/hessian 目录下加入 serializers 和 deserializers 这两个文件,  两个文件的内容如下:

serializers

--------------------------

java.math.BigDecimal=com.caucho.hessian.io.StringValueSerializer

 

deserializers

--------------------------

java.math.BigDecimal=com.caucho.hessian.io.BigDecimalDeserializer

 

解决办法原文链接 (原文把引用的序列化和反序列化写反了)


 

分享到:
评论

相关推荐

    eclipse插件,根据数据库表自动生成DTO(pojo)插件

    在Java开发中,数据传输对象(DTO)和持久化对象(POJO)是常见的概念,它们用于在不同层之间传递数据。手动创建这些类可能会耗费大量时间,特别是在处理大量数据库表时。因此,"eclipse插件,根据数据库表自动生成...

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    Java中 PO VO BO DTO DAO 和 POJO 关系图

    java Pojo转Map

    总的来说,Java的Pojo到Map的转换是提高代码可读性和灵活性的有效手段,尤其是在JSP页面数据绑定时。通过利用反射API,我们可以轻松地实现这一转换,从而简化编程工作。当然,使用这种方式时要注意性能影响,因为...

    java术语(PO/POJO/VO/BO/DAO/DTO)

    本文将详细解析"PO/POJO/VO/BO/DAO/DTO"这六个概念,并探讨它们在实际项目开发中的作用和应用场景。 1. PO(Persistent Object,持久化对象) PO是指与数据库表结构一一对应的Java对象,它通常包含了数据库表中的...

    java实现相同属性名称及相似类型的pojo、dto、vo等互转操作

    Java 实现相同属性名称及相似类型的 POJO、DTO、VO 等互转操作 Java 实现相同属性名称及相似类型的 POJO、DTO、VO 等互转...使用反射机制和类型判断,我们可以实现 POJO、DTO、VO 等之间的转换,并在实际项目中应用。

    Generate POJO-JPA-Swagger-DTO.groovy

    Generate POJO-JPA-Swagger-DTO

    JAVA中的POJO、VO、PO、DO、DTO都是什么?有什么区别?

    以下是关于POJO、VO、PO、DO、DTO的详细解释及其区别。 1. POJO(Plain Old Java Object):POJO是一个通用术语,指没有特定框架限制的简单Java对象。它通常包含了业务逻辑和数据属性,不包含任何特定框架的注解或...

    SSM项目实战pojo类

    8. **数据传输对象(DTO)和值对象(VO)**:在某些情况下,POJO类会被转换成DTO或VO,以便在不同的系统之间安全地传递数据。DTO和VO通常包含了对外界暴露的数据,但可能不包含所有POJO的属性,以保护内部数据的安全...

    快速生成DTO

    在Java中,DTO通常是一个简单的POJO(Plain Old Java Object),包含属性、getter和setter方法。 4. **工具使用**: "buildDTO"可能是生成DTO的命令或者工具名称,它可能包含了解析Excel模板并自动生成Java代码的...

    VO / DTO / BO / ORM DAO entity DO PO/ POJO(分层领域模型规约)整理

    通过对VO、DTO、BO、ORM、DAO、Entity、DO、PO 和 POJO 的深入分析,我们可以看出这些概念在不同的层次和场景下发挥着各自的作用。正确地使用这些模型能够帮助开发者更好地组织代码,提高系统的可维护性和扩展性。在...

    数据库表转实体类和DTO

    数据库表转实体类和DTO是软件开发中一个常见的任务,特别是在Java后端开发中,它涉及到数据模型的设计和数据访问层的操作。实体类(Entity Class)通常代表数据库中的表,而DTO(Data Transfer Object)则用于在不同...

    Java Web开发 之VO、PO、DTO等收集

    J2EE开发人员必须知道 Java Web开发中VO、PO、DTO、POJO代表含义。

    POJO javaBean EJB JNDI 理解及区别

    与POJO和JavaBean不同,EJB不仅是一种编码规范,更是一套完整的运行时环境,提供了容器管理的持久性、事务处理、安全性和远程访问等功能。EJB主要有三种类型:会话Bean、实体Bean和消息驱动Bean,分别用于业务逻辑...

    java 使用 JAXB 将xml转换为 bean 包含xml和dto和读取文件的util类

    总结来说,这个压缩包提供的内容涉及了Java中使用JAXB进行XML与Java对象之间转换的实际应用,以及辅助的DTO和文件读取工具。这些对于理解和实现XML数据处理的Java应用非常有帮助。开发者可以通过学习和使用这些示例...

    分页dto把html写在dto里

    标题“分页dto把html写在dto里”和描述“把分页按钮写在dto里,其他dto继承他”表明了一个特殊的实践,即将HTML代码直接包含在DTO对象中,以便于处理分页功能,并且其他DTO可能通过继承这个特殊的DTO来共享相同的...

    mybatis 生成 pojo mapper dao 的工具包

    mybatis 生成 pojo mapper dao 的工具包

    使用AutoMapper实现Dto和Model的自由转换(下)

    在本篇中,我们将深入探讨如何使用AutoMapper库在.NET应用程序中实现Data Transfer Objects (Dto)与业务模型之间的自由转换。AutoMapper是一个流行的开源库,它简化了对象之间的映射过程,大大减少了手动编写转换...

    Javabean与DTO的区别.docx

    总结一下,JavaBean、DTO、POJO和PO各有其特定的用途: - JavaBean主要用于封装业务逻辑和数据,方便在JSP中使用,同时也适用于代码复用。 - DTO专注于数据传输,不包含业务逻辑,常用于系统间的数据交换。 - POJO是...

    Any2Dto插件,可以根据数据库和JavaCode生成强类型且精确字段的DTO

    这个插件专为IntelliJ IDEA用户设计,能够根据数据库结构和已有的Java代码自动生成强类型的DTO类,从而提高开发效率和代码质量。 首先,让我们深入了解DTO的概念。DTO是一种设计模式,主要用于隔离数据的表示层和...

Global site tag (gtag.js) - Google Analytics