对比 MyBatis,你看出什么端倪?

2020-12-11 16:34:54 +08:00
 Braisdom

项目地址: https://github.com/braisdom/ObjectiveSql

1 简单查询

@DomainModel
public class Blog {
    private Long id;
    private String title;
    private Integer state;
    @Relation(relationType = RelationType.BELONGS_TO)
    private Author author;
}

根据单字段查询

MyBatis ObjectiveSQL
public interface BlogMapper {
  @Select("SELECT * FROM blog WHERE id = #{id}")
  Blog selectBlog(int id);
}
...
BlogMapper mapper = session.getMapper(BlogMapper.class); 
Blog blog = mapper.selectBlog(i);
Blog blog = Blog.queryByPrimaryKey(1);

稍微复杂一点的查询

MyBatis ObjectiveSQL
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="findByTitle" resultType="Blog">
    select * from Blog where title like  '%#{title}%'
  </select>
</mapper>
...
BlogMapper mapper = session.getMapper(BlogMapper.class); 
Blog blog = mapper.findByTitle("标题");
public static Blog queryByTitle(String title) {
     Query<Blog> query = createQuery();
     query.where("title like ?",  "%" + title + "%");
     return query.queryFirst();
}
...
Blog blog = Blog.queryByTitle(1);

2 复杂查询

动态查询

MyBatis ObjectiveSQL
<select id="findActiveBlogLike"
     resultType="Blog">
  SELECT * FROM BLOG
  WHERE
  <if test="state != null">
    state > #{state}
  </if>
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="author != null and author.name != null">
    AND author_name like #{author.name}
  </if>
</select>
...
BlogMapper mapper = session.getMapper(BlogMapper.class); 
Blog blog = mapper.findActiveBlogLike(...);
Blog.Table blog = Blog.asTable();
Select select = new Select();
LogicalExpression eternalExpression = new EternalExpression();
if(state != null)
     eternalExpression = eternalExpression.and(blog.state > state);
if(title != null)
     eternalExpression = eternalExpression.and(blog.title.like(title));
if(author != null && author.name != null)
     eternalExpression = eternalExpression.and(blog.author.like(author.name));
return select.from(blog).where(eternalExpression).execute();

关联查询

MyBatis ObjectiveSQL
<mapper>
  <resultMap type="Blog" id="blog">
    <id column="id" property="id" />
    ...
    <association property="author" javaType="Author">
      ...
    </association>
  </resultMap>
  <select id="findBlog" parameterType="int" resultMap="blog">
    ...
  </select>
</mapper>
...
BlogMapper mapper = session.getMapper(BlogMapper.class); 
Blog blog = mapper. findBlog(...);
Blog blog = Blog.queryByPrimaryKey(1, 
                    Blog.BELONGS_TO_AUTHOR)
9972 次点击
所在节点    Java
103 条回复
lower
2020-12-12 14:15:57 +08:00
那个说的操作符重载 是怎么弄的?看了代码没太看懂
类似这样:eternalExpression = eternalExpression.and(blog.state > state);
C603H6r18Q1mSP9N
2020-12-12 14:18:50 +08:00
php 既视感,支持下,感觉 php 更简单点,请继续努力:

$blog = db('blog')->find(1);

$res = db('blog')->whereLike('title', $title)->select();

if ($state) $where['state'] = ['>', $state];
if ($title) $where['title'] = ['like', $title];
$res = db('blog')->where($where)->select();

$blog = db('blog')->with('author')->find(1);
Braisdom
2020-12-12 14:24:33 +08:00
@shanghai1998 简单的表达式,每个框架和语言差别不大,一个项目中存在大量复杂表达式,那些都是关键,php 的复杂表达式写起来估计那没这么美观。

你写的这些每个语言,或者 ORM 框架都差不了太多,最多的就是对符号的偏好不同罢了。


@lower 那块比较复杂,不是简单能说清楚的。有兴趣加我微信:braisdom
hantsy
2020-12-12 14:31:27 +08:00
@Braisdom 为了 SQL 看起来更清楚,不必要的条件就直接过滤掉,不喜欢用 Or 把所有条件考虑都加进去。
https://github.com/hantsy/helidon-sample/blob/master/mp-jpa/src/main/java/com/example/PostRepository.java#L38
Braisdom
2020-12-12 14:43:31 +08:00
@hantsy 只是一个示例,算术表达式,比较表达式,逻辑表达式、函数调用 这几种在 SQL 中是最为常用的,也是每个语言都有的,但不同语言的表现形式是不一样的。

