在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目前支持SELECTINSERTUPDATEDELETETRUNCATEMERGE。您可以像这样创建 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 UPDATEFOR UPDATELOCK 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字符串的好方法?的主要内容,如果未能解决你的问题,请参考以下文章

在 Oracle 中生成动态 SQL

如何在 Java 中生成 SALT 值?

sql 在mysql #mysql中生成随机字符串

在Java中生成随机单词?

在 Java 中生成当前时间戳

在Java中生成一个随机字符串[关闭]