您现在的位置是:首页 > 正文

Java分层领域模型的DO、DTO、DAO、BO、AO、VO、POJO、Query定义

2024-02-01 05:57:22阅读 3



 


分层领域模型:

DO( Data Object):					与数据库表结构一一对应,通过DAO层向上传输数据源对象。
DTO( Data Transfer Object):		数据传输对象,Service或Manager向外传输的对象。
DAO( Data Access Object):			数据访问对象,对于该数据库表、某个实体的增删改查。
BO( Business Object):				业务对象, 由Service层输出的封装业务逻辑的对象。
AO( Application Object):			应用对象,在Web层与Service层之间抽象的复用对象模型,极为贴近展示层,复用度不高。
VO( View Object):					显示层对象,通常是Web向模板渲染引擎层传输的对象。
Query:								数据查询对象,各层接收上层的查询请求。 注意超过2个参数的查询封装,禁止使用Map类来传输。

POJO( Plain Ordinary Java Object):简单的Java对象,专指只有setter/getter/toString的简单类,包括DO/DTO/BO/VO等。






  • 如下此项目工程结构内容为自己项目所用到,特此记录,如后用到其它再更新填写新内容!


整个工程分三部分结构如下:

wxa-admin
├── src
│     └── main
│         └── java
│             └── com.guyu.wxa
│        	    └── WxaApplication                 
│                  
├── src
│     └── main
│          └── resources
│               └── i18n
│               │      ├── messages.properties
│               │      └── validate.properties
│           	├── application.dev.yml
│               ├── application.prod.yml
│        	    ├── application.text.yml
│               ├── application.yml
│               ├── banner.txt
│               └── bootstrap.yml
│  
├── build.sh
├── Dockerfile        
└── pom.xml

com.guyu.wxa.business.rest
├── src
│     └── main
│         └── java
│             └── com.guyu.wxa.business.rest
│        	        ├── xxxRest
│                   ├── xxxRest
│                   └── xxxRest
│           
└── pom.xml

com.guyu.wxa.business.sm
├── src
│     └── main
│         └── java
│             └── com.guyu.wxa.business.sm
│                 │ 	
│       	  	  ├── dao
│                 │    ├── xxxDao
│                 │    ├── xxxDao
│                 │    └── xxxDao
│                 │ 	
│       	      ├── domain
│                 │    ├── xxxDO
│                 │    ├── xxxDO
│                 │    └── xxxDO
│                 │ 	
│       	      ├── dto
│                 │    ├── xxx
│                 │    │    ├── xxxQueryDto
│                 │    │    ├── xxxResultDto
│                 │    │    └── xxxxDto
│                 │    │
│                 │    ├── xxx
│                 │    │    ├── xxxQueryDto
│                 │    │    ├── xxxResultDto
│                 │    │    └── xxxxDto
│                 │    │
│                 │    └── xxx
│                 │        ├── xxxQueryDto
│                 │        ├── xxxResultDto
│                 │        └── xxxxDto
│                 │    
│       	      ├── service
│                 │    ├── impl
│                 │    │   ├── xxxServiceImlp
│                 │    │   ├── xxxServiceImlp
│                 │    │   └── xxxServiceImlp
│                 │    │ 	
│                 │    ├── xxxService
│                 │    ├── xxxService
│                 │    └── xxxService
│                 │    
│       	      ├── util
│                 │    ├── CommonUtil
│                 │    ├── Md5Util
│                 │    └── xxxxUtil
│                 │    
│                 └── xxx
│  
├── src
│     └── main
│          └── resources
│               └── mapper
│        	        ├── xxxMapper.xml
│                   ├── xxxMapper.xml
│                   └── xxxMapper.xml
│           
└── pom.xml



领域模型命名及格式:

1、数据对象:xxxDO,xxx即为数据表名。

    	@Table(name = "t_ps_app")
		public class AppDO extends BaseDO{
		
			private static final long serialVersionUID = 1L;
			
			@ApiModelProperty(value = "rs id")
			private Integer rsId;
							...
		 }

2、数据传输对象:xxxDTO,xxx为业务领域相关的名称。

		2-1、数据查询对象:xxxQueryDTO,xxx为该数据表名和分页等。
		
		public class AppPageQueryDto extends BaseQueryDto{
		
			@ApiModelProperty(value = "设备id(必传)", required = true)
		    @NotNull(message = "VLD.global.deviceId")
		    private Integer deviceId;
			...
		}



		2-2、数据查询结果对象:xxxResultDTO,xxx为该数据表名和分页等。
		
		public class AppPageResultDto {
		
			@ApiModelProperty(value = "id")
			private Integer id;
					...
		}

3、数据访问对象:xxxDAO,xxx即为数据库表名。
			
		public interface AppDao extends BaseDAO<AppDO>{

		   List<AppPageResultDto> page(@Param("queryDto") AppPageQueryDto dto);
					...
		}

4、服务层:xxxService,xxx即为数据库表名。

		public interface AppService extends IConstants {

		  PageInfo<AppPageResultDto> page(Integer pageNum, Integer pageSize, AppPageQueryDto dto);
  						...
		}

5、实现服务层:xxxServiceImpl,xxx即为数据库表名。

		@Service
		@Transactional
		@Slf4j
		public class AppServiceImpl implements AppService {
			
			@Autowired
			private AppWhiteListService appWhiteListService;
			
			@Autowired
			private AppDao appDao;
		
			@Override
			public PageInfo<AppPageResultDto> page(Integer pageNum, Integer pageSize, AppPageQueryDto dto) {
				log.info("AppServiceImpl.page()");
				PageHelper.startPage(pageNum, pageSize);
				if (2 == dto.getPushStatus()) {
					dto.setName(null);
					dto.setCategoryId(null);
				}
				if (0 == dto.getPushStatus()) {
					if (1 == dto.getSearchType()) {
						dto.setName(null);
					}else {
						dto.setCategoryId(null);
					}
				}
				List<AppPageResultDto> list = appDao.page(dto);
				PageInfo<AppPageResultDto> pageInfo = new PageInfo<AppPageResultDto>(list);
				return pageInfo;
			}
      						...
		}

6、控制层:xxxRest,xxx即为数据库表名。
	
		@Api( value= "关于应用的接口",tags={ "应用" })
		@RestController
		@RequestMapping({ "/bus/app" })
		@Slf4j
		public class AppRest extends BaseRest{
		
		    @Autowired
		    private AppService appService;
		    
		    @ApiOperation(value = "分页查询", notes = "分页查询")
		    @PostMapping("/page")
		    public ResultVO<PageInfo<AppPageResultDto>> page(
		    		@RequestParam(value = "pageNum", required = true, defaultValue = "1")  Integer pageNum,
		            @RequestParam(value = "pageSize", required = true, defaultValue = "10") Integer pageSize,
		            @Valid @RequestBody AppPageQueryDto dto) {
		        log.info("应用 -> 分页查询");
		        dto.setRsId(getRsId());
		        return ResultVO.ok(appService.page(pageNum,pageSize, dto));
		    }
  						...
		}

7、动态SQL映射:xxxMapper.xml,xxx即为数据库表名。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.guyu.wxa.business.sm.dao.AppDao" >

	<!-- 分页查询 -->
	<select id="page" parameterType="com.guyu.wxa.business.sm.dto.app.AppPageQueryDto" resultType="com.guyu.wxa.business.sm.dto.app.AppPageResultDto">
		SELECT 
			a.id,
			a.name,
			a.package_name AS 'packageName',
			a.apk_url AS 'apkUrl',
			a.icon_url AS 'iconUrl',
			convert(a.file_size/(1024*1024),decimal(10,2)) AS 'fileSize',
			IFNULL(ap.push_status, 0) AS 'pushStatus',
			a.push_times AS 'pushTimes',
			a.version,
			a.version_name AS 'versionName',
			IFNULL(aut.`status`, 0) AS 'status',
			IFNULL(aut.start_time, '12:00:00') AS 'startTime',
			IFNULL(aut.end_time, '13:00:00') AS 'endTime'
		FROM
			t_ps_app a
		LEFT JOIN
			t_ps_app_push ap
		ON
			ap.app_id = a.id
		AND
			ap.device_id = #{queryDto.deviceId}
		LEFT JOIN
			t_ps_app_use_time aut
		ON
			aut.app_id = a.id
		AND
			aut.device_id = #{queryDto.deviceId}
		WHERE
			a.del_flag = 1
		AND
			a.publish_status = 1
		<if test="null!=queryDto.categoryId and 0!=queryDto.categoryId">
        AND
            a.category_id = #{queryDto.categoryId}
      	</if>
		<if test="null!=queryDto.pushStatus and 0!=queryDto.pushStatus">
		AND
		    ap.push_status = #{queryDto.pushStatus}
		</if>
		<if test="null!=queryDto.name and ''!=queryDto.name">
		AND
		   	a.name
	    LIKE CONCAT
	    	('%','${queryDto.name}','%')
		</if>
		GROUP BY
			a.id
		ORDER BY
			a.list_index DESC,
			a.create_date DESC
    </select>
    				...
</mapper>	

  • 注在写 xxxMapper.xml:
    - 查询 SELECT … 字段是对应 xxxResultDto中;
    - <if test … 字段是对应 xxxQueryDto中,只要该字段为 String 类型时要写 LIKE CONCAT;

8、展示对象:xxxVO,xxx一般为网页名称。

9、POJO是DO/DTO/BO/VO的统称,禁止命名成xxxPOJO。


