分层领域模型:
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 | 【版权所有 侵权必究】 |