是否有任何库将SQL查询表示为Java代码中的对象?
我想知道是否有任何库可用于将SQL查询表示为Java中的对象。
在代码中,我有很多类型为java.lang.String的静态变量,它们是手写的SQL查询。 我会寻找具有漂亮的流畅 API的库,它允许我将查询表示为对象而不是字符串。
例:
Query q = select("DATE", "QUOTE") .from("STOCKMARKET") .where(eq("CORP", "?")) .orderBy("DATE", DESC);
杰克尔看起来很漂亮: http : //www.jequel.de/
它使用流畅的界面,因此它易于阅读,几乎像自然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)));
它还支持使用参数对DataSource执行查询,因此它也处理参数化查询的创建。
Querydsl支持查询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与其他框架的比较。
http://www.hibernate.org/可能是最强大的Java ORM库。 它可以做更多,然后只是简单的查询映射。 因此,您可以轻松地在应用程序中的其他位置实现它。 对于你的情况,它可以这样做:
public class LookupCodeName { private String code; private String name; /*... getter-setters ... */ } public class someBL { public List 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 )sqlQuery.list(); }
这些是一些很好的专有库,可以动态创建类型安全的SQL查询
- jOOQ: http : //www.jooq.org (我是开发人员)
- QueryDSL: http ://www.querydsl.com
- JaQu: http ://www.h2database.com/html/jaqu.html
- iciql: http ://iciql.com/(JaQu友好的分支)
- Quaere: http ://quaere.codehaus.org
- 杰克: http : //www.jequel.de (在维护模式中,我认为)
- Squiggle: http : //code.google.com/p/squiggle-sql (在维护模式下,我认为)
除了上述之外,总会有
- Hibernate / JPA CriteriaQuery
- MyBatis的
你在jOOQ中的例子:
create.select(DATE, QUOTE) .from(STOCKMARKET) .where(CORP.equal(123)) .orderBy(DATE.desc());
Apache Empire-db是一个关系数据库抽象层和数据持久性组件,它允许开发人员在应用程序开发中采用比传统的对象关系映射框架(ORM)更多的以SQL为中心的方法。
更多信息: https : //empire-db.apache.org/
Quaere
如果您不想映射字符串查询,那么您必须将您的类注释为实体并将其与表绑定,然后您可以使用hibernate或java persistance。 例子虽然太复杂了。 但是,最后您的查询将转换为以下内容:
查找实体列表:
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 smList = c.list();
按ID查找对象:
StockMarket sm = entityManager.find(StockMarket.class, id);
您可以使用naskarlab / fluent-query:
https://github.com/naskarlab/fluent-query
例:
@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); }
您可以在项目的unit testing中看到更多示例: