JDBC的学习--尚硅谷

 

 

1.数据库的连接
[java] view plain copy
 
  1. /** 
  2.      * DriverManager 是驱动的管理类.  
  3.      * 1). 可以通过重载的 getConnection() 方法获取数据库连接. 较为方便 
  4.      * 2). 可以同时管理多个驱动程序: 若注册了多个数据库连接, 则调用 getConnection() 
  5.      * 方法时传入的参数不同, 即返回不同的数据库连接。  
  6.      * @throws Exception  
  7.      */  
  8.   
  9.   
  10.   
  11. @Test  
  12.     public void testGetConnection2() throws Exception{  
  13.         System.out.println(getConnection2());   
  14.     }  
  15.       
  16.     public Connection getConnection2() throws Exception{  
  17.         //1. 准备连接数据库的 4 个字符串.   
  18.         //1). 创建 Properties 对象  
  19.         Properties properties = new Properties();  
  20.           
  21.         //2). 获取 jdbc.properties 对应的输入流  
  22.         InputStream in =   
  23.                 this.getClass().getClassLoader().getResourceAsStream("jdbc.properties");  
  24.           
  25.         //3). 加载 2) 对应的输入流  
  26.         properties.load(in);  
  27.           
  28.         //4). 具体决定 user, password 等4 个字符串.   
  29.         String user = properties.getProperty("user");  
  30.         String password = properties.getProperty("password");  
  31.         String jdbcUrl = properties.getProperty("jdbcUrl");  
  32.         String driver = properties.getProperty("driver");  
  33.           
  34.         //2. 加载数据库驱动程序(对应的 Driver 实现类中有注册驱动的静态代码块.)  
  35.         Class.forName(driver);  
  36.           
  37.         //3. 通过 DriverManager 的 getConnection() 方法获取数据库连接.   
  38.         return DriverManager.getConnection(jdbcUrl, user, password);  
  39.     }  

2.statement 和prepareStatement

[java] view plain copy
 
  1. @Test  
  2. public void testPreparedStatement() {  
  3.     Connection connection = null;  
  4.     PreparedStatement preparedStatement = null;  
  5.   
  6.     try {  
  7.         connection = JDBCTools.getConnection();  
  8.         String sql = "INSERT INTO customers (name, email, birth) "  
  9.                 + "VALUES(?,?,?)";  
  10.   
  11.         preparedStatement = connection.prepareStatement(sql);  
  12.         preparedStatement.setString(1, "ATGUIGU");  
  13.         preparedStatement.setString(2, "simpleit@163.com");  
  14.         preparedStatement.setDate(3,  
  15.                 new Date(new java.util.Date().getTime()));  
  16.   
  17.         preparedStatement.executeUpdate();  
  18.     } catch (Exception e) {  
  19.         e.printStackTrace();  
  20.     } finally {  
  21.         JDBCTools.releaseDB(null, preparedStatement, connection);  
  22.     }  
  23. }  


[java] view plain copy
 
  1. /** 
  2.  * SQL 注入. 
  3.  */  
  4. @Test  
  5. public void testSQLInjection() {  
  6.     String username = "a' OR PASSWORD = ";  
  7.     String password = " OR '1'='1";  
  8.   
  9.     String sql = "SELECT * FROM users WHERE username = '" + username  
  10.             + "' AND " + "password = '" + password + "'";  
  11.   
  12.     System.out.println(sql);  
  13.   
  14.     Connection connection = null;  
  15.     Statement statement = null;  
  16.     ResultSet resultSet = null;  
  17.   
  18.     try {  
  19.         connection = JDBCTools.getConnection();  
  20.         statement = connection.createStatement();  
  21.         resultSet = statement.executeQuery(sql);  
  22.   
  23.         if (resultSet.next()) {  
  24.             System.out.println("登录成功!");  
  25.         } else {  
  26.             System.out.println("用户名和密码不匹配或用户名不存在. ");  
  27.         }  
  28.   
  29.     } catch (Exception e) {  
  30.         e.printStackTrace();  
  31.     } finally {  
  32.         JDBCTools.releaseDB(resultSet, statement, connection);  
  33.     }  
  34. }  

