java - 替换 .sql 脚本中的变量并使用 Java JDBC 运行它们

标签 java sql templates jdbc

我使用 Java JDBC(主要是在桌面应用程序中)已经很长时间了,我意识到我执行的许多操作都可以改进和简化。例如:

  • 将 SQL 语句直接硬编码到 Java 中不太实用。

  • 用“?”替换变量在 JDBC 中很好,但使用真正的变量名称(如“USER-NAME”或类似名称)会更好。

  • 一次执行多个更新语句会很酷。

为了改进 JDBC,我决定编写自己的工具,但在我重新发明轮子之前,我想知道是否有任何 Java 实用程序能够:

  • 读取和执行 .sql 脚本,最好存储在我的应用程序的 JAR 中。

  • 在这些脚本中定义变量,最好使用真实名称而不是“?”性格。

  • 从这些脚本运行查询 (SELECT) 和更新(CREATE、INSERT、DELETE ...)语句。

  • 在一个方法调用中执行多个更新语句。例如,这可以让我运行 DDL 和 DML 脚本来初始化数据库。

我知道 JDBC ScriptRunner但还不够完整。那里有更好的东西吗?老实说,我认为像这样的工具会非常有用。

注意:我不介意导入一个库。

最佳答案

我使用 Warework就为了那个。这是一个很大的 JAR,但我认为它可以满足您的需求。我将向您展示它是如何工作的:

1- 在项目的源文件夹中创建此目录结构:

/META-INF/system/statement/sql

2- 在“/META-INF/system”目录中,创建一个名为“pool-service.xml”的文件,其中包含此内容:

<?xml version="1.0" encoding="UTF-8"?> 
<proxy-service xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="http://repository.warework.com/xsd/proxyservice-1.0.0.xsd"> 
 <clients> 
  <client name="c3p0-client" connector="com.warework.service.pool.client.connector.C3P0Connector"> 
   <parameter name="driver-class" value="com.mysql.jdbc.Driver" /> 
   <parameter name="jdbc-url" value="jdbc:mysql://host:port/database-name" /> 
   <parameter name="user" value="the-user-name" /> 
   <parameter name="password" value="the-password" /> 
   <parameter name="connect-on-create" value="true" /> 
  </client> 
 </clients> 
</proxy-service> 

在此文件中,将参数值替换为连接数据库所需的值。保持“connect-on-create”等于“true”。

3- 在“/META-INF/system/statement/sql”目录中编写您的 .sql 脚本。您可以像这样编写 SELECT 语句(每个文件一个语句):

find-user.sql

SELECT * FROM HOME_USERS A WHERE A.ID = ${USER_ID}

UPDATE这样的语句(每个文件一个或多个语句):

创建用户.sql

INSERT INTO HOME_USERS (ID, NAME) VALUES (${USER_ID}, ${USER_NAME});
INSERT INTO ACTIVE_USERS (ID) VALUES (${USER_ID}); 

4- 要连接数据库,请执行以下操作:

// "Test.class" must be any class of your project (the same project where /META-INF/system directory exists).
// Do not change "full" and "relational-database" strings.
// If you change "system" for "test", then the directory will be /META-INF/test.
RDBMSView ddbb = (RDBMSView) ScopeFactory.createTemplate(Test.class, "full", "system").getObject("relational-database");

// Connect with the database.
ddbb.connect();

5- 从 .sql 文件运行 SELECT 语句,如下所示:

// Values for variables in the SELECT statement. 
Hashtable values = new Hashtable(); 

// Set variables to filter the query. 
values.put("USER_ID", new Integer(8375)); 

// Read '/META-INF/system/statement/sql/find-user.sql', replace variables and run. 
// -1 values are for pagination (first -1 is the page, second -1 is the max rows per page).
ResultSet result = (ResultSet) ddbb.executeQueryByName("find-user", values, -1, -1); 

6- 从 .sql 文件运行 UPDATE 语句,如下所示:

// Values for variables in the UPDATE statements. 
Hashtable values = new Hashtable(); 

// Set variables for the update statement. 
values.put("USER_ID", new Integer(3));
values.put("USER_NAME", "Oompa Loompa");

// Read '/META-INF/system/statement/sql/create-user.sql', replace variables and run. 
// ';' is the character that separates each statement.
ddbb.executeUpdateByName("create-user", values, new Character(';'));

RDBMSView类提供这些方法以及连接/断开连接、提交、回滚……您还可以直接从 String 对象运行语句。

关于java - 替换 .sql 脚本中的变量并使用 Java JDBC 运行它们,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12289358/

相关文章:

c# - C# 中的 Java 预处理器

java - 在 Android 中将位图转换为 TIFF

java - 当我使用 jedis 、 set(byte[], byte[]) 或 set(String, String) 时,哪一个性能更好?

mysql - 将 SQL 查询转换为 MySQL 5.7.23

C++:嵌套模板类错误 "explicit specialization in non-namespace scope"

C++ 函数模板的奇怪类型转换错误

java - 将动画 Drawable 保存为 GIF 文件?

MySql 运行总时间取决于票务状态

mysql - SQL从数据库中拉取随机图像

c++ - 顺序独立的可变参数模板参数