最佳实践:在Java中使用DB

bin*_*yLV 4 java database

首先,我是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;
}
Run Code Online (Sandbox Code Playgroud)

对于这样的基本操作,代码看起来很长.另一个问题是大多数代码必须在许多地方重复(声明Connection,PreparedStatement,ResultSet,关闭它们,捕获异常).虽然,这是我在谷歌搜索时的大多数例子中看到的.

在PHP中,我将创建一个包装类,它将具有方法select(),它接受2个参数(字符串)sqlQuery和(数组)参数,并返回简单的数据数组.包装类也有几个更具体的方法,如:

  • selectValue()表示单个值(例如select count(*) from user)
  • selectRow()表示单行(例如select name, surname from user where id = :user_id)
  • selectColumn为单列(例如select distinct remote_address from user)

在Java中实践过这样的东西吗?还是有什么更好/更方便的?或者我应该使用与getUserID()上面例子相同的风格?正如我所说,这次ORM不是一个选择.

提前致谢 :)


编辑:目前DBConnection写的是课程.它从构造函数中的c3p0连接池获取连接.它具有与DB工作的几个公共方法: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并将其结果转换为提到的类型.由于我是Java的新手,我也不确定是否为选择选择了合适的类型.除此之外,一切似乎都按预期工作.

Tim*_*the 5

如果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()"

编辑:还有 一件事:我认为之后添加ORM很困难,因为所有的SQL都已经用普通的JDBC编写了.你不能重构那些东西,你必须扔掉它再做一次.

编辑: 如果要关闭语句,则不必关闭resultSet.在Java的API的ResultSet读取:

当生成它的Statement对象关闭,重新执行或用于从多个结果序列中检索下一个结果时,ResultSet对象将自动关闭.

除此之外,C3P0也进行资源管理,并在返回连接时关闭语句.你也可以这样看.