Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fenix — 比 MyBatis 更加强大的 Spring Data JPA 扩展库 | 闪烁之狐 #80

Open
blinkfox opened this issue Aug 21, 2019 · 16 comments

Comments

@blinkfox
Copy link
Owner

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

Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
Repository owner deleted a comment from Cherrison Sep 9, 2019
@azhengZJ
Copy link

azhengZJ commented Oct 6, 2019

spring-data-jpa使用多年,自己也写了一些很实用的组件,难得看到有jpa的扩展库,使用下来感觉非常赞,唯一不足的就是不能动态映射,不能自定义实体类(VO/DTO)返回。这样就不能select自己想要的,对于稍微复杂select的sql支持不是很好。望改进,加油 !!!

@blinkfox
Copy link
Owner Author

blinkfox commented Oct 7, 2019

@azhengZJ JPA 里面是可以将查询结果映射为自定义实体类的,你可以了解下 JPA 投影(Projection)的用法,功能也比较强大。Fenix 的核心扩展点在动态 SQL 的支持,所以,投影也是支持的。

@azhengZJ
Copy link

azhengZJ commented Oct 7, 2019

@blinkfox
正是因为使用了Projections未生效,所以在此留言,但是未用fenix的xml文件的动态投影都生效了,也可能是我用法不对,我继续研究研究!

@azhengZJ
Copy link

azhengZJ commented Oct 7, 2019

@blinkfox
各种方式都尝试了,确实不支持,如果支持的话,希望能提供一下文档,感谢!

@blinkfox
Copy link
Owner Author

blinkfox commented Oct 7, 2019

@azhengZJ 我自己测试就是支持的,不晓得你的为啥不行,或者有报什么错之类的,发出来我看看。

@azhengZJ
Copy link

azhengZJ commented Oct 7, 2019

@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]

@blinkfox
Copy link
Owner Author

blinkfox commented Oct 7, 2019

@azhengZJ 你这个不是投影的用法吧,投影的话,你需要自己定义一个接口,接口中的方法其实就对应着你自定义 Bean 里面的 Getter 方法,当然还可以增加其他扩展或者需要预处理的方法。你可以参看我单元测试里面的 queryUserBlogsByProjection 方法的写法:

-BlogRepositoryTest
-BlogRepository
-UserBlogProjectio

除了使用投影的方式之外,你的示例场景,可以直接在你的实体类中,定义一个只有这两个值的构造方法,用 select new MailMessage(id, content) 的方式也行。

@azhengZJ
Copy link

azhengZJ commented Oct 8, 2019

@blinkfox
投影的类型可以是接口也可以是类。
基于接口的投影,须提供字段对应的get方法接口。

interface NamesQueryDTO {

  String getFirstname();
  String getLastname();
  
}

基于类的投影,定义好所有查询字段,并且提供全参构造器。强烈推荐 使用Lombok的@value注解 简化代码。

@Value
class NamesOnlyDTO {
	String firstname, lastname;
}

@azhengZJ
Copy link

azhengZJ commented Oct 8, 2019

https://blog.csdn.net/qq_41959009/article/details/101363309
之前写过相关博客,定义成接口也没关系,只要支持就行,通常还是使用类更方便。

@azhengZJ
Copy link

azhengZJ commented Oct 8, 2019

测试了一下 ,对接口确实是支持的,对类的方式还是不支持,new对象的方式我也知道,这种方式我不太喜欢用,因为需要创建对应的构造方法,而且构造方法和select字段的顺序有强一致性的要求,这个就增加了开发难度,而且后期构造方法或者select字段顺序不小心被改动都会影响到它的正常执行。不过能支持接口已经满足我的需求,感谢!

@blinkfox
Copy link
Owner Author

blinkfox commented Oct 8, 2019

@azhengZJ 也是支持类的,就在刚才的的几个单元测试文件中,有类的情况,单测方法为:queryUserBlogsByTitleWithFenix,其中的 XML 写法在 BlogRepository.xml 文件中,fenixId 为 queryUserBlogsByTitleWithFenix,JPA 里面自定义的类是必须要用 new 和对应的构造方法的方式才行。

要想只通过字段名字来对应,不用写 new 的话,除非想办法做成 MyBatis 里面那样,XML 中定义一个 ResultMap,对应具体的实体类,将各个结果字段通过反射的 Setter 方法来注入到结果对象中才行,JPA 里面是不行的。

Fenix 目前的 SQL 执行都是使用 JPA 自身提供的,没有做过额外处理。

@azhengZJ
Copy link

azhengZJ commented Oct 8, 2019

@blinkfox 好的 ,理解的,感谢!

@blinkfox
Copy link
Owner Author

@azhengZJ Fenix v1.1.0 版本支持返回自定义实体对象了,这是使用使用示例

@azhengZJ
Copy link

@blinkfox 👍 效率非常高,这个功能很实用。

@deepthan
Copy link

deepthan commented Jan 6, 2020

o

@chenxinshinian
Copy link

博主,我发现一个bug,苹果safari浏览器浏览显示的文章访问次数不对

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants