SpringBoot实体类——VO/DTO/PO简单总结
创始人
2024-06-02 18:28:06

目录

1.概念叙述

2.类型转换

3.使用实例


1.概念叙述

VO:View Object,主要用于展示层。它的作用是把某个指定前端页面的所有数据封装起来。他的作用主要是减少传输数据量大小和保护数据库隐私数据(如用户密码、用户邮箱等相关信息)不外泄,同时保护数据库的结构不外泄。

DTO:Data Transfer Object,数据传输对象,用于展示层与服务层之间的数据传输对象。(注:实际开发中还存在BO,其作用和DTO类似,当业务逻辑不复杂时一般会被合并。)

PO:Persistant Object,持久化对象,和数据库形成映射关系。简单说PO就是每一个数据库中的数据表,一个字段对应PO中的一个变量。(也就是我们常用的Entities)

几者之间的关系如下图:

从前端页面中收到JSON格式数据,后端接口中将其封装为一个VO对象;接口接收到VO对象后将其转换为DTO对象,并调用业务类方法对其进行处理;然后处理为PO对象,调用Dao接口连接数据库进行数据访问(查询、插入、更新等)。

后端从数据库得到结果后,根据Dao接口将结果映射为PO对象,然后调用业务类方法将其转换为需要的DTO对象,再根据前端页面实际需求,转换为VO对象进行返回。

2.类型转换

上述过程中,VO/DTO/PO等实体类中字段常常会存在多数相同,根据业务需求少数不同。为避免频繁的set和get操作对其进行转换,spring为我们提供了多种方法。

(1)使用BeanUtils:(springframework包下)

UserDto user = new UserDto ();
BeanUtils.copyProperties(userInfo ,user ,new String[]{"birthday"});

上述代码中,意思是将左边UserInfo实体类(可以视为一个VO对象)和UserDto实体类类(可以视为一个DTO对象)中一样的值进行赋值user对象中,new String[]{""}中是跳过赋值的字段,该属性可以为空。

(2)使用BeanUtils:(Apache包下)

UserDto user = new UserDto ();
BeanUtils.copyProperties(user,userInfo);

上述代码中,意思是将右边UserInfo实体类(可以视为一个VO对象)和UserDto实体类类(可以视为一个DTO对象)中一样的值进行赋值user对象中。(和spring包下方法相反)

(3)使用modelMapper:

导入依赖:

        org.modelmappermodelmapper2.3.9

配置文件:

@Configuration
public class ModelMapperConfig {private Converter dateToStringConverter = new AbstractConverter() {@Overrideprotected String convert(Date date) {SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");return date == null ? null : simpleDateFormat.format(date);}};@Beanpublic ModelMapper modelMapper() {ModelMapper modelMapper = new ModelMapper();// 官方配置说明: http://modelmapper.org/user-manual/configuration/// 完全匹配modelMapper.getConfiguration().setFullTypeMatchingRequired(true);// 匹配策略使用严格模式modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);modelMapper.addConverter(dateToStringConverter);configureUser(modelMapper);return modelMapper;}private void configureUser(ModelMapper modelMapper) {//将dto转为UserAccount实体类modelMapper.typeMap(UserInfor.class, UserAccount.class).addMappings(mapper -> mapper.map(UserInfor::getUsername, UserAccount::setUsername)).addMappings(mapper -> mapper.map(UserInfor::getPassword, UserAccount::setPassword));}

使用:

UserAccount account= modelMapper.map(userInfo,UserAccount.class);

上述代码,根据配置文件中configureUser方法中配置的字段,将两个实体类中的字段进行复制赋值。

3.使用实例

下面我们模拟一个业务:后端接口从前端中接收到用户注册数据,进行注册;前端调用查询接口,获取用户的数据。

首先,我们定义VO、DTO、PO对象:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserInfo implements Serializable {//该实体类为封装好的前端传输页面VO对象@NotBlank(message = "用户名不能为空")private String Username;@NotBlank(message = "密码不能为空")private String Password;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserDTO implements Serializable {//该实体类为业务处理DTO对象private int Account;private String Username;private String Password;private String Roles;
}
@Data
@AllArgsConstructor
@NoArgsConstructor
@TableName("user_account")
public class UserAccount implements Serializable {//该实体类为用户账号表对应PO对象@TableIdprivate int SerialNum;private int Account;private String Username;private String Password;private String Roles;private String status;private String registerDate;
}

然后,我们编写用户注册相关代码(基于springboot+mybatis plus),由于使用mybatis plus,此处省略mapper层代码,仅展示serviceImpl和controller中代码。

控制层:

    //用户注册@PostMapping("/register")public CommonResult userRegister(@RequestBody @Valid UserInfo user){int result = userService.userRegister(user);if(result!=0){return CommonResult.success(result);}else {return CommonResult.fail(result);}} 

业务处理:

    @Overridepublic int userRegister(UserInfo user) {if(accountMapper.selectCount(new QueryWrapper().eq("username",user.getUsername()))!=0){log.info("用户名已存在");return 0;}UserDTO userDTO = new UserDTO();BeanUtils.copyProperties(userDTO,user);//加密密码Md5Hash md5Hash = new Md5Hash(userDTO.getPassword(), userDTO.getUsername(),2);userDTO.setPassword(md5Hash.toString());//模拟生成账号userDTO.setAccount(12345678);//赋予权限userDTO.setRoles("user");return accountMapper.insert(user);}

最终,我们可以往数据库中传入一条用户刚注册的账号数据,status和RegisterDate等属性取数据库设置好的默认值。

然后,我们再定义一个VO用于展示用户的信息:

@Data
@AllArgsConstructor
@NoArgsConstructor
public class UserVo implements Serializable {//该VO用于展示用户信息,去除了用户密码等敏感信息private int serialNum;private int account;private String username;
}

进行用户信息的查询,获取所有的用户账号:

业务层:

    public List getAllUser() {return accountMapper.selectList(null);}

控制层:

    @GetMapping("/get/all")public CommonResult getAllAccount() throws InvocationTargetException, IllegalAccessException {//查询所有数据List userAccountList = userService.getAllUser();List resultList = new ArrayList<>();//封装为VO进行展示for(UserAccount u:userAccountList){UserVo userVo = new UserVo();BeanUtils.copyProperties(userVo,u);resultList.add(userVo);}//根据序列号进行排序,后注册的放在最前面resultList.sort(new Comparator() {@Overridepublic int compare(UserVo o1, UserVo o2) {return o2.getSerialNum() - o1.getSerialNum();}});return new CommonResult<>(200,"账号列表如下:",resultList,resultList.size());} 

然后我们就可查询得到所有的去除了敏感信息可用于展示的用户账号信息。

注:此处由于业务简单,没有将PO对象转换为DTO再转换为VO。

相关内容

热门资讯

苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...