3.JDBCTools

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.io.IOException;  
  4. import java.io.InputStream;  
  5. import java.sql.Connection;  
  6. import java.sql.DriverManager;  
  7. import java.sql.PreparedStatement;  
  8. import java.sql.ResultSet;  
  9. import java.sql.SQLException;  
  10. import java.sql.Statement;  
  11. import java.util.Properties;  
  12.   
  13. public class JDBCTools {  
  14.   
  15.     /** 
  16.      * 执行 SQL 语句, 使用 PreparedStatement 
  17.      * @param sql 
  18.      * @param args: 填写 SQL 占位符的可变参数 
  19.      */  
  20.     public static void update(String sql, Object ... args){  
  21.         Connection connection = null;  
  22.         PreparedStatement preparedStatement = null;  
  23.           
  24.         try {  
  25.             connection = JDBCTools.getConnection();  
  26.             preparedStatement = connection.prepareStatement(sql);  
  27.               
  28.             for(int i = 0; i < args.length; i++){  
  29.                 preparedStatement.setObject(i + 1, args[i]);  
  30.             }  
  31.               
  32.             preparedStatement.executeUpdate();  
  33.               
  34.         } catch (Exception e) {  
  35.             e.printStackTrace();  
  36.         } finally{  
  37.             JDBCTools.releaseDB(null, preparedStatement, connection);  
  38.         }  
  39.     }  
  40.       
  41.     /** 
  42.      * 执行 SQL 的方法 
  43.      *  
  44.      * @param sql: insert, update 或 delete。 而不包含 select 
  45.      */  
  46.     public static void update(String sql) {  
  47.         Connection connection = null;  
  48.         Statement statement = null;  
  49.   
  50.         try {  
  51.             // 1. 获取数据库连接  
  52.             connection = getConnection();  
  53.   
  54.             // 2. 调用 Connection 对象的 createStatement() 方法获取 Statement 对象  
  55.             statement = connection.createStatement();  
  56.   
  57.             // 4. 发送 SQL 语句: 调用 Statement 对象的 executeUpdate(sql) 方法  
  58.             statement.executeUpdate(sql);  
  59.   
  60.         } catch (Exception e) {  
  61.             e.printStackTrace();  
  62.         } finally {  
  63.             // 5. 关闭数据库资源: 由里向外关闭.  
  64.             releaseDB(null, statement, connection);  
  65.         }  
  66.     }  
  67.   
  68.     /** 
  69.      * 释放数据库资源的方法 
  70.      *  
  71.      * @param resultSet 
  72.      * @param statement 
  73.      * @param connection 
  74.      */  
  75.     public static void releaseDB(ResultSet resultSet, Statement statement,  
  76.             Connection connection) {  
  77.   
  78.         if (resultSet != null) {  
  79.             try {  
  80.                 resultSet.close();  
  81.             } catch (SQLException e) {  
  82.                 e.printStackTrace();  
  83.             }  
  84.         }  
  85.   
  86.         if (statement != null) {  
  87.             try {  
  88.                 statement.close();  
  89.             } catch (SQLException e) {  
  90.                 e.printStackTrace();  
  91.             }  
  92.         }  
  93.   
  94.         if (connection != null) {  
  95.             try {  
  96.                 connection.close();  
  97.             } catch (SQLException e) {  
  98.                 e.printStackTrace();  
  99.             }  
  100.         }  
  101.   
  102.     }  
  103.   
  104.     /** 
  105.      * 获取数据库连接的方法 
  106.      */  
  107.     public static Connection getConnection() throws IOException,  
  108.             ClassNotFoundException, SQLException {  
  109.         // 0. 读取 jdbc.properties  
  110.         /** 
  111.          * 1). 属性文件对应 Java 中的 Properties 类 2). 可以使用类加载器加载 bin 目录(类路径下)的文件 
  112.          */  
  113.         Properties properties = new Properties();  
  114.         InputStream inStream = ReviewTest.class.getClassLoader()  
  115.                 .getResourceAsStream("jdbc.properties");  
  116.         properties.load(inStream);  
  117.   
  118.         // 1. 准备获取连接的 4 个字符串: user, password, jdbcUrl, driverClass  
  119.         String user = properties.getProperty("user");  
  120.         String password = properties.getProperty("password");  
  121.         String jdbcUrl = properties.getProperty("jdbcUrl");  
  122.         String driverClass = properties.getProperty("driverClass");  
  123.   
  124.         // 2. 加载驱动: Class.forName(driverClass)  
  125.         Class.forName(driverClass);  
  126.   
  127.         // 3. 调用  
  128.         // DriverManager.getConnection(jdbcUrl, user, password)  
  129.         // 获取数据库连接  
  130.         Connection connection = DriverManager.getConnection(jdbcUrl, user,  
  131.                 password);  
  132.         return connection;  
  133.     }  
  134.   
  135. }  


