在java中生成SQL字符串的好方法?
Posted
技术标签:
【中文标题】在java中生成SQL字符串的好方法?【英文标题】:Good way to generate SQL strings in java? 【发布时间】:2011-10-22 10:18:07 【问题描述】:我不是在寻找像 Hibernate 这样的持久层,我只是想生成 SQL 字符串,它们应该与 PreparedStatement
兼容。我试过Squiggle之类的库,但它只支持SELECT
,我也想生成插入和更新。理想的用法是:
generateInsertOn("myTable").addValue("value1").addValue("value2").generate();
会生成这个字符串:
"INSERT INTO myTable (value1, value2) VALUES(?, ?)"
我知道存在与我很相似的问题,例如this,但他们问的问题和我不一样。
【问题讨论】:
如果您已经知道有类似的问题,那么您可以告诉我们这些问题很好。但是告诉我们为什么这些问题不是你想要的会更好! 你自己写有什么问题? hibernate 有什么问题,它很棒...... @NimChimpsky,如果你想完全控制你的渲染的 SQL,我认为 Hibernate 不适合这项工作...... @NimChimpsky:Hibernate 有很多用途,但当您想控制 SQL 时就不行了。在许多 RDBMS 和大型系统中,如果您不控制 SQL,那么您注定要失败。考虑向 Oracle 查询添加提示,或微调嵌套的LEFT OUTER JOIN
表达式、集成存储过程等。但是我们不知道 OP 的意图,所以我们不要开始讨论......
【参考方案1】:
你应该明确地看看SQLBuilder。它允许使用非常流畅的 API 生成简单但完整的 SQL。
【讨论】:
SQLBuilder 是否仍处于活动状态?最近的历史似乎没有很多更新...sourceforge.net/projects/openhms/files/sqlbuilder 有效吗?我的意思是,我不知道,我没用过。但如果它有效,谁在乎它是否有效? 好吧,这取决于 OP 是否正在寻找快速而肮脏的工作的工具,或者他是否需要再忍受这个决定一段时间。以 Xalan 为例。它工作得很好,但它根本不活跃。有一些重要的未解决问题可能永远不会得到解决......:-/ @Lukas_Eder 您在这里谈论的是 Xalan 还是 SQLBuilder?我知道您想为 JOOQ 辩护,因为您是代码作者(我绝对不想最小化这一点),但我没有找到很好的政策来立即驳回其他不明确问题的框架(换句话说,如果你发现 SQLBuilder 遗漏了一些重要的点,把它们写下来或者不要谈论它们,但请不要说它们有 bug,我认为你在 JOOQ 中也有)。 哈哈,你们法国人 :-) 所以,现在我明白了。我实际上指的是 Xalan。最新版本位于2007。所以我认为它不活跃。【参考方案2】:对于任意 SQL,请使用 jOOQ。 jOOQ目前支持SELECT
、INSERT
、UPDATE
、DELETE
、TRUNCATE
和MERGE
。您可以像这样创建 SQL:
// Since you're not executing the SQL, set connection to null
Connection connection = null;
Factory create = new mysqlFactory(connection);
String sql1 = create.select(A, B, C)
.from(MY_TABLE)
.where(A.equal(5))
.and(B.greaterThan(8))
.getSQL();
String sql2 = create.insertInto(MY_TABLE)
.values(A, 1)
.values(B, 2)
.getSQL();
String sql3 = create.update(MY_TABLE)
.set(A, 1)
.set(B, 2)
.where(C.greaterThan(5))
.getSQL();
支持的语法非常丰富。您还将找到对诸如ON DUPLICATE KEY UPDATE
、FOR UPDATE
、LOCK IN SHARE MODE
等子句的支持。
更多详情,请参阅
http://www.jooq.org
(免责声明,我在 jOOQ 背后的公司工作)
【讨论】:
有没有办法在不为我的表生成类的情况下使用它? @wutzebaer:查看 plain SQL 相关手册页:jooq.org/doc/2.5/manual/sql-building/plain-sql【参考方案3】:在这里,你有没有考虑过iBatis?这是一个真正脚踏实地的查询映射框架(我不愿以某种方式称其为 ORM 框架)。您必须像这样创建 XML 文件:
<mapper namespace="org.mybatis.jpetstore.persistence.ProductMapper">
<cache />
<select id="getProduct" parameterType="string" resultType="Product">
SELECT
PRODUCTID,
NAME,
DESCN as description,
CATEGORY as categoryId
FROM PRODUCT
WHERE PRODUCTID = #productId
</select>
</mapper>
像这样连接一个映射器:
public interface ProductMapper
Product getProduct(String productId);
这允许您从以下服务访问数据:
@Autowired
private ProductMapper productMapper;
public Product getProduct(String productId)
return productMapper.getProduct(productId);
你可以用 Spring 连接起来:
<!-- enable autowire -->
<context:annotation-config />
<!-- enable transaction demarcation with annotations -->
<tx:annotation-driven />
<!-- define the SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="typeAliasesPackage" value="org.mybatis.jpetstore.domain" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="org.mybatis.jpetstore.persistence" />
</bean>
另见the full petstore example。
我不是 iBatis 的忠实粉丝,但它可能适合您在这种特定情况下的需求。
【讨论】:
以上是关于在java中生成SQL字符串的好方法?的主要内容,如果未能解决你的问题,请参考以下文章