令人晕眩的PO,DAO,DTO,VO

什么是 PO,DAO,DTO,VO 呢?

引入

对于编程的朋友们来说,MVC是不会陌生的,Spring MVC就是MVC模式的一个很成熟的框架,同时呢JAVA是一种面向对象的语言,着重的就是对象的操作了,俗话说万物皆对象,这一点Python似乎比JAVA理解和应用的更加透彻一些,讲道理,Python中int类型的都是对象而不是是JAVA一样属于基本数据类型了(额,其实Python中没有int这一说,只有整数类型)。

好吧,话题扯远了,回到MVC来,对一个成熟的Web项目而言,如果是MVC模式的话就会用模型-控制器-视图的三层,而在里面对于一个对象来说是会存在着不同的“形态”的。

PS: 这个形态只是一种比喻啊,可以认为是游戏中的一个英雄有着不同的皮肤,或者说是穿上了不同的时装,虽然给人看着不一样,但是实质上还是那个英雄或者是角色。

小栗子

一个写好了的Web项目,第一步首先应该是注册(当然,一定要说我后台管理员直接登录不行嘛的朋友咱还是不计较这些好吧~~),这时也就会遇见第一个对象,用户对象,也就是正在注册的你自己,面向对象的思想将你抽象称为了一个用户对象。

此时我们可以假设一个用户对象应该有些什么信息呢?

  • 首先我们可以简单一点

    • 名字是要的吧

    • 现在除了第三方登录之外大多的都是通过手机号码注册的,那我们还可以加一个手机号码的字段

    • 注册的方式我们可以通过手机号码,我们也可以通过邮箱啊,所以我们可以再添加一个字段叫做注册方式的字段

    • 这样的话,我们的用户表就可以创建出来了

      CREATE TABLE `user` (
        `id` int(11) NOT NULL AUTO_INCREMENT,
        `name` varchar(64) COLLATE utf8_unicode_ci NOT NULL COMMENT '用户名',
        `telphone` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '电话号码',
        `register_mode` varchar(255) COLLATE utf8_unicode_ci NOT NULL COMMENT '注册方式'
        PRIMARY KEY (`id`)
      ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
      
  • 唉,这时也许有朋友就有疑问了,不对啊,我要是注册的话,我没设置密码啊,那我下次怎么登录呢?

    别急,对于密码来说,一般是不和用户表存在一起的,而是怎么做呢?我们可以另外弄一张表,存用户的密码,通过用户的ID作为外键的关联,存下来的也只是加密之后的密码,这样子会安全一些,当然你要是直接存在用户表里面那也是可以的。

    我们在弄个用户密码表

    CREATE TABLE `user_password` (
      `id` int(11) NOT NULL AUTO_INCREMENT,
      `password` varchar(128) COLLATE utf8_unicode_ci NOT NULL COMMENT '密码',
      `user_id` int(11) NOT NULL COMMENT '用户ID',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
    
  • 现在,对于正要在一个新网站注册的你,就成功的变为了一个对象了,当然,现在显示出来的是两张数据库表。

PO 登场 —— 这是Model层的数据

定义好了数据库表,PO这个对象就可以出来了,PO的定义在百度一搜到处都是,笔者觉得简单的理解为和数据库表一毛一样的一个对象就成了。

因为我们上面定义了两张表,这下字可以定义出来两个PO类

public class UserDO{
    private int id;
    private String name;
    private String telphone;
    private String registerMode;
    //setter和getter方法就省略不写了,如果你集成了lomback那就直接上注释更简单,个人倒是十分推荐这个插件
}
public class UserPasswordDO{
    private int id;
    private String password;
    private int userId;
    //setter和getter方法省略
}

DAO登场 —— 这个东东还是算作是Model层的东西

有了数据库表对应的对象,我们需要对PO类进行操作啊,我要是注册的话需要新增一条数据的吧,我要是登录需要查数据的吧,这个时候就是DAO的作用了,也就是通过PO对数据库表里面的数据进行直接的操作。

笔者在这个位置以Spring Data JPA做为示例,因为简单,而且笔者所用的案例书写并不复杂,Spring Data JPA使得我只要继承JpaRepository这个接口我就可以实现基本的增上改查的方法了,或者说使用MyBatis的朋友直接通过代码生成的插件直接生成也没得问题。

于是呢,我们的DAO类也阔以出来了

public interface UserDAO extends JpaRepository<UserPO,Integer>{
    //哎嘿 就这样 之后我们就可以使用基本的增删改查方法了 实质上和Hibernate差不多
}
public interface UserPasswordDAO extends JpaRepository<UserPasswordPO,Integer>{   
}

插一句

后面的讲解需要联系前后端的问题,这里不细聊前端,对于后端来说,我们需要处理的也是数据,这里就以JSON格式为例子,

假设呢,我们需要注册,那我们就要提交我们的注册信息了:

{
    "name":"我要注册呀",
    "telphone":"12345678901",
    "password":"123456"
}

之后的内容就以这个为前端传给后台的信息啦啊~

DTO登场 —— 这个就是Service层的东西了

对于实际的注册的任务,传过来的数据肯定是用户名和密码一起来的,不能说我先传一个用户名,然后再传一个密码的吧。

这个时候呢,DTO就有作用了,它干啥呢,它就把传过来的数据都给自己先安上,然后要存数据库了,嘿,那也没事儿,DTO可以一分为二(或者三四五六七都行),再把这些数据都分给对应的PO类,之后的数据库的操作就不再是DTO的事情了。

这样一来,我们的DTO类的就出来了

public class UserDTO{
    private int id;
    private String name;
    private String telphone;
    private String registerMode;
    private String password;
    //setter方法和getter方法省略
}

此时,假设我们直接把这个当做显示数据,如果前端说我要查询用户id为1的信息,那我们会传给前端什么信息呢?

{
    "id":"1",
    "name":"我要注册呀",
    "telphone":"12345678901",
    "registerMode":"pyPhone",
    "password":"fwDfvds324SFDSertw3"
}

乍一看好像也没什么问题啊(这里的密码乱写的,假装是加密了之后的啊…),但是VO为啥也会出现呢?那就是下面讲的东西了

最后VO也来了 —— 这哥们是View层的东西,对应代码的话就在Controller层中定义

为什么这个会定义在Controller层中呢?这是因为前后端的分离,我们是通过Controller层返回给前端数据的,Controller层定义很多的API接口,前端通过对应的域名访问,后端接到请求,处理,数据通过JSON格式或者其他格式传给前端。

如果我们要是不定义VO,直接使用DTO行不行呢?里面已经有用户的所有信息了啊,你要是想查一个用户,这样不就都过来了吗?

其实,这也是可以的,但是我们要看到这个DTO里面有个密码的字段,这是个不安全的操作,按道理来说后端是不应该把密码从数据库中查询出来返回给前端的。

也许有朋友说密码不是被加密了吗?这样传也没很大的问题吧,但是呢,即使加密了,也可能被解密出来,我们还是可以安全一点点,其次呢,那个注册方式的字段对于前端来说是无意义的,这是我们后端需要判断的一个字符串,即使给了前端它们也不知道干啥,显示出来吧,用户也不知道这是个啥,所有VO就出来了,它顶着这些问题,其实就是把前端想要展示的数据,再定义为一个类。

这样子,我们最后的VO也出来了

public class UserVO{
    private int id;
    private String name;
    private String telphone;
    //setter和getter方法省略
}

这样的话,在传递给前端的信息,那就很舒适了

{
    "id":"1",
    "name":"我要注册呀",
    "telphone":"12345678901"
}

如果说你觉着电话号码也不应该传的话…

其实前端显示的时候是可以吧电话号码变成123****8901这样习惯性的样式的.

OK,这就是PO->AO->DTO->VO的内容了~!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值