Pio*_*ski 67
首先考虑在预准备语句中使用查询参数:
PreparedStatement stm = c.prepareStatement("UPDATE user_table SET name=? WHERE id=?");
stm.setString(1, "the name");
stm.setInt(2, 345);
stm.executeUpdate();
Run Code Online (Sandbox Code Playgroud)
可以做的另一件事是将所有查询保留在属性文件中.例如,在queries.properties文件中可以放置以上查询:
update_query=UPDATE user_table SET name=? WHERE id=?
Run Code Online (Sandbox Code Playgroud)
然后借助一个简单的实用程序类:
public class Queries {
private static final String propFileName = "queries.properties";
private static Properties props;
public static Properties getQueries() throws SQLException {
InputStream is =
Queries.class.getResourceAsStream("/" + propFileName);
if (is == null){
throw new SQLException("Unable to load property file: " + propFileName);
}
//singleton
if(props == null){
props = new Properties();
try {
props.load(is);
} catch (IOException e) {
throw new SQLException("Unable to load property file: " + propFileName + "\n" + e.getMessage());
}
}
return props;
}
public static String getQuery(String query) throws SQLException{
return getQueries().getProperty(query);
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用以下查询:
PreparedStatement stm = c.prepareStatement(Queries.getQuery("update_query"));
Run Code Online (Sandbox Code Playgroud)
这是一个相当简单的解决方案,但效果很好.
Luk*_*der 59
对于任意SQL,请使用jOOQ.jOOQ目前支持SELECT
,INSERT
,UPDATE
,DELETE
,TRUNCATE
,和MERGE
.您可以像这样创建SQL:
String sql1 = DSL.using(SQLDialect.MYSQL)
.select(A, B, C)
.from(MY_TABLE)
.where(A.equal(5))
.and(B.greaterThan(8))
.getSQL();
String sql2 = DSL.using(SQLDialect.MYSQL)
.insertInto(MY_TABLE)
.values(A, 1)
.values(B, 2)
.getSQL();
String sql3 = DSL.using(SQLDialect.MYSQL)
.update(MY_TABLE)
.set(A, 1)
.set(B, 2)
.where(C.greaterThan(5))
.getSQL();
Run Code Online (Sandbox Code Playgroud)
您也可以使用jOOQ执行它,而不是获取SQL字符串.看到
(免责声明:我为jOOQ背后的公司工作)
Ash*_*cer 14
您应该考虑的一种技术是SQLJ - 一种直接在Java中嵌入SQL语句的方法.举个简单的例子,你可能在名为TestQueries.sqlj的文件中有以下内容:
public class TestQueries
{
public String getUsername(int id)
{
String username;
#sql
{
select username into :username
from users
where pkey = :id
};
return username;
}
}
Run Code Online (Sandbox Code Playgroud)
还有一个额外的预编译步骤,它将您的.sqlj文件转换为纯Java - 简而言之,它会查找与之分隔的特殊块
#sql
{
...
}
Run Code Online (Sandbox Code Playgroud)
并将它们转换为JDBC调用.使用SQLJ有几个主要好处:
大多数主要数据库供应商都有翻译器的实现,因此您应该能够轻松找到所需的一切.
我会看一下Spring JDBC.每当我需要以编程方式执行SQL时,我就会使用它.例:
int countOfActorsNamedJoe
= jdbcTemplate.queryForInt("select count(0) from t_actors where first_name = ?", new Object[]{"Joe"});
Run Code Online (Sandbox Code Playgroud)
它对于任何类型的sql执行都非常有用,特别是查询; 它可以帮助您将结果集映射到对象,而不会增加完整ORM的复杂性.
我赞同使用像 Hibernate 这样的 ORM 的建议。然而,肯定有一些情况下这不起作用,所以我会借此机会介绍一些我帮助编写的东西:SqlBuilder是一个 java 库,用于使用“builder”样式动态构建 sql 语句。它相当强大且相当灵活。
小智 5
我一直在开发一个 Java servlet 应用程序,它需要为临时报告目的构造非常动态的 SQL 语句。该应用程序的基本功能是将一堆命名的 HTTP 请求参数提供给一个预编码的查询,并生成一个格式良好的输出表。我使用 Spring MVC 和依赖注入框架将所有 SQL 查询存储在 XML 文件中,并将它们与表格式信息一起加载到报告应用程序中。最终,报告要求变得比现有参数映射框架的功能更复杂,我不得不自己编写。这是一个有趣的开发练习,并产生了一个比我能找到的任何其他东西都更强大的参数映射框架。
新的参数映射如下所示:
select app.name as "App",
${optional(" app.owner as "Owner", "):showOwner}
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = ${integer(0,50):serverId}
and app.id in ${integerList(50):appId}
group by app.name, ${optional(" app.owner, "):showOwner} sv.name
order by app.name, sv.name
Run Code Online (Sandbox Code Playgroud)
结果框架的美妙之处在于它可以通过适当的类型检查和限制检查将 HTTP 请求参数直接处理到查询中。输入验证不需要额外的映射。在上面的示例查询中, 将检查名为serverId的参数以确保它可以转换为整数并且在 0-50 的范围内。参数appId将作为整数数组处理,长度限制为 50。如果字段showOwner存在并设置为“true”,引号中的 SQL 位将添加到生成的可选字段映射查询中。field 有更多参数类型映射可用,包括带有进一步参数映射的可选 SQL 段。它允许开发人员能够想出尽可能复杂的查询映射。它甚至在报告配置中有控件来确定给定的查询是通过 PreparedStatement 具有最终映射还是简单地作为预先构建的查询运行。
对于示例 Http 请求值:
showOwner: true
serverId: 20
appId: 1,2,3,5,7,11,13
Run Code Online (Sandbox Code Playgroud)
它将产生以下 SQL:
select app.name as "App",
app.owner as "Owner",
sv.name as "Server", sum(act.trans_ct) as "Trans"
from activity_records act, servers sv, applications app
where act.server_id = sv.id
and act.app_id = app.id
and sv.id = 20
and app.id in (1,2,3,5,7,11,13)
group by app.name, app.owner, sv.name
order by app.name, sv.name
Run Code Online (Sandbox Code Playgroud)
我真的认为 Spring 或 Hibernate 或其中一个框架应该提供更强大的映射机制来验证类型,允许复杂的数据类型,如数组和其他此类功能。我写我的引擎只是为了我的目的,它不是为了一般发布而完全阅读。目前它只适用于 Oracle 查询,所有代码都属于一家大公司。有一天我可能会采纳我的想法并构建一个新的开源框架,但我希望现有的大玩家之一能够接受挑战。