4.DAO

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.lang.reflect.InvocationTargetException;  
  4. import java.sql.Connection;  
  5. import java.sql.PreparedStatement;  
  6. import java.sql.ResultSet;  
  7. import java.sql.ResultSetMetaData;  
  8. import java.sql.SQLException;  
  9. import java.util.ArrayList;  
  10. import java.util.HashMap;  
  11. import java.util.List;  
  12. import java.util.Map;  
  13.   
  14. import org.apache.commons.beanutils.BeanUtils;  
  15.   
  16. public class DAO {  
  17.   
  18.     // INSERT, UPDATE, DELETE 操作都可以包含在其中  
  19.     public void update(String sql, Object... args) {  
  20.         Connection connection = null;  
  21.         PreparedStatement preparedStatement = null;  
  22.   
  23.         try {  
  24.             connection = JDBCTools.getConnection();  
  25.             preparedStatement = connection.prepareStatement(sql);  
  26.   
  27.             for (int i = 0; i < args.length; i++) {  
  28.                 preparedStatement.setObject(i + 1, args[i]);  
  29.             }  
  30.   
  31.             preparedStatement.executeUpdate();  
  32.         } catch (Exception e) {  
  33.             e.printStackTrace();  
  34.         } finally {  
  35.             JDBCTools.releaseDB(null, preparedStatement, connection);  
  36.         }  
  37.     }  
  38.   
  39.     // 查询一条记录, 返回对应的对象  
  40.     public <T> T get(Class<T> clazz, String sql, Object... args) {  
  41.         List<T> result = getForList(clazz, sql, args);  
  42.         if(result.size() > 0){  
  43.             return result.get(0);  
  44.         }  
  45.           
  46.         return null;  
  47.     }  
  48.   
  49.     /** 
  50.      * 传入 SQL 语句和 Class 对象, 返回 SQL 语句查询到的记录对应的 Class 类的对象的集合 
  51.      * @param clazz: 对象的类型 
  52.      * @param sql: SQL 语句 
  53.      * @param args: 填充 SQL 语句的占位符的可变参数.  
  54.      * @return 
  55.      */  
  56.     public <T> List<T> getForList(Class<T> clazz,   
  57.             String sql, Object... args) {  
  58.   
  59.         List<T> list = new ArrayList<>();  
  60.   
  61.         Connection connection = null;  
  62.         PreparedStatement preparedStatement = null;  
  63.         ResultSet resultSet = null;  
  64.   
  65.         try {  
  66.             //1. 得到结果集  
  67.             connection = JDBCTools.getConnection();  
  68.             preparedStatement = connection.prepareStatement(sql);  
  69.   
  70.             for (int i = 0; i < args.length; i++) {  
  71.                 preparedStatement.setObject(i + 1, args[i]);  
  72.             }  
  73.   
  74.             resultSet = preparedStatement.executeQuery();  
  75.               
  76.             //2. 处理结果集, 得到 Map 的 List, 其中一个 Map 对象  
  77.             //就是一条记录. Map 的 key 为 reusltSet 中列的别名, Map 的 value  
  78.             //为列的值.   
  79.             List<Map<String, Object>> values =   
  80.                     handleResultSetToMapList(resultSet);  
  81.               
  82.             //3. 把 Map 的 List 转为 clazz 对应的 List  
  83.             //其中 Map 的 key 即为 clazz 对应的对象的 propertyName,   
  84.             //而 Map 的 value 即为 clazz 对应的对象的 propertyValue  
  85.             list = transfterMapListToBeanList(clazz, values);  
  86.   
  87.         } catch (Exception e) {  
  88.             e.printStackTrace();  
  89.         } finally {  
  90.             JDBCTools.releaseDB(resultSet, preparedStatement, connection);  
  91.         }  
  92.   
  93.         return list;  
  94.     }  
  95.   
  96.     public <T> List<T> transfterMapListToBeanList(Class<T> clazz,  
  97.             List<Map<String, Object>> values) throws InstantiationException,  
  98.             IllegalAccessException, InvocationTargetException {  
  99.   
  100.         List<T> result = new ArrayList<>();  
  101.   
  102.         T bean = null;  
  103.   
  104.         if (values.size() > 0) {  
  105.             for (Map<String, Object> m : values) {  
  106.                 bean = clazz.newInstance();  
  107.                 for (Map.Entry<String, Object> entry : m.entrySet()) {  
  108.                     String propertyName = entry.getKey();  
  109.                     Object value = entry.getValue();  
  110.   
  111.                     BeanUtils.setProperty(bean, propertyName, value);  
  112.                 }  
  113.                 // 13. 把 Object 对象放入到 list 中.  
  114.                 result.add(bean);  
  115.             }  
  116.         }  
  117.   
  118.         return result;  
  119.     }  
  120.   
  121.     /** 
  122.      * 处理结果集, 得到 Map 的一个 List, 其中一个 Map 对象对应一条记录 
  123.      *  
  124.      * @param resultSet 
  125.      * @return 
  126.      * @throws SQLException 
  127.      */  
  128.     public List<Map<String, Object>> handleResultSetToMapList(  
  129.             ResultSet resultSet) throws SQLException {  
  130.         // 5. 准备一个 List<Map<String, Object>>:  
  131.         // 键: 存放列的别名, 值: 存放列的值. 其中一个 Map 对象对应着一条记录  
  132.         List<Map<String, Object>> values = new ArrayList<>();  
  133.   
  134.         List<String> columnLabels = getColumnLabels(resultSet);  
  135.         Map<String, Object> map = null;  
  136.   
  137.         // 7. 处理 ResultSet, 使用 while 循环  
  138.         while (resultSet.next()) {  
  139.             map = new HashMap<>();  
  140.   
  141.             for (String columnLabel : columnLabels) {  
  142.                 Object value = resultSet.getObject(columnLabel);  
  143.                 map.put(columnLabel, value);  
  144.             }  
  145.   
  146.             // 11. 把一条记录的一个 Map 对象放入 5 准备的 List 中  
  147.             values.add(map);  
  148.         }  
  149.         return values;  
  150.     }  
  151.   
  152.     /** 
  153.      * 获取结果集的 ColumnLabel 对应的 List 
  154.      *  
  155.      * @param rs 
  156.      * @return 
  157.      * @throws SQLException 
  158.      */  
  159.     private List<String> getColumnLabels(ResultSet rs) throws SQLException {  
  160.         List<String> labels = new ArrayList<>();  
  161.   
  162.         ResultSetMetaData rsmd = rs.getMetaData();  
  163.         for (int i = 0; i < rsmd.getColumnCount(); i++) {  
  164.             labels.add(rsmd.getColumnLabel(i + 1));  
  165.         }  
  166.   
  167.         return labels;  
  168.     }  
  169.   
  170.     // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.)  
  171.     public <E> E getForValue(String sql, Object... args) {  
  172.           
  173.         //1. 得到结果集: 该结果集应该只有一行, 且只有一列  
  174.         Connection connection = null;  
  175.         PreparedStatement preparedStatement = null;  
  176.         ResultSet resultSet = null;  
  177.   
  178.         try {  
  179.             //1. 得到结果集  
  180.             connection = JDBCTools.getConnection();  
  181.             preparedStatement = connection.prepareStatement(sql);  
  182.   
  183.             for (int i = 0; i < args.length; i++) {  
  184.                 preparedStatement.setObject(i + 1, args[i]);  
  185.             }  
  186.   
  187.             resultSet = preparedStatement.executeQuery();  
  188.               
  189.             if(resultSet.next()){  
  190.                 return (E) resultSet.getObject(1);  
  191.             }  
  192.         } catch(Exception ex){  
  193.             ex.printStackTrace();  
  194.         } finally{  
  195.             JDBCTools.releaseDB(resultSet, preparedStatement, connection);  
  196.         }  
  197.         //2. 取得结果  
  198.           
  199.         return null;  
  200.     }  
  201.   
  202. }  


