<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          一款I(lǐng)DEA插件神器,幫你一鍵轉(zhuǎn)換DTO、VO、BO、PO、DO

          共 6632字,需瀏覽 14分鐘

           ·

          2022-05-22 08:19

          關(guān)注Java學習之道一起成長,一起學習~

          作者: 藍巫
          來源: juejin.cn/post/7053264631262871583

          Part1什么是DTO、VO、BO、PO、DO、POJO

          POJO的定義是無規(guī)則簡單的對象,在日常的代碼分層中pojo會被分為VO、BO、 PO、 DTO

          VO (view object/value object)表示層對象

          1、前端展示的數(shù)據(jù),在接口數(shù)據(jù)返回給前端的時候需要轉(zhuǎn)成VO

          2、個人理解使用場景,接口層服務(wù)中,將DTO轉(zhuǎn)成VO,返回給前臺

          B0(bussines object)業(yè)務(wù)層對象

          1、主要在服務(wù)內(nèi)部使用的業(yè)務(wù)對象

          2、可以包含多個對象,可以用于對象的聚合操作

          3、個人理解使用場景,在服務(wù)層服務(wù)中,由DTO轉(zhuǎn)成BO然后進行業(yè)務(wù)處理后,轉(zhuǎn)成DTO返回到接口層

          PO(persistent object)持久對象

          1、出現(xiàn)位置為數(shù)據(jù)庫數(shù)據(jù),用來存儲數(shù)據(jù)庫提取的數(shù)據(jù)

          2、只存儲數(shù)據(jù),不包含數(shù)據(jù)操作

          3、個人理解使用場景,在數(shù)據(jù)庫層中,獲取的數(shù)據(jù)庫數(shù)據(jù)存儲到PO中,然后轉(zhuǎn)為DTO返回到服務(wù)層中

          DTO(Data Transfer Object)數(shù)據(jù)傳輸對象

          1、在服務(wù)間的調(diào)用中,傳輸?shù)臄?shù)據(jù)對象

          2、個人理解,DTO是可以存在于各層服務(wù)中(接口、服務(wù)、數(shù)據(jù)庫等等)服務(wù)間的交互使用DTO來解耦

          DO(domain object)領(lǐng)域?qū)嶓w對象

          DO 現(xiàn)在主要有兩個版本:

          ①阿里巴巴的開發(fā)手冊中的定義,DO( Data Object)這個等同于上面的PO

          ②DDD(Domain-Driven Design)領(lǐng)域驅(qū)動設(shè)計中,DO(Domain Object)這個等同于上面的BO

          參考文檔:

          https://juejin.cn/post/6952848675924082718
          https://juejin.cn/post/6844904046097072141
          https://zhuanlan.zhihu.com/p/264675395

          Part2插件如何完成轉(zhuǎn)化

          插件名稱:Simple Object Copy

          1. 定義方法出入?yún)?/section>
          2. 光標定位方法內(nèi),使用快捷鍵ALT+INSERT(WIN) 、 command + N(mac) ,或者右鍵鼠標選擇Generate,彈出生成選項框后,選擇genCopyMethod,代碼就生成好了

          需要手寫的代碼

          一鍵生成后的展示

          復雜對象轉(zhuǎn)化展示(一鍵生成后的展示)

          復雜對象轉(zhuǎn)化源碼示例

          @Data
          public?class?UserVO?{
          ????private?String?name;
          ????private?Date?entryDate;
          ????private?String?userId;
          ????private?List?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?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?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;
          }

          Part3其他轉(zhuǎn)化方式

          1.無入侵市面上有很多類似的工具類,比較常用的有

          • 1、Spring BeanUtils (copyProperties)
          • 2、Cglib ?BeanCopier (copyProperties)
          • 3、Apache BeanUtils (copyProperties)
          • 4、Apache PropertyUtils (copyProperties)
          • 5、Dozer
          • 6、mapstruct
          • 7、JSON 序列化 再反序列化

          這些工具,不僅要引入相應(yīng)的依賴jar包,而且對代碼有入侵,要調(diào)用對應(yīng)得api方法才能進行轉(zhuǎn)化,一旦遇到類型不一致,字段名稍有變動,就需要另寫java代碼補全字段,整體代碼非常丑陋。

          舉例:

          1.mapstruct

          同樣的代碼,,不僅要引入依賴、寫如下轉(zhuǎn)化mapper,還要,在對應(yīng)地方調(diào)用對應(yīng)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);
          }

          //調(diào)用示例
          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?roleList;
          ????private?RoomVO?room;
          ????public?static?UserVO?convertToUserVO(UserDTO?item)?{
          ????????if?(item?==?null)?{
          ????????????return?null;
          ????????}
          ????????UserVO?result?=?new?UserVO();
          ????????BeanUtils.copyProperties(item,result);
          ????????List?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);
          ????????//這里沒有代碼提示,需要自己寫,小心前端總是問為啥都是null
          ????????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.性能優(yōu)勢

          相比上面的工具類,不是使用反射、就是是用代理、序列化操作。相比于純正的set方法去轉(zhuǎn)化 ,差距不是一個量級。此次不贅述。

          3.靈活性、兼容性

          跟上述工具類相比插件有很大優(yōu)勢,不再贅述,下面我們比較一下,我之前常用的idea插件generateO2O

          我方插件特點對比插件特點
          Simple Object Copy依據(jù)返回值為主,根據(jù)字段名去匹配 ,不會導致返回值漏屬性generateO2O以入?yún)橹髌ヅ渥侄?,存在漏屬性的情況
          Simple Object Copy支持對象包含對象、對象包含list、set集合的轉(zhuǎn)化generateO2O不支持子對象的轉(zhuǎn)化、不支持list泛型不同的轉(zhuǎn)化
          Simple Object Copy相同出入?yún)㈩惷?,生成全限定類?/td>generateO2O同類名出現(xiàn)問題
          Simple Object Copy支持泛型對象、支持構(gòu)造器初始化、支持lombok builder初始化、空參構(gòu)造加各個屬性set初始化

          在此推薦其他一個我常用插件:generateAllSetter,搭配食用更佳

          4、如何下載

          打開idea plugins,切market place 搜索:Simple Object Copy

          試用30天,支付寶、微信 、PayPal都可以付款。6元(人民幣)每年,當然學生、教育機構(gòu)、公益免費。

          官方會郵件讓你注冊jb賬號,給賬號開通權(quán)限,你可以在官網(wǎng)找到自己的激活碼,然后再idea 不登錄用。也可以在idea 登錄jb賬號在線試用。

          這可能是你的第一個付費插件。多謝支持,哈哈!

          如果你沒錢的話,也可郵件我。我找找有沒有免費方式。

          Part4下班早一半

          通過插件的使用

          1、可以節(jié)省一個個字段的設(shè)置的開發(fā)時間

          2、避免了漏字段設(shè)置,ps:前端同學總是來問為啥字段總是null 。

          3、而且通過出入?yún)⒌脑O(shè)計思想去開發(fā),規(guī)范了代碼,在有特殊請求轉(zhuǎn)化的時候也比較方便。

          -- END?--

          -??| 更多精彩文章 -



          ← 左右滑動與Java學習之道互動交流 →

          加我微信,交個朋友
          長按/掃碼添加↑↑↑

          瀏覽 27
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  水蜜桃在线观看视频 | 五月天亚洲乱伦小说 | 国产精品久久久 | 免费看日韩无码AV中文字幕 | 日韩黄片在线看 |