它们之间的关系:
Service层是建立在DAO层之上的,建立了DAO层后才可以建立Service层,而Service层又是在Controller层之下的,因而Service层应该既调用DAO层的接口,又要提供接口给Controller层的类来进行调用,它刚好处于一个中间层的位置。每个模型都有一个Service接口,每个接口分别封装各自的业务处理方法。

举个例子:
Controller像是服务员,顾客点什么菜,菜上给几号桌,都是ta的职责;
Service是厨师,action送来的菜单上的菜全是ta做的;
Dao是厨房的小工,和原材料打交道的事情全是ta管。
相互关系是,小工(dao)的工作是要满足厨师(service)的要求,厨师要满足服务员(controller)转达的客户(view)的要求,服务员自然就是为客户服务喽。






POJO真正的意义:

POJO - [“Plain Old Java Object”] , 即简单的Java对象,是MartinFowler等发明的一个术语,用来表示普通的Java对象,不是JavaBean, EntityBean 或者 SessionBean。POJO不担当任何特殊的角色,也不实现任何特殊的Java框架的接口如 EJB,JDBC等等。
即POJO是一个简单的普通的Java对象,它不包含业务逻辑或持久逻辑等,但不是JavaBean、EntityBean等,不具有任何特殊角色和不继承或不实现任何其它Java框架的类或接口。


  • 摘自Martin Fowler个人网站的一句话:
    “We wondered why people were so against using regular objects in their systems and concluded that it was because simple objects lacked a fancy name.
    So we gave them one, and it’s caught on very nicely.”

    我们疑惑为什么人们不喜欢在他们的系统中使用普通的对象,我们得到的结论是——普通的对象缺少一个响亮的名字,因此我们给它们起了一个,并且取得了很好的效果。







Note:
欢迎点赞,留言,转载请在文章页面明显位置给出原文链接
知者,感谢您在茫茫人海中阅读了我的文章
没有个性 哪来的签名!
详情请关注点我
持续更新中

© 2020 08 - Guyu.com | 【版权所有 侵权必究】

网站文章

  • FreeRtos源码分析之任务切换原理(四)

    FreeRtos源码分析之任务切换原理(四)

    一、CortexM3中断优先级CortexM3支持多达240个外部中断和16个内部中断,每一个中断都对应一个中断都对应一个优先级寄存器。每一个优先级寄存器占用8位,STM32采用其中的高四位来表示优先...

    2024-02-01 05:57:16
  • 路由守卫大全

    路由守卫是一个路由的访问机制,如果允许访问就放行,不允许访问就不放行,可以通过 router.beforeEach() 方法来实现对应的操作。

    2024-02-01 05:57:09
  • html如何修改span的值,如何动态改变div span的内容

    本文介绍了javascript动态改变div span的内容的教程,希望能帮助到大家先看一个实例对span的控制与div类似,但是它是按照行来显示的,看下面的代码:function chagespan...

    2024-02-01 05:56:39
  • Microsoft Word 教程:如何在 Word 中插入图片、图标?

    Microsoft Word 教程:如何在 Word 中插入图片、图标?

    欢迎观看 Microsoft Word 教程,小编带大家学习 Microsoft Word 的使用技巧,了解如何在 Word 中插入图片、图标。

    2024-02-01 05:56:31
  • 使用 Java Native Interface 的最佳实践

    使用 Java Native Interface 的最佳实践

    2019独角兽企业重金招聘Python工程师标准>>> ...

    2024-02-01 05:56:23
  • vue 水印添加

    vue 水印添加

    vue 页面添加水印

    2024-02-01 05:55:55
  • 用计算机算标准曲线,标准曲线计算软件

    用计算机算标准曲线,标准曲线计算软件

    标准曲线计算器电脑版是一款可计算标准曲线的电脑计算器软件。计算过标准曲线的用户都应该知道标准曲线的计算挺麻烦的,而且计算结果要非常的精准才可以。本软件已经设置好了公式,您只要往里面添加数据就可以得出标...

    2024-02-01 05:55:46
  • Java求geometry的面积最小外接矩形

    Java求geometry的面积最小外接矩形

    Java求geometry的面积最小外接矩形 geom.getEnvelope() 得到外接矩形,不一定是面积最小;可以对多边形的每一条边求外接矩形,然后比较得到面积最小外接矩形。这篇博客将分为3步进...

    2024-02-01 05:55:39
  • 常见的Web应用攻击手段

    常见的Web应用攻击手段 1.XSS攻击 XSS攻击即跨站点脚本攻击(Cross Site Script),指黑客通过篡改网页,注入恶意HTML脚本,在用户浏览网页时,控制用户浏览器进行恶意操作的一种...

    2024-02-01 05:55:09
  • unity 检测物体是否在相机视野范围内

    脚本挂在摄像机要显示的对象上前提:该对象有 render 组件public class visibleTT : MonoBehaviour{ public bool isRendering = false; public float lastTime = 0; public float curTime = 0; void Update() {

    2024-02-01 05:55:03