标签:
从28号到31号讲了,从开始连接jdbc,从数据库里面显示数据,然后讲了状态通道,预状态通道,当然存储过程通道老师还没说。。。这个很遗憾。可以考虑自己查一下。
预状态通道比起状态通道具有更高的安全性和更快的执行速度,之所以具有更高的安全性是因为它可以防止sql注入。
这段时间算是一个适应过程,所以 这段时间着重背熟了这个模板,想来也抄了好几遍呢。所以这里面直接给出一个比较靠谱的模板放在这里了。
这个 是前面那个 反射要用到的 一个 基石了,前面调用的就是 后面这个 练级jdbc的模板了。需要给出 jdbc.properties 这个 文件。
jdbc.properties
driver = com.mysql.jdbc.Driver url = jdbc:mysql://localhost:3306/booksystem username = root password = lifei23
package com.letben.util; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import java.util.Properties; /** * 希望由调用者执行finally语句 * @author Administrator *(封装应该要把资源都关闭的吧) */ public class JDBCTemplate { private static String driver ; private static String url ; private static String user ; private static String password ; private Connection connection; private Statement statement; private PreparedStatement preparedStatement; private ResultSet resultSet=null; static { //返回代表这个对象的类或者接口的加载器 //getClassLoader() //如果是bootstrap,就返回空,对象代表基本数据类型,或者是void的话,也返回空 //其他状况下,是会返回对应的加载器 InputStream inputStream = JDBCTemplate.class. getClassLoader().getResourceAsStream( "jdbc.properties"); Properties properties = new Properties(); try { properties.load(inputStream);//加载的时候会报io异常 driver =properties.getProperty("driver"); url =properties.getProperty("url"); user = (String) properties.get("user"); password = (String) properties.get("password"); Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 对外提供得到链接底层数据库的connection对象 * @return connection * @throws SQLException,由调用者来处理这个异常。因为 我们不希望,由用户来翻我们的底层工具类 */ public Connection getConnection() throws SQLException{ connection = DriverManager.getConnection(url, user, password); return connection; } /** * 不想对外提供,本方法作为内部使用,如果我们封装的方法不足以用户调用,希望 调用者通过connection来处理 * 这样的话,希望在connection里面标记一个参数用以统计被调用次数,借此完善本工具类。 * * 已经得到 实例化Connection */ private void getStatement(){ try { getConnection(); statement = connection.createStatement(); } catch (SQLException e) { e.printStackTrace(); } } /** * 不想对外提供,本方法作为内部使用,如果我们封装的方法不足以用户调用,希望 调用者通过connection来处理 * 这样的话,希望在connection里面标记一个参数用以统计被调用次数,借此完善本工具类。 * 已经实例化Connection */ private void getPreparedStatement(String sql){ try { getConnection(); preparedStatement = connection.prepareStatement(sql); } catch (SQLException e) { e.printStackTrace(); } } /** * 内部方法用以绑定每一个参数和用法,不希望外面调用 * @param params,需要传一个参数列表进来用以绑定参数 */ private void bindParams(List params) { try { if(params!=null&& !params.isEmpty()) for(int i=0;i<params.size();i++) preparedStatement.setString(i+1, params.get(i)+""); } catch (SQLException e) { e.printStackTrace(); } } /** * 通过预状态通道,查询数据库,得到结果集。位置参数通过参数列表传入数据库。 * @param sql 数据库查询语句 * @param params 参数列表 * @return ResultSet 结果集 */ public ResultSet query(String sql,List params){ getPreparedStatement(sql); try { bindParams(params); resultSet = preparedStatement.executeQuery(); } catch (SQLException e) { e.printStackTrace(); } return resultSet; } /** * 利用 数据库查询语句 得到一个查询结果集,通过状态通道方式 * @param sql 数据库查询语句 * @return ResultSet */ public ResultSet query(String sql){ getStatement(); try { resultSet = statement.executeQuery(sql); } catch (SQLException e) { e.printStackTrace(); } return resultSet; } /** * 利用数据库查询语句,得到一个更新是否成功,通过状态通道方式 * @param sql 数据库查询语句 * @return boolean */ public boolean updateData(String sql){ getStatement(); int result=0; try { result = statement.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); } if(result>0) return true; return false; } /** * 通过预状态通道 方式更新底层数据库,需要传递数据库语句,和参数列表,对于要查询的语句的参数给出相应的列表,进行操作。 * @param sql 数据库查询语句 * @param params 参数列表 * @return 更新数据 成功与否 */ public boolean updateData(String sql,List params){ getPreparedStatement(sql); int result=0; bindParams(params); try { result = preparedStatement.executeUpdate(); } catch (SQLException e) { e.printStackTrace(); } if(result>0) return true; return false; } /** * 关闭资源操作 */ public void closeRes(){ try { if(connection!=null){ connection.close(); } if(statement!=null){ statement.close(); } if(preparedStatement!=null){ preparedStatement.close(); } if(resultSet!=null){ resultSet.close(); } } catch (SQLException e) { e.printStackTrace(); } } //TODO //现在有这样一种需求,对于事务的操作的需求,要求一荣俱荣,一损俱损。 //需要的方法有对应的分别基于两种状态通道的操作,通过形参来重载 //关闭自动提交,打开自动提交。还有提交一个方法,回滚一个方法。6个方法 public boolean executeBatch(List<String> sqls){ boolean flag=false; getStatement(); closeAutoCommit(); try { if(sqls!=null&&!sqls.isEmpty()){ for (String sql : sqls) { statement.addBatch(sql); } statement.executeBatch(); } transactionCommit(); flag=true; openAutoCommit(); } catch (SQLException e) { e.printStackTrace(); transactionRollback(); } return flag; } /** * 【这个的通用性总感觉没有那么强!】 * 预状态通道 * @param sql * @param params * @return 成组提交结果 */ public boolean executeBatch(String sql, String[][] params){ boolean flag=false; getPreparedStatement(sql); closeAutoCommit(); try { for (int i = 0; i < params.length; i++) { for (int j = 0; j < params[i].length; j++) { preparedStatement.setString(j+1, params[i][j]); } preparedStatement.addBatch(); } preparedStatement.executeBatch(); transactionCommit(); flag=true; openAutoCommit(); } catch (SQLException e) { e.printStackTrace(); transactionRollback(); } return flag; } /** * 事务成组,统一提交 */ private void transactionCommit() { try { connection.commit(); } catch (SQLException e) { e.printStackTrace(); } } /** * 打开自动执行 */ private void openAutoCommit(){ try { connection.setAutoCommit(true); } catch (SQLException e) { e.printStackTrace(); } } /** * 关闭自动执行 */ private void closeAutoCommit() { try { connection.setAutoCommit(false); } catch (SQLException e) { e.printStackTrace(); } } /** * 事务执行失败回滚 */ private void transactionRollback(){ try { connection.rollback(); } catch (SQLException e) { e.printStackTrace(); } } }
标签:
原文地址:http://www.cnblogs.com/letben/p/5185018.html