Open blinkfox opened 4 years ago
spring-data-jpa使用多年,自己也写了一些很实用的组件,难得看到有jpa的扩展库,使用下来感觉非常赞,唯一不足的就是不能动态映射,不能自定义实体类(VO/DTO)返回。这样就不能select自己想要的,对于稍微复杂select的sql支持不是很好。望改进,加油 !!!
@azhengZJ JPA 里面是可以将查询结果映射为自定义实体类的,你可以了解下 JPA 投影(Projection
)的用法,功能也比较强大。Fenix 的核心扩展点在动态 SQL 的支持,所以,投影也是支持的。
@blinkfox 正是因为使用了Projections未生效,所以在此留言,但是未用fenix的xml文件的动态投影都生效了,也可能是我用法不对,我继续研究研究!
@blinkfox 各种方式都尝试了,确实不支持,如果支持的话,希望能提供一下文档,感谢!
@azhengZJ 我自己测试就是支持的,不晓得你的为啥不行,或者有报什么错之类的,发出来我看看。
@blinkfox
这是定义接口的地方
@QueryFenix
List<FenixVO> queryByXML(@Param("params") ReqMailMessageVO params);
这是xml
<fenix id="queryByXML" removeIfExist="1 = 1 AND ">
SELECT
a.id,
a.content
FROM
MailMessage AS a
WHERE
1 = 1
<andLike field="a.content" value="params.content" match="params.content != empty"/>
</fenix>
这是调用的地方
List<FenixVO> list = repository.queryByXML(vo);
这是返回的VO
import lombok.Value;
@Value
public class FenixVO {
private Long id;
private String content;
}
报错如下
Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.Long] to type [com.zuji.msgdemo.entity.vo.FenixVO]
@azhengZJ 你这个不是投影的用法吧,投影的话,你需要自己定义一个接口,接口中的方法其实就对应着你自定义 Bean 里面的 Getter
方法,当然还可以增加其他扩展或者需要预处理的方法。你可以参看我单元测试里面的 queryUserBlogsByProjection
方法的写法:
-BlogRepositoryTest -BlogRepository -UserBlogProjectio
除了使用投影的方式之外,你的示例场景,可以直接在你的实体类中,定义一个只有这两个值的构造方法,用 select new MailMessage(id, content)
的方式也行。
@blinkfox 投影的类型可以是接口也可以是类。 基于接口的投影,须提供字段对应的get方法接口。
interface NamesQueryDTO {
String getFirstname();
String getLastname();
}
基于类的投影,定义好所有查询字段,并且提供全参构造器。强烈推荐 使用Lombok的@Value注解 简化代码。
@Value
class NamesOnlyDTO {
String firstname, lastname;
}
https://blog.csdn.net/qq_41959009/article/details/101363309 之前写过相关博客,定义成接口也没关系,只要支持就行,通常还是使用类更方便。
测试了一下 ,对接口确实是支持的,对类的方式还是不支持,new对象的方式我也知道,这种方式我不太喜欢用,因为需要创建对应的构造方法,而且构造方法和select字段的顺序有强一致性的要求,这个就增加了开发难度,而且后期构造方法或者select字段顺序不小心被改动都会影响到它的正常执行。不过能支持接口已经满足我的需求,感谢!
@azhengZJ 也是支持类的,就在刚才的的几个单元测试文件中,有类的情况,单测方法为:queryUserBlogsByTitleWithFenix
,其中的 XML 写法在 BlogRepository.xml 文件中,fenixId 为 queryUserBlogsByTitleWithFenix
,JPA 里面自定义的类是必须要用 new
和对应的构造方法的方式才行。
要想只通过字段名字来对应,不用写 new 的话,除非想办法做成 MyBatis 里面那样,XML 中定义一个 ResultMap,对应具体的实体类,将各个结果字段通过反射的 Setter 方法来注入到结果对象中才行,JPA 里面是不行的。
Fenix 目前的 SQL 执行都是使用 JPA 自身提供的,没有做过额外处理。
@blinkfox 好的 ,理解的,感谢!
@blinkfox :thumbsup: 效率非常高,这个功能很实用。
o
博主,我发现一个bug,苹果safari浏览器浏览显示的文章访问次数不对
https://blinkfox.github.io/2019/08/20/hou-duan/jpa/fenix-bi-mybatis-geng-jia-qiang-da-de-spring-data-jpa-kuo-zhan-ku/
Fenix(菲尼克斯)是一个比 MyBatis 更加强大,为解决复杂、动态 SQL (JPQL) 而生的 Spring Data JPA 扩展库,目的是辅助开发者更方便、快捷的书写复杂、动态且易于维护的 SQL,支持 XML 和 Java