5.事务和事务的隔离级别

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.PreparedStatement;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7.   
  8. import org.junit.Test;  
  9.   
  10. public class TransactionTest {  
  11.   
  12.     /** 
  13.      * 测试事务的隔离级别 在 JDBC 程序中可以通过 Connection 的 setTransactionIsolation 来设置事务的隔离级别. 
  14.      */  
  15.     @Test  
  16.     public void testTransactionIsolationUpdate() {  
  17.           
  18.         Connection connection = null;  
  19.   
  20.         try {  
  21.             connection = JDBCTools.getConnection();  
  22.             connection.setAutoCommit(false);  
  23.               
  24.             String sql = "UPDATE users SET balance = "  
  25.                     + "balance - 500 WHERE id = 1";  
  26.             update(connection, sql);  
  27.               
  28.             connection.commit();  
  29.         } catch (Exception e) {  
  30.             e.printStackTrace();  
  31.         } finally {  
  32.   
  33.         }  
  34.     }  
  35.       
  36.     @Test  
  37.     public void testTransactionIsolationRead() {  
  38.         String sql = "SELECT balance FROM users WHERE id = 1";  
  39.         Integer balance = getForValue(sql);  
  40.         System.out.println(balance);   
  41.     }  
  42.   
  43.     // 返回某条记录的某一个字段的值 或 一个统计的值(一共有多少条记录等.)  
  44.     public <E> E getForValue(String sql, Object... args) {  
  45.   
  46.         // 1. 得到结果集: 该结果集应该只有一行, 且只有一列  
  47.         Connection connection = null;  
  48.         PreparedStatement preparedStatement = null;  
  49.         ResultSet resultSet = null;  
  50.   
  51.         try {  
  52.             // 1. 得到结果集  
  53.             connection = JDBCTools.getConnection();  
  54.             System.out.println(connection.getTransactionIsolation());   
  55.               
  56. //          connection.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);  
  57.             connection.setTransactionIsolation(Connection.TRANSACTION_READ_COMMITTED);  
  58.               
  59.             preparedStatement = connection.prepareStatement(sql);  
  60.   
  61.             for (int i = 0; i < args.length; i++) {  
  62.                 preparedStatement.setObject(i + 1, args[i]);  
  63.             }  
  64.   
  65.             resultSet = preparedStatement.executeQuery();  
  66.   
  67.             if (resultSet.next()) {  
  68.                 return (E) resultSet.getObject(1);  
  69.             }  
  70.         } catch (Exception ex) {  
  71.             ex.printStackTrace();  
  72.         } finally {  
  73.             JDBCTools.releaseDB(resultSet, preparedStatement, connection);  
  74.         }  
  75.         // 2. 取得结果  
  76.   
  77.         return null;  
  78.     }  
  79.   
  80.     /** 
  81.      * Tom 给 Jerry 汇款 500 元. 
  82.      *  
  83.      * 关于事务: 1. 如果多个操作, 每个操作使用的是自己的单独的连接, 则无法保证事务. 2. 具体步骤: 1). 事务操作开始前, 开始事务: 
  84.      * 取消 Connection 的默认提交行为. connection.setAutoCommit(false); 2). 如果事务的操作都成功, 
  85.      * 则提交事务: connection.commit(); 3). 回滚事务: 若出现异常, 则在 catch 块中回滚事务: 
  86.      */  
  87.     @Test  
  88.     public void testTransaction() {  
  89.   
  90.         Connection connection = null;  
  91.   
  92.         try {  
  93.   
  94.             connection = JDBCTools.getConnection();  
  95.             System.out.println(connection.getAutoCommit());  
  96.   
  97.             // 开始事务: 取消默认提交.  
  98.             connection.setAutoCommit(false);  
  99.   
  100.             String sql = "UPDATE users SET balance = "  
  101.                     + "balance - 500 WHERE id = 1";  
  102.             update(connection, sql);  
  103.   
  104.             int i = 10 / 0;  
  105.             System.out.println(i);  
  106.   
  107.             sql = "UPDATE users SET balance = " + "balance + 500 WHERE id = 2";  
  108.             update(connection, sql);  
  109.   
  110.             // 提交事务  
  111.             connection.commit();  
  112.         } catch (Exception e) {  
  113.             e.printStackTrace();  
  114.   
  115.             // 回滚事务  
  116.             try {  
  117.                 connection.rollback();  
  118.             } catch (SQLException e1) {  
  119.                 e1.printStackTrace();  
  120.             }  
  121.         } finally {  
  122.             JDBCTools.releaseDB(null, null, connection);  
  123.         }  
  124.   
  125.         /* 
  126.          * try { 
  127.          *  
  128.          * //开始事务: 取消默认提交. connection.setAutoCommit(false); 
  129.          *  
  130.          * //... 
  131.          *  
  132.          * //提交事务 connection.commit(); } catch (Exception e) { //... 
  133.          *  
  134.          * //回滚事务 try { connection.rollback(); } catch (SQLException e1) { 
  135.          * e1.printStackTrace(); } } finally{ JDBCTools.releaseDB(null, null, 
  136.          * connection); } 
  137.          */  
  138.   
  139.         // DAO dao = new DAO();  
  140.         //  
  141.         // String sql = "UPDATE users SET balance = " +  
  142.         // "balance - 500 WHERE id = 1";  
  143.         // dao.update(sql);  
  144.         //  
  145.         // int i = 10 / 0;  
  146.         // System.out.println(i);  
  147.         //  
  148.         // sql = "UPDATE users SET balance = " +  
  149.         // "balance + 500 WHERE id = 2";  
  150.         // dao.update(sql);  
  151.   
  152.     }  
  153.   
  154.     public void update(Connection connection, String sql, Object... args) {  
  155.         PreparedStatement preparedStatement = null;  
  156.   
  157.         try {  
  158.             preparedStatement = connection.prepareStatement(sql);  
  159.   
  160.             for (int i = 0; i < args.length; i++) {  
  161.                 preparedStatement.setObject(i + 1, args[i]);  
  162.             }  
  163.   
  164.             preparedStatement.executeUpdate();  
  165.         } catch (Exception e) {  
  166.             e.printStackTrace();  
  167.         } finally {  
  168.             JDBCTools.releaseDB(null, preparedStatement, null);  
  169.         }  
  170.     }  
  171.   
  172. }  


6.批量处理sql语句

[java] view plain copy
 
  1. @Test  
  2. public void testBatch(){  
  3.     Connection connection = null;  
  4.     PreparedStatement preparedStatement = null;  
  5.     String sql = null;  
  6.       
  7.     try {  
  8.         connection = JDBCTools.getConnection();  
  9.         JDBCTools.beginTx(connection);  
  10.         sql = "INSERT INTO customers VALUES(?,?,?)";  
  11.         preparedStatement = connection.prepareStatement(sql);  
  12.         Date date = new Date(new java.util.Date().getTime());  
  13.           
  14.         long begin = System.currentTimeMillis();  
  15.         for(int i = 0; i < 100000; i++){  
  16.             preparedStatement.setInt(1, i + 1);  
  17.             preparedStatement.setString(2, "name_" + i);  
  18.             preparedStatement.setDate(3, date);  
  19.               
  20.             //"积攒" SQL   
  21.             preparedStatement.addBatch();  
  22.               
  23.             //当 "积攒" 到一定程度, 就统一的执行一次. 并且清空先前 "积攒" 的 SQL  
  24.             if((i + 1) % 300 == 0){  
  25.                 preparedStatement.executeBatch();  
  26.                 preparedStatement.clearBatch();  
  27.             }  
  28.         }  
  29.           
  30.         //若总条数不是批量数值的整数倍, 则还需要再额外的执行一次.   
  31.         if(100000 % 300 != 0){  
  32.             preparedStatement.executeBatch();  
  33.             preparedStatement.clearBatch();  
  34.         }  
  35.           
  36.         long end = System.currentTimeMillis();  
  37.           
  38.         System.out.println("Time: " + (end - begin)); //569  
  39.           
  40.         JDBCTools.commit(connection);  
  41.     } catch (Exception e) {  
  42.         e.printStackTrace();  
  43.         JDBCTools.rollback(connection);  
  44.     } finally{  
  45.         JDBCTools.releaseDB(null, preparedStatement, connection);  
  46.     }  
  47. }  


7.DBCP和C3P0数据库连接池的使用(非配置文件和配置文件)

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.beans.PropertyVetoException;  
  4. import java.io.InputStream;  
  5. import java.sql.Connection;  
  6. import java.sql.Date;  
  7. import java.sql.PreparedStatement;  
  8. import java.sql.SQLException;  
  9. import java.sql.Statement;  
  10. import java.util.Properties;  
  11.   
  12. import javax.sql.DataSource;  
  13.   
  14. import org.apache.commons.dbcp.BasicDataSource;  
  15. import org.apache.commons.dbcp.BasicDataSourceFactory;  
  16. import org.junit.Test;  
  17.   
  18. import com.mchange.v2.c3p0.ComboPooledDataSource;  
  19.   
  20. public class JDBCTest {  
  21.       
  22.     @Test  
  23.     public void testJdbcTools() throws Exception{  
  24.         Connection connection = JDBCTools.getConnection();  
  25.         System.out.println(connection);   
  26.     }  
  27.       
  28.     /** 
  29.      * 1. 创建 c3p0-config.xml 文件,  
  30.      * 参考帮助文档中 Appendix B: Configuation Files 的内容 
  31.      * 2. 创建 ComboPooledDataSource 实例; 
  32.      * DataSource dataSource =  
  33.      *          new ComboPooledDataSource("helloc3p0");   
  34.      * 3. 从 DataSource 实例中获取数据库连接.  
  35.      */  
  36.     @Test  
  37.     public void testC3poWithConfigFile() throws Exception{  
  38.         DataSource dataSource =   
  39.                 new ComboPooledDataSource("helloc3p0");    
  40.           
  41.         System.out.println(dataSource.getConnection());   
  42.           
  43.         ComboPooledDataSource comboPooledDataSource =   
  44.                 (ComboPooledDataSource) dataSource;  
  45.         System.out.println(comboPooledDataSource.getMaxStatements());   
  46.     }  
  47.       
  48.     @Test  
  49.     public void testC3P0() throws Exception{  
  50.         ComboPooledDataSource cpds = new ComboPooledDataSource();  
  51.         cpds.setDriverClass( "com.mysql.jdbc.Driver" ); //loads the jdbc driver              
  52.         cpds.setJdbcUrl( "jdbc:mysql:///atguigu" );  
  53.         cpds.setUser("root");                                    
  54.         cpds.setPassword("1230");     
  55.           
  56.         System.out.println(cpds.getConnection());   
  57.     }  
  58.       
  59.     /** 
  60.      * 1. 加载 dbcp 的 properties 配置文件: 配置文件中的键需要来自 BasicDataSource 
  61.      * 的属性. 
  62.      * 2. 调用 BasicDataSourceFactory 的 createDataSource 方法创建 DataSource 
  63.      * 实例 
  64.      * 3. 从 DataSource 实例中获取数据库连接.  
  65.      */  
  66.     @Test  
  67.     public void testDBCPWithDataSourceFactory() throws Exception{  
  68.           
  69.         Properties properties = new Properties();  
  70.         InputStream inStream = JDBCTest.class.getClassLoader()  
  71.                 .getResourceAsStream("dbcp.properties");  
  72.         properties.load(inStream);  
  73.           
  74.         DataSource dataSource =   
  75.                 BasicDataSourceFactory.createDataSource(properties);  
  76.           
  77.         System.out.println(dataSource.getConnection());   
  78.           
  79. //      BasicDataSource basicDataSource =   
  80. //              (BasicDataSource) dataSource;  
  81. //        
  82. //      System.out.println(basicDataSource.getMaxWait());   
  83.     }  
  84.       
  85.     /** 
  86.      * 使用 DBCP 数据库连接池 
  87.      * 1. 加入 jar 包(2 个jar 包). 依赖于 Commons Pool 
  88.      * 2. 创建数据库连接池 
  89.      * 3. 为数据源实例指定必须的属性 
  90.      * 4. 从数据源中获取数据库连接 
  91.      * @throws SQLException  
  92.      */  
  93.     @Test  
  94.     public void testDBCP() throws SQLException{  
  95.         final BasicDataSource dataSource = new BasicDataSource();  
  96.           
  97.         //2. 为数据源实例指定必须的属性  
  98.         dataSource.setUsername("root");  
  99.         dataSource.setPassword("1230");  
  100.         dataSource.setUrl("jdbc:mysql:///atguigu");  
  101.         dataSource.setDriverClassName("com.mysql.jdbc.Driver");  
  102.           
  103.         //3. 指定数据源的一些可选的属性.  
  104.         //1). 指定数据库连接池中初始化连接数的个数  
  105.         dataSource.setInitialSize(5);  
  106.           
  107.         //2). 指定最大的连接数: 同一时刻可以同时向数据库申请的连接数  
  108.         dataSource.setMaxActive(5);  
  109.           
  110.         //3). 指定小连接数: 在数据库连接池中保存的最少的空闲连接的数量   
  111.         dataSource.setMinIdle(2);  
  112.           
  113.         //4).等待数据库连接池分配连接的最长时间. 单位为毫秒. 超出该时间将抛出异常.   
  114.         dataSource.setMaxWait(1000 * 5);  
  115.           
  116.         //4. 从数据源中获取数据库连接  
  117.         Connection connection = dataSource.getConnection();  
  118.         System.out.println(connection.getClass());   
  119.           
  120.         connection = dataSource.getConnection();  
  121.         System.out.println(connection.getClass());   
  122.           
  123.         connection = dataSource.getConnection();  
  124.         System.out.println(connection.getClass());   
  125.           
  126.         connection = dataSource.getConnection();  
  127.         System.out.println(connection.getClass());   
  128.           
  129.         Connection connection2 = dataSource.getConnection();  
  130.         System.out.println(">" + connection2.getClass());   
  131.           
  132.         new Thread(){  
  133.             public void run() {  
  134.                 Connection conn;  
  135.                 try {  
  136.                     conn = dataSource.getConnection();  
  137.                     System.out.println(conn.getClass());   
  138.                 } catch (SQLException e) {  
  139.                     e.printStackTrace();  
  140.                 }  
  141.             };  
  142.         }.start();  
  143.           
  144.         try {  
  145.             Thread.sleep(5500);  
  146.         } catch (InterruptedException e) {  
  147.             e.printStackTrace();  
  148.         }  
  149.           
  150.         connection2.close();  
  151.     }  
  152.       
  153.     @Test  
  154.     public void testBatch(){  
  155.         Connection connection = null;  
  156.         PreparedStatement preparedStatement = null;  
  157.         String sql = null;  
  158.           
  159.         try {  
  160.             connection = JDBCTools.getConnection();  
  161.             JDBCTools.beginTx(connection);  
  162.             sql = "INSERT INTO customers VALUES(?,?,?)";  
  163.             preparedStatement = connection.prepareStatement(sql);  
  164.             Date date = new Date(new java.util.Date().getTime());  
  165.               
  166.             long begin = System.currentTimeMillis();  
  167.             for(int i = 0; i < 100000; i++){  
  168.                 preparedStatement.setInt(1, i + 1);  
  169.                 preparedStatement.setString(2, "name_" + i);  
  170.                 preparedStatement.setDate(3, date);  
  171.                   
  172.                 //"积攒" SQL   
  173.                 preparedStatement.addBatch();  
  174.                   
  175.                 //当 "积攒" 到一定程度, 就统一的执行一次. 并且清空先前 "积攒" 的 SQL  
  176.                 if((i + 1) % 300 == 0){  
  177.                     preparedStatement.executeBatch();  
  178.                     preparedStatement.clearBatch();  
  179.                 }  
  180.             }  
  181.               
  182.             //若总条数不是批量数值的整数倍, 则还需要再额外的执行一次.   
  183.             if(100000 % 300 != 0){  
  184.                 preparedStatement.executeBatch();  
  185.                 preparedStatement.clearBatch();  
  186.             }  
  187.               
  188.             long end = System.currentTimeMillis();  
  189.               
  190.             System.out.println("Time: " + (end - begin)); //569  
  191.               
  192.             JDBCTools.commit(connection);  
  193.         } catch (Exception e) {  
  194.             e.printStackTrace();  
  195.             JDBCTools.rollback(connection);  
  196.         } finally{  
  197.             JDBCTools.releaseDB(null, preparedStatement, connection);  
  198.         }  
  199.     }  
  200.       
  201.   
  202.     @Test  
  203.     public void testBatchWithPreparedStatement(){  
  204.         Connection connection = null;  
  205.         PreparedStatement preparedStatement = null;  
  206.         String sql = null;  
  207.           
  208.         try {  
  209.             connection = JDBCTools.getConnection();  
  210.             JDBCTools.beginTx(connection);  
  211.             sql = "INSERT INTO customers VALUES(?,?,?)";  
  212.             preparedStatement = connection.prepareStatement(sql);  
  213.             Date date = new Date(new java.util.Date().getTime());  
  214.               
  215.             long begin = System.currentTimeMillis();  
  216.             for(int i = 0; i < 100000; i++){  
  217.                 preparedStatement.setInt(1, i + 1);  
  218.                 preparedStatement.setString(2, "name_" + i);  
  219.                 preparedStatement.setDate(3, date);  
  220.                   
  221.                 preparedStatement.executeUpdate();  
  222.             }  
  223.             long end = System.currentTimeMillis();  
  224.               
  225.             System.out.println("Time: " + (end - begin)); //9819  
  226.               
  227.             JDBCTools.commit(connection);  
  228.         } catch (Exception e) {  
  229.             e.printStackTrace();  
  230.             JDBCTools.rollback(connection);  
  231.         } finally{  
  232.             JDBCTools.releaseDB(null, preparedStatement, connection);  
  233.         }  
  234.     }  
  235.       
  236.     /** 
  237.      * 向  Oracle 的 customers 数据表中插入 10 万条记录 
  238.      * 测试如何插入, 用时最短.  
  239.      * 1. 使用 Statement. 
  240.      */  
  241.     @Test  
  242.     public void testBatchWithStatement(){  
  243.         Connection connection = null;  
  244.         Statement statement = null;  
  245.         String sql = null;  
  246.           
  247.         try {  
  248.             connection = JDBCTools.getConnection();  
  249.             JDBCTools.beginTx(connection);  
  250.               
  251.             statement = connection.createStatement();  
  252.               
  253.             long begin = System.currentTimeMillis();  
  254.             for(int i = 0; i < 100000; i++){  
  255.                 sql = "INSERT INTO customers VALUES(" + (i + 1)   
  256.                         + ", 'name_" + i + "', '29-6月 -13')";  
  257.                 statement.addBatch(sql);  
  258.             }  
  259.             long end = System.currentTimeMillis();  
  260.               
  261.             System.out.println("Time: " + (end - begin)); //39567  
  262.               
  263.             JDBCTools.commit(connection);  
  264.         } catch (Exception e) {  
  265.             e.printStackTrace();  
  266.             JDBCTools.rollback(connection);  
  267.         } finally{  
  268.             JDBCTools.releaseDB(null, statement, connection);  
  269.         }  
  270.     }  
  271.   
  272. }  