我只是使的 Java 中的上述表达式 能够直接转换,保持统一的编码样式,而不是通过其它形式的封装,大部分 ORM 框架,包括 Spark SQL, Flink SQL 等 SQL 编程都是通过函数来实现,例如:plus(a, b), minus(a, b) 等,这种形式会使得代码可读性极差。
lispczz
2020-12-12 14:49:36 +08:00
这个项目我挺喜欢。但是我想说,我已经在 V2EX 首页看到至少三次这个项目了,感受都快有点像知乎看到 圆胖肿 或者 微博看到 阚清子 了。
sagaxu
2020-12-12 14:54:52 +08:00
mybatis 不是 orm,只是个裸 query builder,选用它的人,大概率是嫌弃 orm 的,可能不需要一个更好的 orm 。

任何 dsl 都有学习成本,在 dsl 和 sql 之间来回翻译,需要对 dsl 内部非常熟悉,否则稍微复杂一点点的逻辑就会卡住不知道怎么下手。还有一些时候要用到 db 特有的功能,没有比裸写 sql 更简单的办法了。
Braisdom
2020-12-12 14:55:19 +08:00
@lispczz 哈哈,现在才刚刚开始,项目已经初步的稳定,但未来的路还很长,需要更多的人认可,并能参与进来。

v2ex 是个很好的平台,是我在推广过程中,回复和评论最多的一个平台,与大家在一起讨论,收获颇多,感谢各位的支持,希望得到更多批评与挑战。
young1lin
2020-12-12 14:58:51 +08:00
主要是 MyBatis 是个会写 SQL 的人都能上手,JPA 和 Hibernate 比较难一点点,还有历史遗留问题。
felixin
2020-12-12 15:11:15 +08:00
怎么用函数呢?比如 postgres 里面的 json 操作函数,能给个例子看看吗
beidounanxizi
2020-12-12 15:12:42 +08:00
写过 Go 原生 和 gorm 以及 mybatis 最舒服 最 instinct 的还是原生的
不想用 orm 的原因是因为 写数据库的查询 用原生 sql 优化也方便
Braisdom
2020-12-12 16:48:47 +08:00
@young1lin 这要去研究一下 SQL 和 ORM 的发展史了,你就能明白为什么会有 ORM 这种形式的框架,为什么数据库不像 TCP/IP,HTTP,SMTP 等交换协议一样,泛泛的讨论框架的区别没有太大意义,每个框架的出现代表一个时代的认知水平,人的认知随时间一直在变的。ObjectiveSQL 的出现也是基于前人的认知升级而已。
quan01994
2020-12-12 17:40:31 +08:00
下面的复杂表达式计算,现有的所有 ORM 框架都做不到。。
你是指 java 的 orm 吗。

C# 还是有很多能做到的。
kran
2020-12-12 17:53:01 +08:00
很喜欢这个项目。也很佩服楼主的技术和沟通能力。

就是没看懂那个运算符重载。。。
NeinChn
2020-12-12 18:10:47 +08:00
这不就是简单场景没必要,复杂场景学习成本高么

举个例子,我们线上数据库都是同一套,因此要做线上隔离全靠表名区别

以 members 为例,staging 环境的表名是 members_staging

你这个文档写的真的不清不楚,根本没办法通过文档决定怎么开发

简单看了下代码,DomainModel 的 tableName 或者 class 的 getSimpleName 。

那我一个 domain 用在多个表上还要搞 2 个类么?

真的有时间,建议完善下文档,至少做到 MyBatis 的文档水平,再做宣传。

想让别人做什么事情都看源代码解决是不现实的事情,有的是太菜看不懂源代码,有的是太忙没有时间花在读这种代码上。
Braisdom
2020-12-12 20:32:21 +08:00
@quan01994 .net 的 entity framework 我参考了很多,表达式这块它可以做的,但有很多做了。
Braisdom
2020-12-12 20:35:46 +08:00
@NeinChn 兄弟,不同部署环境应该通过数据库区分,例如:开发环境 development, 测试环境 test,生产环境 production, 我实在不明白,你为什么用表名去区分不同的部署环境,
Braisdom
2020-12-12 20:37:20 +08:00
@kran 私下交流,请加我,Java 的运算符重载是个特殊的应用,加我微信: braisdom
NeinChn
2020-12-12 21:28:15 +08:00
@Braisdom 你这是没见过 staging 么.....
Braisdom
2020-12-12 21:33:02 +08:00
@NeinChn 我理解你的意思了,如果数据是暂时存储,一般通过内存数据库 Redis 类型的,如果是数据库的中间状态可以通过继承的方式存在,数据库中理论上不应该存在一模一样的表结构。

我的理解不一定正确,如果有问题,恳请你明示,感谢支持。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://tanronggui.xyz/t/734572

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX