最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

使用JPA自定義VO類型轉(zhuǎn)換(EntityUtils工具類)

 更新時(shí)間:2021年11月22日 11:48:20   作者:不得真假  
這篇文章主要介紹了使用JPA自定義VO類型轉(zhuǎn)換(EntityUtils工具類),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

JPA自定義VO類型轉(zhuǎn)換(EntityUtils工具類)

在JPA查詢中,如果需要返回自定義的類,可以使用EntityUtils工具類,該類源碼:

import org.slf4j.Logger;
import org.slf4j.LoggerFactory; 
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
/**
 * @author 954L
 * @create 2019/10/30 17:27
 */
public class EntityUtils {
 
    private static final Logger log = LoggerFactory.getLogger(EntityUtils.class);
 
    /**
     * 將數(shù)組數(shù)據(jù)轉(zhuǎn)換為實(shí)體類
     * 此處數(shù)組元素的順序必須與實(shí)體類構(gòu)造函數(shù)中的屬性順序一致
     *
     * @param list  數(shù)組對(duì)象集合
     * @param clazz 實(shí)體類
     * @param <T>   實(shí)體類
     * @param model 實(shí)例化的實(shí)體類
     * @return 實(shí)體類集合
     */
    public static <T> List<T> castEntity(List<Object[]> list, Class<T> clazz, Object model) {
        List<T> returnList = new ArrayList<T>();
        if (list.isEmpty()) return returnList;
        Object[] co = list.get(0);
        List<Map> attributeInfoList = getFiledsInfo(model);
        Class[] c2 = new Class[attributeInfoList.size()];
        if (attributeInfoList.size() != co.length) {
            return returnList;
        }
        for (int i = 0; i < attributeInfoList.size(); i++) {
            c2[i] = (Class) attributeInfoList.get(i).get("type");
        }
        try {
            for (Object[] o : list) {
                Constructor<T> constructor = clazz.getConstructor(c2);
                returnList.add(constructor.newInstance(o));
            }
        } catch (Exception ex) {
            log.error("實(shí)體數(shù)據(jù)轉(zhuǎn)化為實(shí)體類發(fā)生異常:異常信息:{}", ex.getMessage());
            return returnList;
        }
        return returnList;
    }
 
    private static Object getFieldValueByName(String fieldName, Object modle) {
        try {
            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = modle.getClass().getMethod(getter, new Class[]{});
            Object value = method.invoke(modle, new Object[]{});
            return value;
        } catch (Exception e) {
            return null;
        }
    }
 
    private static List<Map> getFiledsInfo(Object model) {
        Field[] fields = model.getClass().getDeclaredFields();
        List<Map> list = new ArrayList(fields.length);
        Map infoMap = null;
        for (int i = 0; i < fields.length; i++) {
            infoMap = new HashMap(3);
            infoMap.put("type", fields[i].getType());
            infoMap.put("name", fields[i].getName());
            infoMap.put("value", getFieldValueByName(fields[i].getName(), model));
            list.add(infoMap);
        }
        return list;
    } 
}

使用原生sql查詢:

    /**
     * 根據(jù)公司名稱查詢崗位
     * @param name 公司名稱
     * @return  List<EmploymentPosition>
     */
    @Query(value = "select id, position, salary, people, experience, address, update_time from employment_position where company_name = ?1 and is_delete is false ORDER BY sort asc", nativeQuery = true)
    List<Object[]> findByCompanyName(String name);

使用類型轉(zhuǎn)換:

@Override
    public List<EmploymentPositionVO> findByCompanyName(String name) {
        List<Object[]> objects = employmentPositionRepository.findByCompanyName(name);
        return EntityUtils.castEntity(objects, EmploymentPositionVO.class, new EmploymentPositionVO());
    }

VO類如下:

import lombok.Data; 
import java.math.BigInteger;
import java.sql.Timestamp;
 
/**
 * @website https://el-admin.vip
 * @description /
 * @author budezhenjia
 * @date 2021-02-08
 **/
@Data
public class EmploymentPositionVO {
 
    /** ID */
    private BigInteger id;
 
    /** 崗位名稱 */
    private String position;
 
    /** 月薪 */
    private String salary;
 
    /** 人數(shù) */
    private Integer people;
 
    /** 工作經(jīng)驗(yàn) */
    private String experience;
 
    /** 工作地點(diǎn) */
    private String address;
 
    /** 更新時(shí)間 */
    private Timestamp updateTime; 
    public EmploymentPositionVO(BigInteger id, String position, String salary, Integer people, String experience, String address, Timestamp updateTime) {
        this.id = id;
        this.position = position;
        this.salary = salary;
        this.people = people;
        this.experience = experience;
        this.address = address;
        this.updateTime = updateTime;
    } 
    public EmploymentPositionVO() {
    }
}

注意!

