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

Spring data JPA只查詢(xún)部分字段問(wèn)題及解決

 更新時(shí)間:2024年08月12日 09:35:03   作者:北極象  
這篇文章主要介紹了Spring data JPA只查詢(xún)部分字段問(wèn)題及解決,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

背景

在JPA查詢(xún)中,有時(shí)只需要查部分字段,這時(shí)jpa repository查出的是map,無(wú)法映射到Entity類(lèi)。

會(huì)提示錯(cuò)誤:

org.springframework.core.convert.ConverterNotFoundException: 
No converter found capable of converting from type 
[org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap] to type

網(wǎng)上搜索有多種解決方案。這里列舉一下。

經(jīng)過(guò)驗(yàn)證,本人采取了第一種方案,證明是可行的。

JPA 2.1以上的解決辦法

實(shí)體中增加named query和result map

@SqlResultSetMapping(name = "EBookInfo",
        classes = @ConstructorResult(targetClass = EBookInfo.class,
                columns = {
                        @ColumnResult(name = "book_id", type = Long.class),
                        @ColumnResult(name = "book_name", type = String.class),
                        @ColumnResult(name = "file_type", type = String.class)
                }))
@NamedNativeQuery(name = "listExpressEbooks",
        query = "select book_id, book_name, file_type from ebook order by update_date desc",
        resultSetMapping = "EBookInfo")
@Entity
@Table(name = "ebook")
public class Ebook {

    private Long bookId;

    private Integer authorId;
    private String authorName;
    private Integer categoryId;
    private String bookName;
    private String subTitle;
    private String tags;
    private String isbn;
    private String edition;
    private Byte bookType;
    private Integer star;
    private Integer downloadCount;
    private Byte status;
    private String fileType;
    private String outline;
    private String introduction;
    private String preface;
    private String cover;
    private Float price;
    private String publisher;
    private String bgColor;
    private String foreColor;
    private String titleColor;
    private String coverBackgroundId;
    private String coverPictureId;
    private Integer coverTemplateId;
    private String coverPictureMode;
    private Integer pageMode;
    private Timestamp requestDate;
    private Timestamp publishDate;
    private Timestamp updateDate;

定義一個(gè)新的DTO對(duì)象

字段和查詢(xún)的字段對(duì)應(yīng),需要提供構(gòu)造函數(shù):

@Data
public class EBookInfo {
    private Long bookId;
    private String bookName;    
    private String fileType;

    public EBookInfo(Long bookId, String bookName, String fileType) {
        this.bookId = bookId;
        this.bookName = bookName;
        this.fileType = fileType;
    }

}

repository中定義查詢(xún)接口

    @Query(name = "listExpressEbooks", nativeQuery = true)
    public List<EBookInfo> listExpressEbooks();

其它方案

查詢(xún)中構(gòu)造新對(duì)象

public List<Blog> selectByYearMonth(String year, String month, int status) {
    String sql = String.format("select new Blog(blog.id, blog.title, blog.abs, blog.createtime) from Blog blog where blog.status = %d and YEAR(createtime) = %s and MONTH(createtime) = %s order by blog.createtime desc", status, year, month);

    //Query query = this.em.createNativeQuery(sql, "ExpressedResult");
    Query query = this.em.createQuery(sql);
    List results = query.getResultList();

    return results;
}

上述方法是之前我項(xiàng)目中代碼庫(kù)里的寫(xiě)法,Blog需要提供相應(yīng)的構(gòu)造函數(shù)。

自己寫(xiě)convertor

repository 返回 Tuple 對(duì)象,自己寫(xiě)代碼手動(dòng)轉(zhuǎn)換為指定對(duì)象,repository層使用native查詢(xún)。

這里要借助輔助類(lèi):

class NativeResultProcessUtils {

        /**
         * tuple轉(zhuǎn)實(shí)體對(duì)象
         * @param source tuple對(duì)象
         * @param targetClass 目標(biāo)實(shí)體class
         * @param <T> 目標(biāo)實(shí)體類(lèi)型
         * @return 目標(biāo)實(shí)體
         */
        public static <T> T processResult(Tuple source,Class<T> targetClass) {
            Object instantiate = BeanUtils.instantiate(targetClass);
            convertTupleToBean(source,instantiate,null);
            return (T) instantiate;
        }

        /**
         *
         * tuple轉(zhuǎn)實(shí)體對(duì)象
         * @param source tuple對(duì)象
         * @param targetClass 目標(biāo)實(shí)體class
         * @param <T> 目標(biāo)實(shí)體類(lèi)型
         * @param ignoreProperties 要忽略的屬性
         * @return 目標(biāo)實(shí)體
         */
        public static <T> T processResult(Tuple source,Class<T> targetClass,String... ignoreProperties) {
            Object instantiate = BeanUtils.instantiate(targetClass);
            convertTupleToBean(source,instantiate,ignoreProperties);
            return (T) instantiate;
        }

        /**
         * 把tuple中屬性名相同的值復(fù)制到實(shí)體中
         * @param source tuple對(duì)象
         * @param target 目標(biāo)對(duì)象實(shí)例
         */
        public static void convertTupleToBean(Tuple source,Object target){
            convertTupleToBean(source,target,null);
        }

        /**
         * 把tuple中屬性名相同的值復(fù)制到實(shí)體中
         * @param source tuple對(duì)象
         * @param target 目標(biāo)對(duì)象實(shí)例
         * @param ignoreProperties 要忽略的屬性
         */
        public static void convertTupleToBean(Tuple source,Object target, String... ignoreProperties){
            //目標(biāo)class
            Class<?> actualEditable = target.getClass();
            //獲取目標(biāo)類(lèi)的屬性信息
            PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);
            //忽略列表
            List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);

