- 使用 Spring Initializr 创建 Spring Boot 应用程序
- 在Spring Boot中配置Cassandra
- 在 Spring Boot 上配置 Tomcat 连接池
- 将Camel消息路由到嵌入WildFly的Artemis上
POJO 的定义是无规则简单的对象,在日常的代码分层中 pojo 会被分为VO、BO、 PO、 DTO
VO (view object/value object)表示层对象
1、前端展示的数据,在接口数据返回给前端的时候需要转成VO
2、个人理解使用场景,接口层服务中,将DTO转成VO,返回给前台
B0(bussines object)业务层对象
1、主要在服务内部使用的业务对象
2、可以包含多个对象,可以用于对象的聚合操作
3、个人理解使用场景,在服务层服务中,由DTO转成BO然后进行业务处理后,转成DTO返回到接口层
PO(persistent object)持久对象
1、出现位置为数据库数据,用来存储数据库提取的数据
2、只存储数据,不包含数据操作
3、个人理解使用场景,在数据库层中,获取的数据库数据存储到PO中,然后转为DTO返回到服务层中
DTO(Data Transfer Object)数据传输对象
1、在服务间的调用中,传输的数据对象
2、个人理解,DTO是可以存在于各层服务中(接口、服务、数据库等等)服务间的交互使用DTO来解耦
DO(domain object)领域实体对象
DO 现在主要有两个版本:
①阿里巴巴的开发手册中的定义,DO( Data Object)这个等同于上面的PO
②DDD(Domain-Driven Design)领域驱动设计中,DO(Domain Object)这个等同于上面的BO
参考文档:
https://juejin.cn/post/6952848675924082718
https://juejin.cn/post/6844904046097072141
https://zhuanlan.zhihu.com/p/264675395
插件名称:Simple Object Copy
定义方法出入参
光标定位方法内,使用快捷键ALT+INSERT(WIN) 、 command + N(mac) ,或者右键鼠标选择Generate,弹出生成选项框后,选择genCopyMethod,代码就生成好了
需要手写的代码
一键生成后的展示
复杂对象转化展示(一键生成后的展示)
复杂对象转化源码示例:
@Data
public class UserVO {
private String name;
private Date entryDate;
private String userId;
private List<RoleVO> roleList;
private RoomVO room;
public static UserVO convertToUserVO(UserDTO item) {
if (item == null) {
return null;
}
UserVO result = new UserVO();
result.setName(item.getName());
result.setEntryDate(item.getEntryDate());
result.setUserId(item.getUserId());
List<RoleDTO> roleList = item.getRoleList();
if (roleList == null) {
result.setRoleList(null);
} else {
result.setRoleList(roleList.stream().map(UserVO::convertToRoleVO).collect(Collectors.toList());
}
result.setRoom(convertToRoomVO(item.getRoom()));
return result;
}
public static RoomVO convertToRoomVO(RoomDTO item) {
if (item == null) {
return null;
}
RoomVO result = new RoomVO();
result.setRoomId(item.getRoomId());
result.setBuildingId(item.getBuildingId());
result.setRoomName();
result.setBuildingName();
return result;
}
public static RoleVO convertToRoleVO(RoleDTO item) {
if (item == null) {
return null;
}
RoleVO result = new RoleVO();
result.setRoleId(item.getRoleId());
result.setRoleName(item.getRoleName());
result.setCreateTime(item.getCreateTime());
return result;
}
}
@Data
public class UserDTO {
private String name;
private Date entryDate;
private String userId;
private List<RoleDTO> roleList;
private RoomDTO room;
}
@Data
public class RoleVO {
private String roleId;
private String roleName;
private LocalDateTime createTime;
}
@Data
public class RoleDTO {
private String roleId;
private String roleName;
private LocalDateTime createTime;
}
@Data
public class RoomVO {
private String roomId;
private String buildingId;
private String roomName;
private String buildingName;
}
@Data
public class RoomDTO {
private String roomId;
private String buildingId;
}
1.无入侵市面上有很多类似的工具类,比较常用的有
1、Spring BeanUtils (copyProperties)
2、Cglib BeanCopier (copyProperties)
3、Apache BeanUtils (copyProperties)
4、Apache PropertyUtils (copyProperties)
5、Dozer
6、mapstruct
7、JSON 序列化 再反序列化
这些工具,不仅要引入相应的依赖jar包,而且对代码有入侵,要调用对应得api方法才能进行转化,一旦遇到类型不一致,字段名稍有变动,就需要另写java代码补全字段,整体代码非常丑陋。
举例:
同样的代码,,不仅要引入依赖、写如下转化mapper,还要,在对应地方调用对应api(代码入侵验证),然而Simple Object Copy 只需要一键生成。
RoomDTO中不存在的roomName、buildingName还要mapstruct另写方法,很容易忽略。源实体中不存在的属性,没有提示,小心前端总是问为啥都是null。
在Simple Object Copy 插件代码生成后,不存在的字段也生成了空方法,直接编译提示补充,不容易忽略
需要手写的代码:
@Mapper(componentModel = "spring",uses = {RoleVOMapper.class,RoomVOMapper.class})
public interface UserMapper {
UserConverter INSTANCE = Mappers.getMapper(UserConverter.class);
UserVO toUserVO(UserDTO userDTO);
}
@Mapper(componentModel = "spring")
public interface RoleMapper {
RoleVO toRoleVO(RoleDTO roleDTO);
}
@Mapper(componentModel = "spring")
public interface RoomMapper {
RoomVO toRoomVO(RoomDTO roomDTO);
}
public class Main {
public static void main(String[] args) {
UserDTO user = ;
UserVO userVO = UserMapper.INSTANCE.toUserVO(user);
userVO.getRoomVO().setRoomName("大厅1");
userVO.getRoomVO().setBuildingName("尚德楼");
}
}
1. BeanUtils
性能稍差。
不支持复杂对象还是要写大量代码,代码字段不清晰不易理解,别人接手难。RoomDTO中不存在的roomName、buildingName还要BeanUtils另写方法,很容易忽略。源实体中不存在的属性,没有提示,小心前端总是问为啥都是null。
需要手写的代码
@Data
public class UserVO {
private String name;
private Date entryDate;
private String userId;
private List<RoleVO> roleList;
private RoomVO room;
public static UserVO convertToUserVO(UserDTO item) {
if (item == null) {
return null;
}
UserVO result = new UserVO();
BeanUtils.copyProperties(item,result);
List<RoleDTO> roleList = item.getRoleList();
if (roleList == null) {
result.setRoleList(null);
} else {
result.setRoleList(roleList.stream().map(UserVO::convertToRoleVO).collect(Collectors.toList());
}
result.setRoom(convertToRoomVO(item.getRoom()));
return result;
}
public static RoomVO convertToRoomVO(RoomDTO item) {
if (item == null) {
return null;
}
RoomVO result = new RoomVO();
BeanUtils.copyProperties(item,result);
result.setRoomName();
result.setBuildingName();
return result;
}
public static RoleVO convertToRoleVO(RoleDTO item) {
if (item == null) {
return null;
}
RoleVO result = new RoleVO();
BeanUtils.copyProperties(item,result);
return result;
}
}
2.性能优势
相比上面的工具类,不是使用反射、就是是用代理、序列化操作。相比于纯正的set方法去转化,差距不是一个量级。此次不赘述。
3.灵活性、兼容性
跟上述工具类相比插件有很大优势,不再赘述,下面我们比较一下,我之前常用的idea插件generateO2O
在此推荐其他一个我常用插件:generateAllSetter,搭配食用更佳,
4. 如何下载?
打开idea plugins,切market place 搜索:Simple Object Copy
推荐3个原创springboot+Vue项目,有完整视频讲解与文档和源码:
关注我,学Java
在使用 LLDB 研究调试异常时,我发现了以下文章和线程,以及其他提供相同信息的文章: https://www.natashatherobot.com/xcode-debugging-trick/ X
我在我的 asp.net 核心应用程序中使用了 Orchard Localization。 Startup.cs services.AddPortableObjectLocalization(opti
我有一个正在积极开发中的 python 程序,它使用 gettext 进行翻译。 我有一个带有翻译的 .POT 文件,但它有点过时了。我有一个脚本来生成最新的 .PO 文件。有没有办法检查 .POT
我在项目中使用 Poedit 进行本地化。每当我用 poedit 更改条目时,它都会重新排序所有元素。我认为它根据行号和文件对元素重新排序,但由于我在这个项目中与许多编码人员一起工作,poedit 不
看起来 django 不想创建/更新 .po我的项目的文件(或者 django 不知道我正在使用任何其他语言)。 # mkdir locale # python manage.py makemessa
我几乎觉得问这个很愚蠢,但是......那里有任何好的示例 .po 文件吗?我一直在阅读 GNU gettext 手册,虽然它指定了一般结构,但并没有像我想要的那样详细。另外,我真的很想要一个实际充实
我想从 PO 文件中删除所有已翻译的字符串,或者生成一个仅包含未翻译字符串的 PO 文件。 那可能吗? 最佳答案 我找到了方法: msgattrib --untranslated source.po
我正在使用一套 .po由公司翻译系统生成的文件(使用 Pootle,如果相关)。我无法将这些文件转换为 .mo (与 .po 文件对应的二进制文件)使用 msgfmt实用程序(使用 -C 运算符,检查
我想在 gettext .po 文件中以某种方式使用变量,例如: msgid "ui_settings_connect_text" msgstr "Connect to another running
有谁知道从 PO 文件中批量删除所有模糊翻译的方法。就像是: if#,fuzzy == TRUE Then SET msgstr=""AND REMOVE #,fuzzy 最佳答案 如果安装了 get
我正在使用 .po 和 .mo 文件来翻译我的网站。我的问题是,是否可以将参数传递到 .po translation file 中的翻译句子中? ? 例如:en -> 嗨,我叫莎拉,我是个酒鬼我想用两
我们有两个 .po 文件,每个文件来自一个软件的不同分支。 我们需要将这些组合成一个 .po 文件。 两个文件之间存在重复项,理想的处理方式是让一个文件的字符串受到青睐(一致)。 我们有一个 SUSE
我有一个 .po 文件,其中大多数翻译的字符串与原始字符串相同。然而,很少有不同的。如何快速找到与原版不同的内容? 最佳答案 使用podiff 我用过它,它对我有用。它是C语言的,所以你必须编译它。
已关闭。此问题不符合Stack Overflow guidelines 。目前不接受答案。 要求我们推荐或查找书籍、工具、软件库、教程或其他场外资源的问题对于 Stack Overflow 来说是偏离
在 Django 中运行 django-admin.py makemessages -l de 创建翻译文件后,您可以使用纯文本编辑器或 Poedit 来填写它们。 Poedit 的优势在于它提供了专
我无法在文档中找到,但我不知道如何翻译包含可变内容的短语。 我的 Django View 中有以下短语: apple_count = 100 a = _('I have %d apples' %
我有一个下面的正则表达式,如果它找到 PO Box office 组合则返回 true \b[P|p]*(OST|ost)*\.*\s*[O|o|0]*(ffice|FFICE)*\.*\s*[B|b
我有一个这样声明的变量: @property (nonatomic, retain) NSMutableArray *aInfo; 一开始,如果我这样声明变量: self.aInfo = [[NSMu
我一直在调试我的代码,发现我的管理器被取消初始化(这是我的错误的原因 - 没有调用委托(delegate)方法)。 奇怪的是,在调试过程中,我在设置管理器的委托(delegate)(弱)后使用了“po
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 要求我们推荐或查找工具、库或最喜欢的场外资源的问题对于 Stack Overflow 来说是偏离主题的,
我是一名优秀的程序员,十分优秀!