查詢sql語(yǔ)句所查詢出來(lái)的字段應(yīng)與VO類中屬性順序一致,類型也需要一致??!

例如ID這個(gè)字段MySQL中類型為bigint,VO類中的類型為bigInteger

dto,vo,po,bo等實(shí)體轉(zhuǎn)換工具類

3層開發(fā)以及不是多么新穎的開發(fā)思想了,但是呢,苦于開發(fā)的程序猿們,經(jīng)常會(huì)被各個(gè)實(shí)例之間的轉(zhuǎn)換弄得暈頭轉(zhuǎn)向,尤其是轉(zhuǎn)換的次數(shù)多了,一下就蒙了,不知道轉(zhuǎn)到哪里去了,博主也有這種困難,于是在網(wǎng)上到處找,找到了一些方法,并結(jié)合自身的開發(fā)使用,填補(bǔ)一些坑,希望對(duì)大家有所幫助!

下面宣布這次的主角:dozer

他是誰(shuí),一看英文名就不懂吧,其實(shí)他是一個(gè)大家都知道的一個(gè)角色,spring里面他可是家喻戶曉的一個(gè)主角,沒錯(cuò)就是beanUtils(其實(shí),就是他的替身?。┲饕饔镁褪怯脕?lái)復(fù)制 JavaBean 屬性的類庫(kù),什么叫復(fù)制,沒錯(cuò),就一模一樣的再來(lái)一份,但是這樣有一點(diǎn)點(diǎn)小小的區(qū)別,那就是,在使用的時(shí)候,需要指定一個(gè)“容器”(瞎說(shuō)的,就是一個(gè)映射接受對(duì)象,也可以叫做目標(biāo))來(lái)存放,不然,復(fù)制到哪去,是不是。

這個(gè)時(shí)候呀,就有一個(gè)經(jīng)紀(jì)人的出現(xiàn),需要通過(guò)“經(jīng)紀(jì)人”去代理復(fù)制,才能叫這個(gè)替身出來(lái)呀(專業(yè)替身30年,必須要有經(jīng)紀(jì)人)

<dependency>
    <groupId>net.sf.dozer</groupId>
    <artifactId>dozer</artifactId>
    <version>5.5.1</version>
</dependency>

好了,經(jīng)紀(jì)人的名片已經(jīng)發(fā)出,這個(gè)時(shí)候,找到劇組,咱們看看這個(gè)替身能不能勝任,能應(yīng)用在哪些劇組,哪些場(chǎng)景!

第一種場(chǎng)景,完全一樣:(咦,度一樣了,那肯定好弄,又看不出來(lái)區(qū)別)

在各個(gè)實(shí)體是一樣的情況下,是很容易的,直接上不就行啦,也不用做啥處理是不是:

直接是用原始替身(API方法)

 Mapper mapper = new DozerBeanMapper();
DestinationObject destObject =  
    mapper.map(sourceObject, DestinationObject.class);

嘿嘿,換一下衣服,直接OK了(也就是使用mapper轉(zhuǎn)換復(fù)制)

第二種場(chǎng)景,完全不一樣:

求乞,完全不一樣,這咋的弄呀,肯定得換替身,是不是!最起碼找個(gè)相似的嘛(不用擔(dān)心,咱們有化妝師呀,化妝走起!)

@Data
public class UserVo{
    @Mapping("userName")
    private String name;
    @Mapping("password")
    private String pwd;
}

看一下,是不是這個(gè)東西,好眼熟,沒錯(cuò),是咱們的vo

@Data
@TableName("user")
public class UserEntity implements Serializable {
    @ApiModelProperty(value = "id")
    @TableId(value = "id", type = IdType.INPUT)
    private String id;
    @ApiModelProperty(value = "用戶名")
    @Mapping("name")
    private String userName;
    @ApiModelProperty(value = "密碼")
    @Mapping("pwd")
    private String password;
    @ApiModelProperty(value = "登錄名")
    private String loginName;
    @ApiModelProperty(value = "創(chuàng)建時(shí)間")
    private Date createTime;
    @ApiModelProperty(value = "修改時(shí)間")
    private Date updateTime;
    @ApiModelProperty(value = "版本號(hào)")
    private Integer version;
    @ApiModelProperty(value = "作廢標(biāo)記")
    private Integer deleted;
}

這個(gè)呢,是咱們的實(shí)體對(duì)象(也就是數(shù)據(jù)庫(kù)對(duì)象了)

看一下,是不是發(fā)小完全不一樣呀!

這里呢,@Mappin充當(dāng)了化妝品的角色,將每一個(gè)不同的細(xì)節(jié)進(jìn)行遮蓋,使其成為和原來(lái)的實(shí)例一模一樣(也就是做了映射了)

 @Mapping("userName")
 private String name;

上面就是一個(gè)化妝處理,將name映射為userName

