做CRUD的功能时,我们常常会定义一个和表对应的实体类信息,然后这个实体类信息的属性和表中的字段一一对应,然后加上每个属性的get和set方法;更规范的做法是,在此基础上再加一个DTO类,它与实体类
长得几乎一样,但是这个类不直接和表关联。
之前一直不明白为何要再定义一个dto类,也觉得get和set方法不外乎是:
public String getEmail() { return email; } public void setEmail(String email) { this.email = email; }
这种“千篇一律”的写法。。直到最近做了对字段加解密的活,才被虐得很惨。。
下面就以对email字段来加解密,说一说我的收获。
假设有一个和表对应的实体类Info(Hibernate):
@SuppressWarnings("serial") @Table(name = "INFO") @Entity public class Info extends BasicEntity { @Column(name = "EMAIL") private String email; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
还有一个对应的DTO:
public class InfoDTO { private String email; public String getEmail() { return email; } public void setEmail(String email) { this.email = email; } }
现在如果要对email字段加解密,就是在数据库里看到的是密文,在前端UI看到的是明文。此时就跟get和set有关了。。
我们在此不讨论如何加解密。一般而言,Entity的set方法用于保存入库,get方法用于从库里取数据,你会很正常的想到这样:
@SuppressWarnings("serial") @Table(name = "INFO") @Entity public class Info extends BasicEntity { @Column(name = "EMAIL") private String email; public String getEmail() { email = ....(emial);//解密的伪代码 return email; } public void setEmail(String email) { email = ....(emial);//加密的伪代码 this.email = email; } }
set方法没有问题,但是get方法就是一个“陷阱”!在首次解密数据库里的密文email时,确实能在前端正常显示明文,但是同时数据库里的email字段也会变成明文!我们在第二次以后再去访问时,因为已经是
明文,再解密的话就会报错!
所以get方法也可能改变数据库里的值,因为一旦你在get方法里对该字段做了逻辑处理后,email是全局变量,会直接影响数据库里面的值!一般我们只认为set会改变库里的值,而get不会。但是要看get方法里
有没有对变量做逻辑处理,这就颠覆了"固化"的思维。
此时DTO类就派上用场啦!可以这样改造,保持Entity实体类的get方法不变,DTO类的get方法再做解密!如:
@SuppressWarnings("serial") @Table(name = "INFO") @Entity public class Info extends BasicEntity { @Column(name = "EMAIL") private String email; public String getEmail() { return email; } public void setEmail(String email) { email = ....(emial);//加密的伪代码 this.email = email; } }
DTO类:
public class InfoDTO { private String email; public String getEmail() { email = ....(emial);//解密的伪代码 return email; } public void setEmail(String email) { this.email = email; } }
这样,无论你访问多少次。数据库里的密文会一直保持,我们可以通过debug知道代码的执行顺序是:
Entity类的get方法从数据库里取出密文->DTO类的set方法把Entity类get到的值赋给自己->DTO类的get方法把自己get到的值做处理(直接显示或做处理)
从这个角度,可以将DTO类理解成一个数据的备份,不直接与数据库挂钩,也就不会影响数据库里的值。
还有一种情景是UI输入查询/添加或修改去保存,这是一个与上面方向相反的过程。
此时DTO类可以用于收集form查询或添加/修改表单的数据,其实也可以用Map,看字段值的多少了。
同样,如果我们考虑email这个字段,用户输入的肯定是明文,存到数据库里需是密文,此时因为在Entity类里set方法直接是加密的了,所以我们要保持在DTO里get到的值是明文,执行顺序:
用户输入明文->DTO类的set方法来保存输入信息->DTO类的get方法来获得输入->Entity类的set方法加密
这时候我们会发现,如果在DTO类的get方法里还保留解密逻辑,就会出错,所以此时DTO的get方法又不能加了。
这就引申出一个问题,我们一般DTO当作Entity类和UI之间的介质,当他要作为接收参数的角色时,get方法里也不能加逻辑处理,此时需要注意!此时,我们只能用其他参数接收载体如Map
所以当字段需要做逻辑处理,不再是传统的get和set时,需要注意get和set对值的改变!
下面一张图是我对get和set的理解(图是用wps画的,很渣勿喷~)
以上加解密只是一个例子,用于说明字段不再是单纯get和set时需要注意的地方!!!
相关推荐
get set方法生成注释和字段注释.zip,包括GetterSetterUtil.java、GetterSetterUtil.class、get set方法生成注释和字段注释.docx详细讲解如果用快捷方式生成set、get注释
根据sql服务器IP获取sql服务器的所有数据库名及数据表名,在根据所选的表名生成所选表的所有字段的get、set方法。
snmp工具文件非常好用的snmp获取工具,get和set功能!
ActionForm里的get和set方法
C# get与set操作.rar
生成普通java对象的get和Set方法和注释。
java中set和get方法的理解 写给初学者
页面传值session 的get 和set方法。
idea自动生成get/set注释的插件, 类似于 MyEclipse 的 Code Templates
UltrlEdit get 和set 脚本 UltrlEdit get 和set 脚本
【Flutter】Dart 面向对象 ( get 方法 | set 方法 | 静态方法 ) https://hanshuliang.blog.csdn.net/article/details/113883540 博客源码快照
自动生成构造方法: 步骤一:在声明的类中,单击鼠标右键,选择source 步骤二:选择Generate Constructor using ...get是用于获取某个变量的值,而set是给某个变量进行赋值,是一对相互操作3. idea自动生成get方法
GET SET 该如何使用呢?什么时候使用呢?该文档详细说明了。
主要介绍了vue计算属性get和set用法,结合实例形式分析了计算属性的功能及get和set用法的具体使用技巧,需要的朋友可以参考下
自定义生成set,get方法注释的java文件,下载后可以根据我的文章中的说明步骤进行操作。
通过导入插件,开发代码的时候自动生成get和set方法以及对应的注释
博文Unity-Get/Set属性访问器详解源码!!!!!!!!!!
试一试
eclipse 的GET/SET对字段的注释自动添加
C#的set get用法,讲解的非常详细!