            //遍歷屬性節(jié)點(diǎn)信息
            for (PropertyDescriptor targetPd : targetPds) {
                //獲取set方法
                Method writeMethod = targetPd.getWriteMethod();
                //判斷字段是否可以set
                if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {
                    //獲取source節(jié)點(diǎn)對(duì)應(yīng)的屬性
                    String propertyName = targetPd.getName();
                    Object value = source.get(propertyName);
                    if(value!=null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) {
                        try {
                            //判斷target屬性是否private
                            if (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {
                                writeMethod.setAccessible(true);
                            }
                            //寫(xiě)入target
                            writeMethod.invoke(target, value);
                        }
                        catch (Throwable ex) {
                            throw new FatalBeanException(
                                "Could not copy property '" + targetPd.getName() + "' from source to target", ex);
                        }
                    }
                }
            }
        }

    }

使用entityManager的Transformers.aliasToBean

未驗(yàn)證,Spring data jpa未必支持

使用entityManager的Transforms.ALIAS_TO_ENTITY_MAP

未驗(yàn)證

總結(jié)

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

相關(guān)文章

  • Spring?Boot?3.x?GraalVM原生鏡像構(gòu)建內(nèi)存溢出問(wèn)題解決方案

    Spring?Boot?3.x?GraalVM原生鏡像構(gòu)建內(nèi)存溢出問(wèn)題解決方案

    文章解析了Spring?Boot?3.x與GraalVM?Native?Image構(gòu)建過(guò)程中出現(xiàn)的內(nèi)存溢出問(wèn)題,從問(wèn)題概述、根本原因、診斷工具、解決方案到高級(jí)調(diào)優(yōu)技巧和應(yīng)急解決方案,全面覆蓋了構(gòu)建優(yōu)化的各個(gè)方面,本文給大家介紹的非常詳細(xì),感興趣的朋友一起學(xué)習(xí)下吧
    2026-01-01
  • Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    Spring Boot利用Thymeleaf發(fā)送Email的方法教程

    spring Boot默認(rèn)就是使用thymeleaf模板引擎的,下面這篇文章主要給大家介紹了關(guān)于在Spring Boot中利用Thymeleaf發(fā)送Email的方法教程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看看吧。
    2017-08-08
  • 淺談SpringBoot @Autowired的兩種注入方式

    淺談SpringBoot @Autowired的兩種注入方式

    本文主要介紹了兩種SpringBoot @Autowired注入方式,具有一定的參考價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2021-06-06
  • SpringBoot常用計(jì)量與bean屬性校驗(yàn)和進(jìn)制數(shù)據(jù)轉(zhuǎn)換規(guī)則全面分析

    SpringBoot常用計(jì)量與bean屬性校驗(yàn)和進(jìn)制數(shù)據(jù)轉(zhuǎn)換規(guī)則全面分析

    這篇文章主要介紹了SpringBoot常用計(jì)量、bean屬性校驗(yàn)與進(jìn)制數(shù)據(jù)轉(zhuǎn)換規(guī)則,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧
    2022-10-10
  • 淺談拋出異常和捕獲異常的一些區(qū)別

    淺談拋出異常和捕獲異常的一些區(qū)別

    這篇文章主要介紹了拋出異常和捕獲異常的一些區(qū)別,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-06-06
  • java實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)單鏈表示例(java單鏈表)

    java實(shí)現(xiàn)數(shù)據(jù)結(jié)構(gòu)單鏈表示例(java單鏈表)

    這篇文章主要介紹了java數(shù)據(jù)結(jié)構(gòu)實(shí)現(xiàn)單鏈表示例,需要的朋友可以參考下
    2014-03-03
  • java DataInputStream和DataOutputStream詳解及實(shí)例代碼

    java DataInputStream和DataOutputStream詳解及實(shí)例代碼

    這篇文章主要介紹了java DataInputStream和DataOutputStream詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下
    2017-01-01
  • 解決mybatis使用foreach批量insert異常的問(wèn)題

    解決mybatis使用foreach批量insert異常的問(wèn)題

    這篇文章主要介紹了解決mybatis使用foreach批量insert異常的問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2021-01-01
  • Mybatis中強(qiáng)大的resultMap功能介紹

    Mybatis中強(qiáng)大的resultMap功能介紹

    這篇文章主要給大家介紹了關(guān)于Mybatis中強(qiáng)大的resultMap功能的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用Mybatis具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-06-06
  • Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之貪心算法

    Java?數(shù)據(jù)結(jié)構(gòu)與算法系列精講之貪心算法

    我們可能在好多地方都會(huì)聽(tīng)到貪心算法這一概念,并且它的算法思想也比較簡(jiǎn)單就是說(shuō)算法只保證局部最優(yōu),進(jìn)而達(dá)到全局最優(yōu)。但我們實(shí)際編程的過(guò)程中用的并不是很多,究其原因可能是貪心算法使用的條件比較苛刻,所要解決的問(wèn)題必須滿(mǎn)足貪心選擇性質(zhì)
    2022-02-02

最新評(píng)論

海门市| 句容市| 米泉市| 宝鸡市| 黎川县| 天水市| 开原市| 龙里县| 桃园县| 育儿| 莫力| 平阴县| 昭平县| 芷江| 观塘区| 保靖县| 黔西县| 沈阳市| 闽清县| 志丹县| 静宁县| 万山特区| 方城县| 秦皇岛市| 兰西县| 滦平县| 栾城县| 邓州市| 雷州市| 乐至县| 泸水县| 海安县| 金湖县| 维西| 缙云县| 紫金县| 洪江市| 安新县| 昆山市| 大关县| 佛冈县|