java中VO和DTO之間的轉(zhuǎn)換實(shí)現(xiàn)
一、背景
1.領(lǐng)域模型中的實(shí)體類分為四種類型:VO、DTO、DO、PO
二、詳細(xì)講解
1.VO(View Object),視圖對(duì)象,用于展示層,它的作用是把某個(gè)指定頁面(或組件)的所有數(shù)據(jù)封裝起來。
2.DTO(Data Transfer Object),數(shù)據(jù)傳輸對(duì)象,這個(gè)概念來源于J2EE的設(shè)計(jì)模式,原來的目的是為了EJB的分布式應(yīng)用提供粗粒度的數(shù)據(jù)實(shí)體,以減少分布式調(diào)用的次數(shù),從而提高分布式調(diào)用的性能和降低網(wǎng)絡(luò)負(fù)載,但在這里,我泛指用于展示層與服務(wù)層之間的數(shù)據(jù)傳輸對(duì)象。
3.DO(Domain Object),領(lǐng)域?qū)ο?,就是從現(xiàn)實(shí)世界中抽象出來的有形或無形的業(yè)務(wù)實(shí)體。
4.PO(PersistentObject),持久化對(duì)象,它跟持久層(通常是關(guān)系型數(shù)據(jù)庫)的數(shù)據(jù)結(jié)構(gòu)形成一一對(duì)應(yīng)的映射關(guān)系,如果持久層是關(guān)系型數(shù)據(jù)庫,那么,數(shù)據(jù)表中的每個(gè)字段(或若干個(gè))就對(duì)應(yīng)PO的一個(gè)(或若干個(gè))屬性。
5.舉例:
后端返回個(gè)前端的對(duì)象,可以 ***VO.java
mybatis生成的dao表實(shí)體對(duì)象,可以 ****PO.java
一般是 PO 轉(zhuǎn)換 DO 然后 轉(zhuǎn)換 DTO提供服務(wù)供外部調(diào)用
注意
PO一般自動(dòng)生成和表字段一一映射
DO一般和DO很多字段是一樣帶,但很多如類型字段是枚舉,有的項(xiàng)目中DO是Model結(jié)尾的類
DTO如webservice接口(提供外部服務(wù)的),返回結(jié)果對(duì)象都是DTO,里面屬性的定義比較講究,易懂安全好擴(kuò)展,DTO與DTO之間關(guān)系是包含還是平級(jí),設(shè)計(jì)的時(shí)候一定要定義清楚,不然后期就是個(gè)坑
VO比較簡單,前端展示需要什么就怎么定義
三、實(shí)體對(duì)象間的轉(zhuǎn)換
一個(gè)規(guī)范的項(xiàng)目
代碼中充滿了VO、From、DTO、DO等等pojo類,這些類作用不一樣但類里面的屬性值往往一模一樣,當(dāng)屬性非常多時(shí),一個(gè)個(gè)set的確非常累人又耗時(shí)間,其實(shí)強(qiáng)大的Spring早為我們準(zhǔn)備好了貼心工具,一行搞定以前甚至30行的代碼量
四、第一種方法的具體代碼例子
1.導(dǎo)入依賴
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId> <version>5.1.6.RELEASE</version> </dependency>
2.一個(gè)DTO(接口定義對(duì)象一般用DTO)
public class TestDemoDTO{ private String name; private Map<String,String> citys; private Date gmtStart; private Boolean flag; private Integer age; private List<String> types; public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, String> getCitys() { return citys; } public void setCitys(Map<String, String> citys) { this.citys = citys; } public Date getGmtStart() { return gmtStart; } public void setGmtStart(Date gmtStart) { this.gmtStart = gmtStart; } public Boolean getFlag() { return flag; } public void setFlag(Boolean flag) { this.flag = flag; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<String> getTypes() { return types; } public void setTypes(List<String> types) { this.types = types; } @Override public String toString() { return "TestDemoDTO{" + "name='" + name + '\'' + ", citys=" + citys + ", gmtStart=" + gmtStart + ", flag=" + flag + ", age=" + age + ", types=" + types + '}'; } }
3.一個(gè)From(前端入?yún)⒍xFrom)
public class TestDemoFrom { private String name; private Map<String,String> citys; private Date gmtStart; private Boolean flag; private Integer age; private List<String> types; public String getName() { return name; } public void setName(String name) { this.name = name; } public Map<String, String> getCitys() { return citys; } public void setCitys(Map<String, String> citys) { this.citys = citys; } public Date getGmtStart() { return gmtStart; } public void setGmtStart(Date gmtStart) { this.gmtStart = gmtStart; } public Boolean getFlag() { return flag; } public void setFlag(Boolean flag) { this.flag = flag; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public List<String> getTypes() { return types; } public void setTypes(List<String> types) { this.types = types; } @Override public String toString() { return "TestDemoFrom{" + "name='" + name + '\'' + ", citys=" + citys + ", gmtStart=" + gmtStart + ", flag=" + flag + ", age=" + age + ", types=" + types + '}'; } }
4.測試類
public class TestDemo { public static void main(String[] args) { TestDemoFrom testDemoFrom = new TestDemoFrom(); HashMap<String, String> map = Maps.newHashMap(); map.put("001","北京"); map.put("002","上海"); map.put("003","廣州"); testDemoFrom.setCitys(map); testDemoFrom.setFlag(true); testDemoFrom.setGmtStart(new Date()); testDemoFrom.setName("諾言"); testDemoFrom.setAge(18); testDemoFrom.setTypes(Lists.newArrayList("我愛","寶貝")); System.out.printf(testDemoFrom.toString()+"\n"); //下面就可以開始轉(zhuǎn)化了,就一行代碼 TestDemoDTO testDemoDTO = new TestDemoDTO(); BeanUtils.copyProperties(testDemoFrom,testDemoDTO); System.out.println(testDemoDTO.toString()); } }
5.結(jié)果
TestDemoFrom{name='諾言', citys={001=北京, 002=上海, 003=廣州}, gmtStart=Fri May 10 22:37:53 CST 2019, flag=true, age=18, types=[我愛, 寶貝]}
TestDemoDTO{name='諾言', citys={001=北京, 002=上海, 003=廣州}, gmtStart=Fri May 10 22:37:53 CST 2019, flag=true, age=18, types=[我愛, 寶貝]}
6.注意
注意賦值失敗情況
如果屬性名稱不同就會(huì)賦值不了
如果類型不同,名稱相同也是會(huì)賦值不了
五、第二種方法的具體代碼例子(使用dozer)
1.導(dǎo)入依賴
<dependency> <groupId>net.sf.dozer</groupId> <artifactId>dozer</artifactId> <version>5.4.0</version> </dependency>
2.測試類
public class TestDemoDozer { @Test public void test() { DozerBeanMapper mapper = new DozerBeanMapper(); TestDemoFrom testDemoFrom = new TestDemoFrom(); HashMap<String, String> map = Maps.newHashMap(); map.put("001","北京"); map.put("002","上海"); map.put("003","廣州"); testDemoFrom.setCitys(map); testDemoFrom.setFlag(true); testDemoFrom.setGmtStart(new Date()); testDemoFrom.setName("諾言"); testDemoFrom.setAge(18); testDemoFrom.setTypes(Lists.newArrayList("我愛","寶貝")); System.out.printf(testDemoFrom.toString()+"\n"); // 轉(zhuǎn)換 TestDemoDTO convert = mapper.map(testDemoFrom,TestDemoDTO.class); System.out.println(convert); } }
3.結(jié)果
TestDemoFrom{name='諾言', citys={001=北京, 002=上海, 003=廣州}, gmtStart=Sat May 11 00:30:02 CST 2019, flag=true, age=18, types=[我愛, 寶貝]}
TestDemoDTO{name='諾言', citys={001=北京, 002=上海, 003=廣州}, gmtStart=Sat May 11 00:30:02 CST 2019, flag=true, age=18, types=[我愛, 寶貝]}
六、結(jié)束
到此這篇關(guān)于java中VO和DTO之間的轉(zhuǎn)換實(shí)現(xiàn)的文章就介紹到這了,更多相關(guān)java VO和DTO轉(zhuǎn)換 內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
IntelliJ IDEA安裝插件阿里巴巴Java開發(fā)手冊(Alibaba Java Coding Guidelines
這篇文章主要介紹了IntelliJ IDEA安裝插件阿里巴巴Java開發(fā)手冊(Alibaba Java Coding Guidelines),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析
這篇文章主要介紹了Spring之關(guān)于PropertyDescriptor的擴(kuò)展剖析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-07-07Spring Boot項(xiàng)目添加外部Jar包以及配置多數(shù)據(jù)源的完整步驟
這篇文章主要給大家介紹了關(guān)于Spring Boot項(xiàng)目添加外部Jar包以及配置多數(shù)據(jù)源的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-06-06關(guān)于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序
這篇文章主要介紹了關(guān)于@PostConstruct、afterPropertiesSet和init-method的執(zhí)行順序,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09