我想我也应该在这里回答,因为我在一个半月前开始使用jooq,所以我有一些经验。
我想使用像jooq这样的工具,因为:
- ORM在我当前的项目(集群的分布式计算平台)中是一个过度的,因为我只需要读取和写入来自db的单独字段,而不是完整的表行,并且我的一些查询足够复杂,不能由简单轻量级的ORM执行。
- 我想要为我的查询自动完成语法,这样我就不需要记住我的整个数据库
- 我希望能够直接在Java中编写查询,以便编译器可以在构建时检查基本的查询语法。
- 我希望我的查询是类型安全的,这样我就不会意外地传递一种类型的变量,而另一种类型的变量是预期的。
- 我想要SQL,但我希望它非常方便和易于使用
好吧,通过jooq,我能够实现这一切。我的主要要求是jooq处理足够复杂的查询(嵌套,分组等)。这一点得到了满足。
我还希望能够使用尽可能少的代码行运行查询,并且能够通过jooq fluent API来实现这一点,该API允许类似jquery的调用来执行SELECT。
在我使用jooq的路上,我报告了一两个错误,我必须说,它们修复得非常快。
我也错过了一些功能,我必须再次说,我已经拥有了几乎所有的功能。
我非常喜欢的是,jooq现在使用SLF4J来报告一些关于它性能的非常有趣的数据,以及输出它所构建的实际查询。它真的帮助我进行了调试。
Jooq甚至为存储过程,UDF和可更新的记录集生成Java工件,不过,我目前没有使用它们。
重要的是,jooq透明地支持DB2,Derby,H2,HSQLDB,MySQL,Oracle,PostGreSQL,SQLite,SQL Server,Sybase SQL Anywhere。我认为,这个列表相当广泛。
Jooq在Google群组中有支持论坛,Lukas日夜准备回答我最愚蠢的问题。
Jooq支持Maven,这对我来说是一个很大的解脱,因为我所有的Java项目都是基于Maven的。我们仍然想念生成器的Maven插件,但这并不重要,因为运行生成器是小菜一碟。
用jooq编写我的查询时,我突然发现它们变得非常可移植,因为我几乎从未在代码中使用过任何MySQL特定的功能,因为jooq试图尽可能地可移植。对于那些不能忍受这种特殊性的人来说,因为我知道对SQL扩展的支持也在进行中。
从我的角度来看,jooq暂时缺乏什么?
好吧,除了SELECT之外,没有用于语句的流畅API。这会使代码变得有点复杂,并使 UPDATE/DELETE 语句编写起来更加复杂。但我认为这将很快被添加。刚刚在 1.5.9 中实现!医 管 局!对我来说太快了 ;)
还有一件事。Jooq有一个很好的手册,但是...我不知道。可能是我只是不明白它的结构或架构...当我第一次开始使用jooq时,我打开了一个又一个页面,寻找我需要的功能。例如,尝试猜测,在jooq手动UPDATE和DELETE语句中描述的地方,查看内容...但我相信,这真的很主观。我甚至无法解释,从我的角度来看,手动有什么问题。如果可以的话,我会发布一两张票;)
手动也不是很好的导航,因为Trac没有自动的“这里,那里和后面”的链接。
好吧,对于莫斯科(俄罗斯)的我来说,Trac页面也无法快速打开,因此阅读手册有点无聊。
Manual还错过了对贡献者的jooq的良好架构描述。Jooq遵循合同设计原则,当我想通过在IDE中对某些方法名称使用我通常的Ctrl-Click来学习如何在内部实现某些功能时,我最终进入了一个沉闷的界面,没有实现;)并不是说我太聪明了,不能立即开始改进jooq,但我当然会喜欢了解jooq是如何从头开始构建的。
同样遗憾的是,我们无法为jooq手册做出贡献。我期望它在某种wiki中。
我还想改进的是新闻报道的方式。我更喜欢链接到手册或示例这个或那个新功能是如何工作的。
手册中的发行说明链接实际上只是一个路线图。我想,我明天会自己做那个...
Jooq目前也有相对较小的社区,但我很高兴地报告,它不会影响代码质量或新功能的引入方式。
Jooq真的是一个好项目。我也会在我未来的项目中坚持下去。我真的很喜欢它。
您还可以查看MentaBean,这是一个轻量级的ORM和SQL Builder,可让您尽可能接近SQL,从而在样板代码方面提供很多帮助。下面是一个示例:
编程配置:
private BeanConfig getUserBeanConfig() {
// programmatic configuration for the bean... (no annotation or XML)
BeanConfig config = new BeanConfig(User.class, "Users");
config.pk("id", DBTypes.AUTOINCREMENT);
config.field("username", DBTypes.STRING);
config.field("birthdate", "bd", DBTypes.DATE); // note that the database column name is different
config.field("status", new EnumValueType(User.Status.class));
config.field("deleted", DBTypes.BOOLEANINT);
config.field("insertTime", "insert_time", DBTypes.TIMESTAMP).defaultToNow("insertTime");
return config;
}
// create table Users(id integer primary key auto_increment,
// username varchar(25), bd datetime, status varchar(20),
// deleted tinyint, insert_time timestamp)
一个简单的 SQL 联接查询:
Post p = new Post(1);
StringBuilder query = new StringBuilder(256);
query.append("select ");
query.append(session.buildSelect(Post.class, "p"));
query.append(", ");
query.append(session.buildSelect(User.class, "u"));
query.append(" from Posts p join Users u on p.user_id = u.id");
query.append(" where p.id = ?");
stmt = conn.prepareStatement(query.toString());
stmt.setInt(1, p.getId());
rset = stmt.executeQuery();
if (rset.next()) {
session.populateBean(rset, p, "p");
u = new User();
session.populateBean(rset, u, "u");
p.setUser(u);
}
-
如何使用Java中的RESTful Web服务获取远程/客户端IP地址? 我已经在我的项目中编写了Rest Web服务。Web服务调用可能来自不同 machine.so 我需要通过REST Web服务找出IP地址。 从这个请求.getRemoteAddr()使用这个。 但是我不能使用getRemoteAddr()。因为我的请
-
从包含大量文件的zip文件中提取1文件的最快方法是什么? 我尝试了但它们也缺少一些东西。 LZMA SDK不提供一种如何使用的文档/教程,这非常令人沮丧。没有 javadoc。 虽然7z jbinding没有提供一种简单的方法来只提取1个文件,但是,它只提供了提取zip文件
-
输入/输出流在销毁时是否关闭? Java 中的 InputStreams 和 OutputStreams 是否在销毁时关闭()?我完全理解这可能是不好的形式(特别是在C和C++世界中),但我很好奇。 另外,假设我有以下代码: 无名的FileInputStream是否在p.load
-
Java 程序中的字符串大小是否有任何限制? 我有一个字符串定义为 字符串 xx 我可以分配的字符数是否有任何限制? 2) 我正在将用户输入分配给此字符串 xx。70%的人只说一个字。有时他们给出一个大句子,所以想知道可
-