8.DBUtils使用

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.Date;  
  5. import java.sql.ResultSet;  
  6. import java.sql.SQLException;  
  7. import java.util.ArrayList;  
  8. import java.util.List;  
  9. import java.util.Map;  
  10.   
  11. import org.apache.commons.dbutils.QueryRunner;  
  12. import org.apache.commons.dbutils.ResultSetHandler;  
  13. import org.apache.commons.dbutils.handlers.BeanHandler;  
  14. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  15. import org.apache.commons.dbutils.handlers.MapHandler;  
  16. import org.apache.commons.dbutils.handlers.MapListHandler;  
  17. import org.apache.commons.dbutils.handlers.ScalarHandler;  
  18. import org.junit.Test;  
  19.   
  20. public class DBUtilsTest {  
  21.   
  22.       
  23.       
  24.     /** 
  25.      * ScalarHandler: 把结果集转为一个数值(可以是任意基本数据类型和字符串, Date 等)返回 
  26.      */  
  27.     @Test  
  28.     public void testScalarHandler(){  
  29.         Connection connection = null;  
  30.           
  31.         try {  
  32.             connection = JDBCTools.getConnection();  
  33.             String sql = "SELECT name, email " +  
  34.                     "FROM customers";  
  35.               
  36.             Object result = queryRunner.query(connection,   
  37.                     sql, new ScalarHandler());  
  38.               
  39.             System.out.println(result);  
  40.         } catch (Exception e) {  
  41.             e.printStackTrace();  
  42.         } finally{  
  43.             JDBCTools.releaseDB(null, null, connection);  
  44.         }  
  45.     }  
  46.       
  47.     /** 
  48.      * MapListHandler: 将结果集转为一个 Map 的 List 
  49.      * Map 对应查询的一条记录: 键: SQL 查询的列名(不是列的别名), 值: 列的值.  
  50.      * 而 MapListHandler: 返回的多条记录对应的 Map 的集合.  
  51.      */  
  52.     @Test  
  53.     public void testMapListHandler(){  
  54.         Connection connection = null;  
  55.           
  56.         try {  
  57.             connection = JDBCTools.getConnection();  
  58.             String sql = "SELECT id, name, email, birth " +  
  59.                     "FROM customers";  
  60.               
  61.             List<Map<String, Object>> result = queryRunner.query(connection,   
  62.                     sql, new MapListHandler());  
  63.               
  64.             System.out.println(result);  
  65.         } catch (Exception e) {  
  66.             e.printStackTrace();  
  67.         } finally{  
  68.             JDBCTools.releaseDB(null, null, connection);  
  69.         }  
  70.     }  
  71.       
  72.     /** 
  73.      * MapHandler: 返回 SQL 对应的第一条记录对应的 Map 对象. 
  74.      * 键: SQL 查询的列名(不是列的别名), 值: 列的值.  
  75.      */  
  76.     @Test  
  77.     public void testMapHandler(){  
  78.         Connection connection = null;  
  79.           
  80.         try {  
  81.             connection = JDBCTools.getConnection();  
  82.             String sql = "SELECT id, name, email, birth " +  
  83.                     "FROM customers";  
  84.               
  85.             Map<String, Object> result = queryRunner.query(connection,   
  86.                     sql, new MapHandler());  
  87.               
  88.             System.out.println(result);  
  89.         } catch (Exception e) {  
  90.             e.printStackTrace();  
  91.         } finally{  
  92.             JDBCTools.releaseDB(null, null, connection);  
  93.         }  
  94.     }  
  95.       
  96.     /** 
  97.      * BeanListHandler: 把结果集转为一个 List, 该 List 不为 null, 但可能为 
  98.      * 空集合(size() 方法返回 0) 
  99.      * 若 SQL 语句的确能够查询到记录, List 中存放创建 BeanListHandler 传入的 Class 
  100.      * 对象对应的对象.  
  101.      */  
  102.     @Test  
  103.     public void testBeanListHandler(){  
  104.         Connection connection = null;  
  105.           
  106.         try {  
  107.             connection = JDBCTools.getConnection();  
  108.             String sql = "SELECT id, name, email, birth " +  
  109.                     "FROM customers";  
  110.               
  111.             List<Customer> customers = queryRunner.query(connection,   
  112.                     sql, new BeanListHandler(Customer.class));  
  113.               
  114.             System.out.println(customers);  
  115.         } catch (Exception e) {  
  116.             e.printStackTrace();  
  117.         } finally{  
  118.             JDBCTools.releaseDB(null, null, connection);  
  119.         }  
  120.     }  
  121.       
  122.     /** 
  123.      * BeanHandler: 把结果集的第一条记录转为创建 BeanHandler 对象时传入的 Class 
  124.      * 参数对应的对象.  
  125.      */  
  126.     @Test  
  127.     public void testBeanHanlder(){  
  128.         Connection connection = null;  
  129.           
  130.         try {  
  131.             connection = JDBCTools.getConnection();  
  132.             String sql = "SELECT id, name customerName, email, birth " +  
  133.                     "FROM customers WHERE id >= ?";  
  134.               
  135.             Customer customer = queryRunner.query(connection,   
  136.                     sql, new BeanHandler(Customer.class), 5);  
  137.               
  138.             System.out.println(customer);  
  139.         } catch (Exception e) {  
  140.             e.printStackTrace();  
  141.         } finally{  
  142.             JDBCTools.releaseDB(null, null, connection);  
  143.         }  
  144.     }  
  145.       
  146.     QueryRunner queryRunner = new QueryRunner();  
  147.   
  148.     class MyResultSetHandler implements ResultSetHandler{  
  149.   
  150.         @Override  
  151.         public Object handle(ResultSet resultSet)   
  152.                 throws SQLException {  
  153. //          System.out.println("handle....");  
  154. //          return "atguigu";  
  155.               
  156.             List<Customer> customers = new ArrayList<>();  
  157.               
  158.             while(resultSet.next()){  
  159.                 Integer id = resultSet.getInt(1);  
  160.                 String name = resultSet.getString(2);  
  161.                 String email = resultSet.getString(3);  
  162.                 Date birth = resultSet.getDate(4);  
  163.                   
  164.                 Customer customer =   
  165.                         new Customer(id, name, email, birth);  
  166.                 customers.add(customer);  
  167.             }  
  168.               
  169.             return customers;  
  170.         }  
  171.           
  172.     }  
  173.       
  174.     /** 
  175.      * QueryRunner 的 query 方法的返回值取决于其 ResultSetHandler 参数的 
  176.      * handle 方法的返回值 
  177.      *  
  178.      */  
  179.     @Test  
  180.     public void testQuery(){  
  181.         Connection connection = null;  
  182.           
  183.         try {  
  184.             connection = JDBCTools.getConnection();  
  185.             String sql = "SELECT id, name, email, birth " +  
  186.                     "FROM customers";  
  187.             Object obj = queryRunner.query(connection, sql,   
  188.                             new MyResultSetHandler());  
  189.               
  190.             System.out.println(obj);   
  191.         } catch (Exception e) {  
  192.             e.printStackTrace();  
  193.         } finally{  
  194.             JDBCTools.releaseDB(null, null, connection);  
  195.         }  
  196.     }  
  197.       
  198.     @Test  
  199.     public void testUpdate(){  
  200.         Connection connection = null;  
  201.           
  202.         try {  
  203.             connection = JDBCTools.getConnection();  
  204.             String sql = "UPDATE customers SET name = ? " +  
  205.                     "WHERE id = ?";  
  206.             queryRunner.update(connection, sql, "MIKE", 11);  
  207.         } catch (Exception e) {  
  208.             e.printStackTrace();  
  209.         } finally{  
  210.             JDBCTools.releaseDB(null, null, connection);  
  211.         }  
  212.     }  
  213.   
  214. }  