每一個(gè)地方處理完成后,直接上劇組,看看能不能不被發(fā)現(xiàn)

    /**
     * 轉(zhuǎn)換實(shí)體為另一個(gè)指定的實(shí)體
     * 任意一個(gè)參數(shù)為NULL時(shí) 會(huì)拋出NPE
     *
     * @param source 源實(shí)體 不能為NULL
     * @param clazz 目標(biāo)實(shí)體 不能為NULL
     * @param <T> 泛型
     * @return 轉(zhuǎn)換后的結(jié)果
     */
    @NonNull
    public static <T> T convert(@NonNull Object source, @NonNull Class<T> clazz) {
        return  dozerMapper.map(source, clazz);
    }

實(shí)例:

 UserEntity userEntity = userMapper.selectOne(wrapper);
            UserVo convert = null;
            if(userEntity != null){
               convert = Dozer.convert(userEntity, UserVo.class);
            }

沒錯(cuò),這樣就完成轉(zhuǎn)換替身的操作了,結(jié)果是可以映射上的,各位可以試試哦!

第三種場(chǎng)景,一堆的不相同的替身(好難呀,一堆的不一樣,不能找?guī)讉€(gè)差不多的嗎?)

針對(duì)于這種一堆的不一樣的替身,dozer也有辦法,通過(guò)JAVA8的stream流來(lái)進(jìn)行化妝(化妝師牛,只能這么說(shuō))

 /**
     * 轉(zhuǎn)換List實(shí)體為另一個(gè)指定的實(shí)體
     * source如果為NULL 會(huì)使用空集合
     * 在目標(biāo)實(shí)體為NULL時(shí) 會(huì)拋出NPE
     *
     * @param source 源集合 可以為NULL
     * @param clazz 目標(biāo)實(shí)體 不能為NULL
     * @param <T> 泛型
     * @return 轉(zhuǎn)換后的結(jié)果
     */
    @Nullable
    public static <T> List<T> convert(@Nullable List<?> source, @NonNull Class<T> clazz) {
        return Optional.ofNullable(source)
                .orElse(Collections.emptyList())
                .stream()
                .map(bean -> dozerMapper.map(bean, clazz))
                .collect(Collectors.toList());
    }

看見沒,這樣一弄,就OK了,咦,是不是發(fā)現(xiàn)化妝師dozerMapper從哪來(lái)的(這么牛的化妝師,召幾個(gè)開化妝店去),博主告訴你,這個(gè)化妝師呀,并不是越多也好的(大家都知道,一樣的對(duì)象,建立太多浪費(fèi)空間),只需要建立一個(gè)全局唯一的就行了,博主帶你們看一下化妝間就明白了(工具類來(lái)了)

package cn.yichehuoban.ycbb.platform.util.beanutils;
import org.dozer.Mapper;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
 
@Component
public class Dozer {
    /**
     * dozer轉(zhuǎn)換的核心mapper對(duì)象
     */
    public static final Mapper dozerMapper = new org.dozer.DozerBeanMapper();
    /**
     * 轉(zhuǎn)換實(shí)體為另一個(gè)指定的實(shí)體
     * 任意一個(gè)參數(shù)為NULL時(shí) 會(huì)拋出NPE
     *
     * @param source 源實(shí)體 不能為NULL
     * @param clazz 目標(biāo)實(shí)體 不能為NULL
     * @param <T> 泛型
     * @return 轉(zhuǎn)換后的結(jié)果
     */
    @NonNull
    public static <T> T convert(@NonNull Object source, @NonNull Class<T> clazz) {
        return  dozerMapper.map(source, clazz);
    }
    /**
     * 轉(zhuǎn)換List實(shí)體為另一個(gè)指定的實(shí)體
     * source如果為NULL 會(huì)使用空集合
     * 在目標(biāo)實(shí)體為NULL時(shí) 會(huì)拋出NPE
     *
     * @param source 源集合 可以為NULL
     * @param clazz 目標(biāo)實(shí)體 不能為NULL
     * @param <T> 泛型
     * @return 轉(zhuǎn)換后的結(jié)果
     */
    @Nullable
    public static <T> List<T> convert(@Nullable List<?> source, @NonNull Class<T> clazz) {
        return Optional.ofNullable(source)
                .orElse(Collections.emptyList())
                .stream()
                .map(bean -> dozerMapper.map(bean, clazz))
                .collect(Collectors.toList());
    }
}

在給大家看一下我們的替身

@Data
public class UserVo{
    @Mapping("userName")
    private String name;
    @Mapping("password")
    private String pwd;
    private String loginName;
    private Integer version;
    private Integer deleted;
    private String id;
}

一樣的地方直接就映射上了,不一樣的地方使用 @Mapping注解,填寫上源指定對(duì)象的字段名就行

這只是幾種方法,還有其他雙向映射,數(shù)據(jù)拷貝等,可以看看他的官方文檔dozer

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • 詳解java8中的Stream數(shù)據(jù)流

    詳解java8中的Stream數(shù)據(jù)流

    Stream使用一種類似用SQL語(yǔ)句從數(shù)據(jù)庫(kù)查詢數(shù)據(jù)的直觀方式來(lái)提供一種對(duì)Java集合運(yùn)算和表達(dá)的高階抽象。接下來(lái)通過(guò)本文給大家分享java8中的Stream數(shù)據(jù)流知識(shí),感興趣的朋友一起看看吧
    2017-10-10
  • SpringBoot實(shí)現(xiàn)application.yml文件敏感信息加密

    SpringBoot實(shí)現(xiàn)application.yml文件敏感信息加密

    本文主要介紹了SpringBoot實(shí)現(xiàn)application.yml文件敏感信息加密,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2023-07-07
  • java 中@Deprecated 注解的實(shí)例詳解

    java 中@Deprecated 注解的實(shí)例詳解

    這篇文章主要介紹了java 中@Deprecated 注解的實(shí)例詳解的相關(guān)資料,這里對(duì)@Deprecated注解進(jìn)行了詳細(xì)介紹,希望能幫助到大家,需要的朋友可以參考下
    2017-08-08
  • spring依賴注入成功但在調(diào)用接口的時(shí)候拿到的依賴卻是null問(wèn)題

    spring依賴注入成功但在調(diào)用接口的時(shí)候拿到的依賴卻是null問(wèn)題

    這篇文章主要介紹了spring依賴注入成功但在調(diào)用接口的時(shí)候拿到的依賴卻是null問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • Java 實(shí)現(xiàn)一個(gè)漢諾塔實(shí)戰(zhàn)練習(xí)

    Java 實(shí)現(xiàn)一個(gè)漢諾塔實(shí)戰(zhàn)練習(xí)

    漢諾塔是源于印度一個(gè)古老傳說(shuō)的益智玩具。大梵天創(chuàng)造世界時(shí)做了三根石柱,在一根柱子上從下往上按大小順序摞著64片黃金圓盤。大梵天命令婆羅門把圓盤從下面開始按大小順序重新擺放在另一根柱子上。并且規(guī)定,在小圓盤上不能放大圓盤,三根柱子之間一次只能移動(dòng)一個(gè)圓盤
    2021-10-10
  • 超級(jí)詳細(xì)Java?JDK環(huán)境配置教程(Mac?版)

    超級(jí)詳細(xì)Java?JDK環(huán)境配置教程(Mac?版)

    這篇文章詳細(xì)講解了在MacOS上安裝JDK及配置Java環(huán)境的步驟,包括下載JDK安裝包、安裝JDK、查詢安裝路徑以及配置環(huán)境變量,旨在為初學(xué)者提供一份保姆級(jí)的安裝指南,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2024-10-10
  • Spring整合MyBatis圖示過(guò)程解析

    Spring整合MyBatis圖示過(guò)程解析

    這篇文章主要介紹了Spring整合MyBatis圖示過(guò)程解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-11-11
  • Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析

    Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析

    Spring的BeanFactoryPostProcessor是容器初始化的擴(kuò)展接口,允許在Bean實(shí)例化前修改或擴(kuò)展Bean的配置元數(shù)據(jù),本文給大家介紹Spring 中 BeanFactoryPostProcessor 的作用和示例源碼分析,感興趣的朋友一起看看吧
    2025-03-03
  • 使用@Service注解出現(xiàn)No bean named 'xxxx' available]錯(cuò)誤的解決

    使用@Service注解出現(xiàn)No bean named 'xxxx'&

    這篇文章主要介紹了使用@Service注解出現(xiàn)No bean named 'xxxx' available]錯(cuò)誤的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-08-08
  • Java中將base64編碼字符串轉(zhuǎn)換為圖片的代碼

    Java中將base64編碼字符串轉(zhuǎn)換為圖片的代碼

    這篇文章主要介紹了Java中將base64編碼字符串轉(zhuǎn)換為圖片,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-03-03

最新評(píng)論

奉节县| 宁河县| 酒泉市| 丽水市| 黑龙江省| 宁陕县| 奇台县| 开化县| 山西省| 蒙自县| 焦作市| 丰宁| 洛隆县| 游戏| 嘉义市| 江达县| 晋州市| 呼和浩特市| 邹平县| 小金县| 申扎县| 甘洛县| 天柱县| 齐河县| 资阳市| 盱眙县| 松原市| 伽师县| 宜丰县| 霍林郭勒市| 枣阳市| 靖边县| 南昌市| 南京市| 蒙阴县| 萍乡市| 平潭县| 都江堰市| 丁青县| 申扎县| 德格县|