我的编程空间,编程开发者的网络收藏夹
学习永远不晚

Spring data JPA只查询部分字段问题

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

Spring data JPA只查询部分字段问题

文章目录

背景

在JPA查询中,有时只需要查部分字段,这时jpa repository查出的是map,无法映射到Entity类。会提示错误:

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

网上搜索有多种解决方案。这里列举一下。经过验证,本人采取了第一种方案,证明是可行的。

JPA 2.1以上的解决办法

实体中增加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;

定义一个新的DTO对象

字段和查询的字段对应,需要提供构造函数:

@Datapublic 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中定义查询接口

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

其它方案

查询中构造新对象

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;}

上述方法是之前我项目中代码库里的写法,Blog需要提供相应的构造函数。

自己写convertor

repository 返回 Tuple 对象,自己写代码手动转换为指定对象,repository层使用native查询。
这里要借助辅助类:

class NativeResultProcessUtils {                public static <T> T processResult(Tuple source,Class<T> targetClass) {            Object instantiate = BeanUtils.instantiate(targetClass);            convertTupleToBean(source,instantiate,null);            return (T) instantiate;        }                public static <T> T processResult(Tuple source,Class<T> targetClass,String... ignoreProperties) {            Object instantiate = BeanUtils.instantiate(targetClass);            convertTupleToBean(source,instantiate,ignoreProperties);            return (T) instantiate;        }                public static void convertTupleToBean(Tuple source,Object target){            convertTupleToBean(source,target,null);        }                public static void convertTupleToBean(Tuple source,Object target, String... ignoreProperties){            //目标class            Class<?> actualEditable = target.getClass();            //获取目标类的属性信息            PropertyDescriptor[] targetPds = BeanUtils.getPropertyDescriptors(actualEditable);            //忽略列表            List<String> ignoreList = (ignoreProperties != null ? Arrays.asList(ignoreProperties) : null);            //遍历属性节点信息            for (PropertyDescriptor targetPd : targetPds) {                //获取set方法                Method writeMethod = targetPd.getWriteMethod();                //判断字段是否可以set                if (writeMethod != null && (ignoreList == null || !ignoreList.contains(targetPd.getName()))) {                    //获取source节点对应的属性                    String propertyName = targetPd.getName();                    Object value = source.get(propertyName);                    if(value!=null && ClassUtils.isAssignable(writeMethod.getParameterTypes()[0], value.getClass())) {                        try {//判断target属性是否privateif (!Modifier.isPublic(writeMethod.getDeclaringClass().getModifiers())) {    writeMethod.setAccessible(true);}//写入targetwriteMethod.invoke(target, value);                        }                        catch (Throwable ex) {throw new FatalBeanException(    "Could not copy property '" + targetPd.getName() + "' from source to target", ex);                        }                    }                }            }        }    }

使用entityManager的Transformers.aliasToBean

未验证,Spring data jpa未必支持

使用entityManager的Transforms.ALIAS_TO_ENTITY_MAP

未验证

参考链接

来源地址:https://blog.csdn.net/jgku/article/details/128581548

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

Spring data JPA只查询部分字段问题

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

如何只返回实体类中的部分字段问题

这篇文章主要介绍了如何只返回实体类中的部分字段问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
2023-05-20

java只返回实体类中的部分字段问题如何解决

这篇文章主要介绍了只返回实体类中的部分字段问题如何解决,具有一定借鉴价值,需要的朋友可以参考下。下面就和我一起来看看吧。如何只返回实体类中的部分字段在实体类上添加注解@JsonInclude(JsonInclude.Include.NON_
2023-07-06

Mysql 字段模糊查询,在页面中输入%查询全部的问题处理

一、背景   测试小妹闲着无聊,针对某一个查询项进行“%”测试,正常查询效果应该是返回空数据,但是却查出所有的数据。 二、解决方案 1、在使用mybatis的模糊查询时,有两个特殊符号需要注意: %(百分号):相当于任意多个字符; _(下划
2023-08-20

mysql 设置@@sql_mode 解决查询非分组里字段报错问题

1 查询sql_mode SELECT @@sql_mode; 2 把查询的值复制黏贴,去掉ONLY_FULL_GROUP_BY,重新设置值 SET @@sql_mode="STRICT_TRANS_TABLES,NO_ZERO_IN_DATE,NO_ZERO
2016-06-27

SQL查询之字段是逗号分隔开的数组如何查询匹配数据问题

目录字段是逗号分隔开的数组如何查询匹配数据方式一:CHARINDEX***()*****方式二:WHERE LIKEmysql逗号分隔的字段查询1.like2.find_in_set3.regexp总结字段是逗号分隔开的数组如何查询匹配数据
2023-03-06

编程热搜

目录