在Java代码中是否有将SQL查询表示为对象的库?

在Java代码中是否有将SQL查询表示为对象的库?,java,sql,api,fluent,Java,Sql,Api,Fluent,我想知道是否有任何库可以用来在Java中将SQL查询表示为对象 在代码中,我有很多java.lang.String类型的静态变量,它们是手工编写的SQL查询。我会寻找一个库,它有一个很好的fluent API,允许我将查询表示为对象而不是字符串 例如: Query q = select("DATE", "QUOTE") .from("STOCKMARKET") .where(eq("CORP", "?")) .orderBy("DATE", DESC); @Test public

我想知道是否有任何库可以用来在Java中将SQL查询表示为对象

在代码中,我有很多java.lang.String类型的静态变量,它们是手工编写的SQL查询。我会寻找一个库,它有一个很好的fluent API,允许我将查询表示为对象而不是字符串

例如:

Query q = select("DATE", "QUOTE")
  .from("STOCKMARKET")
  .where(eq("CORP", "?"))
  .orderBy("DATE", DESC);
@Test
public void testSelect() {
    String expected = "select e0.* from Customer e0";

    String actual = new QueryBuilder()
        .from(Customer.class)
        .to(new NativeSQL())
        .sql()
        ;

    Assert.assertEquals(expected, actual);
}
ApacheEmpireDB是一个关系数据库抽象层和数据持久性组件,它允许开发人员在应用程序开发中采用比传统对象关系映射框架更为以SQL为中心的方法

详情如下:

奎尔

可能是Java最强大的ORM库。它可以做的比简单的查询映射多得多。因此,您可以在应用程序的其他地方轻松地实现它。 对于您的情况,可以这样做:

public class LookupCodeName
{
    private String code;
    private String name;

 /*... getter-setters ... */
}

public class someBL {

public List<LookupCodeName> returnSomeEntity() {
      SQLQuery sqlQuery =  (SQLQuery)((HibernateSession)em).getHibernateSession()
                        .createSQLQuery( "SELECT st.name as name, st.code as code FROM someTable st")
                        .addScalar("code")
                        .addScalar("name")
.setResultTransformer(Transformers.aliasToBean(LookupCodeName.class));
    }
return (List<LookupCodeName>)sqlQuery.list();
}

若不想映射字符串查询,那个么必须将类注释为实体并将其与表绑定,然后可以使用hibernate或java持久性。不过,这个例子太复杂了。但是,最终您的查询将转换为以下内容:

查找实体列表:

 Criteria c = createCreteria(entityManager, StockMarket.class);
    // you can add "where" clause by using c.add(Restrictions); 
   // like this: c.add(Restrictions.ilike("name", "%somename%"); where "name" is your entity's field
     List<StockMarket> smList = c.list();

杰克尔看起来很漂亮:

它使用流畅的界面,因此易于阅读,几乎就像文档中的自然SQL:

SqlString sql = select(ARTICLE.OID)
               .from(ARTICLE, ARTICLE_COLOR)
               .where(ARTICLE.OID.eq(ARTICLE_COLOR.ARTICLE_OID)
               .and(ARTICLE.ARTICLE_NO.is_not(NULL)));
它还支持对带有参数的数据源执行查询,因此它还处理参数化查询的创建。

支持对SQL、JPA和JDO后端进行查询

上面的例子变成:

query.from(stockmarket).where(stockmarket.corp.eq(someVar))
    .orderBy(stockmarket.date.desc())
    .list(stockmarket.date, stockmarket.quote);
Querydsl通过APT使用代码生成将SQL模式镜像到Java查询类型。这样,查询就完全是类型安全的,或者与SQL模式兼容

我是Querydsl的维护者,所以这个答案是有偏见的


我发表了Querydsl与其他框架的比较。

这些是一些很好的专有库,可以动态创建类型安全的SQL查询

jOOQ:我是其中的开发者 QueryDSL: JaQu: ICIQ:友好的JaQu叉子 质询: 杰克尔:我想是在维修模式下 斯奎格:我想是在维护模式下 除了上面提到的,还有

Hibernate/JPA标准查询 MyBatis 您在jOOQ中的示例:

create.select(DATE, QUOTE)
      .from(STOCKMARKET)
      .where(CORP.equal(123))
      .orderBy(DATE.desc());

您可以使用naskarlab/fluent查询:

例如:

Query q = select("DATE", "QUOTE")
  .from("STOCKMARKET")
  .where(eq("CORP", "?"))
  .orderBy("DATE", DESC);
@Test
public void testSelect() {
    String expected = "select e0.* from Customer e0";

    String actual = new QueryBuilder()
        .from(Customer.class)
        .to(new NativeSQL())
        .sql()
        ;

    Assert.assertEquals(expected, actual);
}
您可以在项目的单元测试中看到更多示例:


是的,我知道Hibernate,但在您的示例中,仍然有硬编码SQL表示为字符串SELECT st.name作为名称,st.code作为来自someTable st的代码。也许我的问题不够清楚,但我想用这些查询的对象表示替换字符串查询,而不是使用强大的框架来执行查询。Pregzt,您可能想看看Hibernate标准。我认为标准API使用SQL builder API的方向是错误的。在我当前的项目中,最初的开发人员和早已离开的开发人员使用了CriteriaAPI,而当前的团队讨厌它。我们可以使用本机SQL在编写criteria API所需时间的一半内完成DAO方法,因为我们通常会查看criteria API生成的SQL以验证其正确性。如果你已经知道正确的SQL,为什么还要指望SQL生成器呢?如果你已经知道正确的SQL,为什么还要指望SQL生成器呢?你的所有评论都基于这一声明。但是为什么你认为你知道一个正确的SQL?hibernate的一个特点是:1.sql可能太复杂,无法进行简单的编写。例如,复杂的实体关系2.如果更改实体,则无需更改新的正确数据映射的条件。3.您知道您的应用程序将在哪个数据库上运行吗?硬编码SQL消除了一些独立性。上面的示例使用的是普通SQL,这很糟糕,因为这通常意味着你的应用程序只依赖于一个特定的SQL引擎,而不能在任何DB后端运行。相反,建议使用HQL Hibernate查询语言,该语言可以在后台转换为SQL。不过,这种方法仍然使用字符串,因此重构可能会破坏内容。我通过使用一个好的IDEIntelliJ来解决这个问题,它对重构有HQL支持?他们的网站上几乎没有什么内容。我不是一般的合格用户。请记住,它是java的一部分,几年前就可以大肆宣传linq了。从邮件列表存档中可以看出,该项目确实不是很活跃。FWIW,浏览邮件列表,向我展示一些类似的项目,你可能想看看。JaQu在页面底部也有参考,所以其他一些相关的项目看起来不错。这是我一直在寻找的东西。干杯美好的别忘了回来公布你的发现。我只是在几天前才发现它,我还没有机会经常使用它,但我计划在未来使用它。大约一年前我已经联系了Jequel的开发者。这个项目似乎在2008年进入了维护模式。。。