9.DAO接口

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.SQLException;  
  5. import java.util.List;  
  6.   
  7. /** 
  8.  * 访问数据的 DAO 接口.  
  9.  * 里边定义好访问数据表的各种方法 
  10.  * @param T: DAO 处理的实体类的类型.  
  11.  */  
  12. public interface DAO<T> {  
  13.   
  14.     /** 
  15.      * 批量处理的方法 
  16.      * @param connection 
  17.      * @param sql 
  18.      * @param args: 填充占位符的 Object [] 类型的可变参数. 
  19.      * @throws SQLException  
  20.      */    
  21.     void batch(Connection connection,   
  22.             String sql, Object [] ... args) throws SQLException;  
  23.       
  24.     /** 
  25.      * 返回具体的一个值, 例如总人数, 平均工资, 某一个人的 email 等. 
  26.      * @param connection 
  27.      * @param sql 
  28.      * @param args 
  29.      * @return 
  30.      * @throws SQLException  
  31.      */  
  32.     <E> E getForValue(Connection connection,  
  33.             String sql, Object ... args) throws SQLException;  
  34.       
  35.     /** 
  36.      * 返回 T 的一个集合 
  37.      * @param connection 
  38.      * @param sql 
  39.      * @param args 
  40.      * @return 
  41.      * @throws SQLException  
  42.      */  
  43.     List<T> getForList(Connection connection,  
  44.             String sql, Object ... args) throws SQLException;  
  45.       
  46.     /** 
  47.      * 返回一个 T 的对象 
  48.      * @param connection 
  49.      * @param sql 
  50.      * @param args 
  51.      * @return 
  52.      * @throws SQLException  
  53.      */  
  54.     T get(Connection connection, String sql,   
  55.             Object ... args) throws SQLException;  
  56.       
  57.     /** 
  58.      * INSRET, UPDATE, DELETE 
  59.      * @param connection: 数据库连接 
  60.      * @param sql: SQL 语句 
  61.      * @param args: 填充占位符的可变参数. 
  62.      * @throws SQLException  
  63.      */  
  64.     void update(Connection connection, String sql,   
  65.             Object ... args) throws SQLException;  
  66.   
  67. }  

10.DAO接口的实现类。(通过DBUtils实现)
[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. import java.sql.Connection;  
  4. import java.sql.SQLException;  
  5. import java.util.List;  
  6.   
  7. import org.apache.commons.dbutils.QueryRunner;  
  8. import org.apache.commons.dbutils.handlers.BeanHandler;  
  9. import org.apache.commons.dbutils.handlers.BeanListHandler;  
  10. import org.apache.commons.dbutils.handlers.ScalarHandler;  
  11.   
  12. /** 
  13.  * 使用 QueryRunner 提供其具体的实现 
  14.  * @param <T>: 子类需传入的泛型类型.  
  15.  */  
  16. public class JdbcDaoImpl<T> implements DAO<T> {  
  17.   
  18.     private QueryRunner queryRunner = null;  
  19.     private Class<T> type;  
  20.       
  21.     public JdbcDaoImpl() {  
  22.         queryRunner = new QueryRunner();  
  23.         type = ReflectionUtils.getSuperGenericType(getClass());  
  24.     }  
  25.       
  26.     @Override  
  27.     public void batch(Connection connection, String sql, Object[]... args) throws SQLException {  
  28.         queryRunner.batch(connection, sql, args);  
  29.     }  
  30.   
  31.     @Override  
  32.     public <E> E getForValue(Connection connection, String sql, Object... args) throws SQLException {  
  33.         return (E) queryRunner.query(connection, sql, new ScalarHandler(), args);  
  34.     }  
  35.   
  36.     @Override   
  37.     public List<T> getForList(Connection connection, String sql, Object... args)   
  38.             throws SQLException {  
  39.         return queryRunner.query(connection, sql,   
  40.                 new BeanListHandler<>(type), args);  
  41.     }  
  42.   
  43.     @Override  
  44.     public T get(Connection connection, String sql, Object... args) throws SQLException {   
  45.         return queryRunner.query(connection, sql,   
  46.                 new BeanHandler<>(type), args);  
  47.     }  
  48.   
  49.     @Override  
  50.     public void update(Connection connection, String sql, Object... args) throws SQLException {  
  51.         queryRunner.update(connection, sql, args);  
  52.     }  
  53.       
  54. }  

11.DAOImpl的继承类,可以再自己定义操作数据库的方法

[java] view plain copy
 
  1. package com.atguigu.jdbc;  
  2.   
  3. public class CustomerDao   
  4.     extends JdbcDaoImpl<Customer>{  
  5.       
  6. }  
原文地址:https://www.cnblogs.com/xiaona19841010/p/5199082.html