• 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. }  
  • 相关阅读:
    GMA Round 1 数列求单项
    GMA Round 1 双曲线与面积
    多线程环境中安全使用集合API(含代码)
    使用synchronized获取互斥锁的几点说明
    ThreadPoolExecutor线程池
    线程状态转换
    volatile关键字
    守护线程与线程阻塞的四种情况
    线程挂起,恢复与终止
    线程中断
  • 原文地址:https://www.cnblogs.com/xiaona19841010/p/5199082.html
Copyright © 2020-2023  润新知