最强ORM让你开发效率提升百倍
easy-query在经过2年的迭代目前已经在查询领域可以说是无敌的存在,任何orm都不是对手,这几年的功能点简单罗列一下
[x] 动态join:查询涉及到对应的关系表就会自动添加join反之则不会讲join加入到sql中(2025年了感觉也不是什么新鲜特性了)
[x] 结构化DTO,自动根据DTO和表关系的路径自动筛选出需要的结构化属性(开发效率杀手)
[x] 结构化DTO额外配置,支持结构化DTO的返回下还能额外添加查询条件和筛选条件
[x] 隐式PARTITION BY
[X] 隐式子查询
[x] 子查询转GroupJoin全世界应该是独一份的功能,解决多对多深层关系在ORM中的子查询过多导致的性能问题真正解决了ORM在复杂查询下开发效率和性能的兼顾
框架地址 https://github.com/dromara/easy-query
文档地址 https://www.easy-query.com/easy-query-doc/
该文章demo地址 https://github.com/xuejmnet/eq-doc
刚好前几天我看到公众号有篇关于efcore的性能文章,我看了其实我一眼就知道了他的问题就是eq的子查询转GroupJoin但是正如强大的efcore也是没有实现该功能,话不多说本章节我们将入门通过公众号的demo实现大部分帖子相关的查询和功能
建模
实体关系如下:
- 用户User:每个用户有多篇帖子和多条评论和多个点赞
- 分类Category:帖子所属分类类目支持多个分类一个帖子或者多个帖子公用同一个分类
- 帖子Post:每篇帖子有多个分类并可获得多个赞
- 评论Comment:每条评论属于一个用户并关联一篇帖子 且评论支持楼中楼
- 点赞Like:每个赞关联一篇帖子,多个点赞可以关联同一篇帖子
- 分类帖子关联CategoryPost:帖子和分类的关联关系表
点击查看实体代码- @Data
- @Table("t_user")
- @EntityProxy
- @EasyAlias("t_user")
- @EasyAssertMessage("未找到对应的用户信息")
- public class User implements ProxyEntityAvailable<User , UserProxy> {
- @Column(primaryKey = true,comment = "用户id")
- private String id;
- @Column(comment = "用户姓名")
- private String name;
- @Column(comment = "用户手机")
- private String phone;
- @Column(comment = "创建时间")
- private LocalDateTime createAt;
- }
- @Data
- @Table("t_category")
- @EntityProxy
- @EasyAlias("t_category")
- @EasyAssertMessage("未找到对应的类目信息")
- public class Category implements ProxyEntityAvailable<Category , CategoryProxy> {
- @Column(primaryKey = true,comment = "类目id")
- private String id;
- @Column(comment = "类目姓名")
- private String name;
- @Column(comment = "类目排序")
- private Integer sort;
- }
- @Data
- @Table("t_post")
- @EntityProxy
- @EasyAlias("t_post")
- @EasyAssertMessage("未找到对应的帖子信息")
- public class Post implements ProxyEntityAvailable<Post, PostProxy> {
- @Column(primaryKey = true,comment = "帖子id")
- private String id;
- @Column(comment = "帖子标题")
- private String title;
- @Column(comment = "帖子内容")
- private String content;
- @Column(comment = "用户id")
- private String userId;
- @Column(comment = "发布时间")
- private LocalDateTime publishAt;
- }
- @Data
- @Table("t_comment")
- @EntityProxy
- @EasyAlias("t_comment")
- @EasyAssertMessage("未找到对应的评论信息")
- public class Comment implements ProxyEntityAvailable<Comment , CommentProxy> {
- @Column(primaryKey = true,comment = "评论id")
- private String id;
- @Column(comment = "父id")
- private String parentId;
- @Column(comment = "帖子内容")
- private String content;
- @Column(comment = "用户id",nullable = false)
- private String userId;
- @Column(comment = "帖子id",nullable = false)
- private String postId;
- @Column(comment = "回复时间")
- private LocalDateTime createAt;
- }
- @Data
- @Table("t_like")
- @EntityProxy
- @EasyAlias("t_like")
- @EasyAssertMessage("未找到对应的点赞信息")
- public class Like implements ProxyEntityAvailable<Like , LikeProxy> {
- @Column(primaryKey = true,comment = "评论id")
- private String id;
- @Column(comment = "用户id",nullable = false)
- private String userId;
- @Column(comment = "帖子id",nullable = false)
- private String postId;
- @Column(comment = "点赞时间")
- private LocalDateTime createAt;
- }
- @Data
- @Table("t_category_post")
- @EntityProxy
- @EasyAlias("t_category_post")
- @EasyAssertMessage("未找到对应的类目帖子关联信息")
- public class CategoryPost implements ProxyEntityAvailable<CategoryPost , CategoryPostProxy> {
- @Column(primaryKey = true,comment = "评论id")
- private String id;
- @Column(comment = "帖子id",nullable = false)
- private String postId;
- @Column(comment = "类目id",nullable = false)
- private String categoryId;
- }
复制代码 帖子相关查询
帖子分页
对Post表进行分页按publishAt倒序进行排序按title进行搜索
首先我们定一个公用类- @Data
- public class PageRequest {
- private Integer pageIndex=1;
- private Integer pageSize=5;
- }
复制代码 定义请求参数- @Data
- public class PostPageRequest extends PageRequest {
- private String title;
- }
复制代码 分页动态条件
- @PostMapping("/page")
- public EasyPageResult<Post> page(@RequestBody PostPageRequest request) {
- return easyEntityQuery.queryable(Post.class)
- .where(t_post -> {
- // if(EasyStringUtil.isNotBlank(request.getTitle())){
- // t_post.title().contains(request.getTitle());
- // }
- t_post.title().contains(EasyStringUtil.isNotBlank(request.getTitle()),request.getTitle());
- })
- .orderBy(t_post -> t_post.publishAt().desc())
- .toPageResult(request.getPageIndex(),request.getPageSize());
- }
复制代码 这边提供了两种方式实现动态查询,当title不为空的时候加入表达式筛选,执行我们来看看实际情况
- 使用if函数包裹表达式断言,支持任意java表达式
- 使用断言函数第一个参数重载,默认第一个参数为true才会执行断言操作
- 使用where重载第一个参数为true执行当前where
请求参数- {"pageIndex":1,"pageSize":5,"title":"电影"}
复制代码- ==> Preparing: SELECT COUNT(*) FROM `t_post` WHERE `title` LIKE CONCAT('%',?,'%')
- ==> Parameters: 电影(String)
- ==> Preparing: SELECT `id`,`title`,`content`,`user_id`,`publish_at` FROM `t_post` WHERE `title` LIKE CONCAT('%',?,'%') ORDER BY `publish_at` DESC LIMIT 3
- ==> Parameters: 电影(String)
复制代码 container还是like!!!
> 细心地朋友会发现我们使用了contains函数而不是like函数,因为当传入的查询条件本身带有%时那么like会让%变成通配符,而contains会将%视为被查询的一部分,这是需要用户注意的,具体使用contains还是like应该有用户自行决断
推荐写法
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |