首先,我是 Java 新手。
我正在尝试找出从 Java 使用 DB 的好/方便的方法。我正在使用 c3p0 进行连接池。这次 Hibernate 或其他 ORM 不是一个选项,我们决定暂时坚持使用“纯 SQL”。
目前基本的数据检索是这样的:
private int getUserID(int sessionID, String userIP) {
int result = 0;
Connection conn = null;
PreparedStatement st = null;
ResultSet rs = null;
try {
// Application.cpds is an instance of c3p0's ComboPooledDataSource
conn = Application.cpds.getConnection();
st = conn.prepareStatement("SELECT user_id, user_ip, is_timed_out FROM g_user.user_session WHERE id = ?");
st.setInt(1, sessionID);
rs = st.executeQuery();
if ( rs.next() ) {
if ( !rs.getBoolean("is_timed_out") && userIP.equals(rs.getString("user_ip")) ) {
result = rs.getInt("user_id");
}
}
}
catch (SQLException e) {
e.printStackTrace();
}
finally {
if ( rs != null ) {
try { rs.close(); } catch (SQLException e) { e.printStackTrace(); }
}
if ( st != null ) {
try { st.close(); } catch (SQLException e) { e.printStackTrace(); }
}
if ( conn != null ) {
try { conn.close(); } catch (SQLException e) { e.printStackTrace(); }
}
}
return result;
}
这样的基本操作代码看起来很长。另一个问题是大部分代码必须在很多地方重复(声明 Connection、PreparedStatement、ResultSet、关闭它们、捕获异常)。不过,这是我在谷歌搜索时在大多数示例中看到的内容。
在 PHP 中,我将创建一个包装类,该类将具有方法 select(),该方法接受 2 个参数 (string)sqlQuery 和 (array)parameters,并将返回简单的数据数组。包装类也有一些更具体的方法,例如:
- selectValue() 用于单个值(例如
select count(*) from user
) - 单行的 selectRow()(例如
select name, surname from user where id = :user_id
) - 为单列选择列(例如
select distinct remote_address from user
)
在 Java 中有这样的做法吗?或者有什么更好/更方便的吗?或者我应该使用与 getUserID()
中相同的样式吗?上面的例子?正如我所说,这次 ORM 不是一个选项。
提前致谢:)
编辑: 当前 DBConnection
类是写的。它从构造函数中的 c3p0 连接池获取连接。它几乎没有使用 DB 的公共(public)方法:select()
对于表格数据,selectValue()
对于单个值,selectRow()
和 selectColumn()
对于单行或单列,以及 insert()
, update()
, delete()
和 ddl()
.方法接受 String query, Object[] params
参数,带 params
是可选的。 insert()
, update()
和 delete()
返回 Integer
这是 PreparedStatement.executeUpdate()
的结果. select
方法返回不同的结果:
-
ArrayCollection<HashMap<String, Object>> select()
-
Object selectValue()
-
HashMap<String, Object> selectRow()
-
ArrayCollection<Object> selectColumn()
最后一个问题是编译器警告 - "warning: [unchecked] unchecked cast"
.这是因为所有方法都调用返回 Object
的单个私有(private)方法并将其结果转换为提到的类型。由于我是 Java 的新手,我也不确定我是否为选择选择了合适的类型。除此之外,一切似乎都按预期工作。
最佳答案
如果没有 ORM 选项,您仍然可以使用 Spring 的 JDBC 辅助类: http://docs.spring.io/spring-framework/docs/4.1.0.RELEASE/spring-framework-reference/html/jdbc.html
或者您可以自己编写一些辅助方法。也许 DBUtil.close(conn, st, rs);
会很好。
顺便说一下,你真的应该使用日志框架而不是“e.printStackTrace()
”
编辑: 还有一件事:当所有 SQL 都已经用纯 JDBC 编写时,我认为之后添加 ORM 有点困难。你不能重构那些东西,你必须把它扔掉再做。
编辑: 如果您无论如何都要关闭语句,则不必关闭结果集。 Java ResultSet API阅读:
A ResultSet object is automatically closed when the Statement object that generated it is closed, re-executed, or used to retrieve the next result from a sequence of multiple results.
除此之外,C3P0 还进行资源管理,并在您返回连接时关闭语句。你也可以查一下。
关于java - 最佳实践 : working with DB in Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3386823/