JDBC的学习--尚硅谷

1.数据库的连接

[java] view plain copy

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

2.statement 和prepareStatement

[java] view plain copy

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

[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. String sql = "SELECT * FROM users WHERE username = ‘" + username
  9. + "‘ AND " + "password = ‘" + password + "‘";
  10. System.out.println(sql);
  11. Connection connection = null;
  12. Statement statement = null;
  13. ResultSet resultSet = null;
  14. try {
  15. connection = JDBCTools.getConnection();
  16. statement = connection.createStatement();
  17. resultSet = statement.executeQuery(sql);
  18. if (resultSet.next()) {
  19. System.out.println("登录成功!");
  20. } else {
  21. System.out.println("用户名和密码不匹配或用户名不存在. ");
  22. }
  23. } catch (Exception e) {
  24. e.printStackTrace();
  25. } finally {
  26. JDBCTools.releaseDB(resultSet, statement, connection);
  27. }
  28. }

3.JDBCTools

[java] view plain copy

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

4.DAO

[java] view plain copy

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

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

[java] view plain copy

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

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

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

[java] view plain copy

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

8.DBUtils使用

[java] view plain copy

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

9.DAO接口

[java] view plain copy

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

10.DAO接口的实现类。(通过DBUtils实现)

[java] view plain copy

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

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

[java] view plain copy

  1. package com.atguigu.jdbc;
  2. public class CustomerDao
  3. extends JdbcDaoImpl<Customer>{
  4. }
时间: 2024-10-26 15:19:44

JDBC的学习--尚硅谷的相关文章

尚硅谷Java视频_jQuery 视频教程

更多Java培训.Java视频教程学习资料,请登录尚硅谷网站下载:www.atguigu.com jQuery是优秀的JavaScript框架,能使用户能更方便地处理HTML documents.events.实现动画效果,并且方便地为网站提供Ajax交互.在世界前10000个访问最多的网站中,有超过 55 6在使用jQuery. 本Java视频教程循序渐进地对jQuery的各种选择器.函数和方法调用进行了详细的讲授,更配备了大量的实例. [视频简介] jQuery 是继 Prototype 之

java学习笔记-尚硅谷1205班李振*:人生是不放弃的坚持到底

11月份,我毅然而然的做了一个决定,那就是结束当前的工作去学习Java,去实现自己心中酝酿很久的想法.11月13号,来到北京,找到了北京java培训机构尚硅谷,经过基础测试,视频面试,有幸获成为了尚硅谷1205期员. 经过一个多月的学习,Java基础学完了,JDBC也学完了,时间不长,但感触颇深.现在谈一谈这段时间以来我的感受. 首先是学校的环境很好,非常适合学习,有一种很浓厚的学习氛围.来到这里我找到了久违的.一直很怀念的学生时代的感觉.其次是在这一段时间里,深切的感受到学校的老师是那样的负责

java学习笔记:1205班包一*:尚硅谷的培训模式颠覆了培训行业

来尚硅谷北京java培训也将近有四个月了,感慨颇多,要说的话太多太多了,有的可以用文字来表达出来,但是有的却不能,能够表达出来的,我尽力要说,表达不出的,就用身心去体会,因为尚硅谷给我的感受太不一样了.首先要说明的是,本人才疏学浅,所写内容不乏有病句之类的错误,还请老师们海涵,在这里先谢谢了. 带着疑问还有猜忌,我来到这个陌生的城市--北京,为的是对自己命运的抗争,与其说是改变自己的命运,不如说实现自己小小的梦想.社会很乱,不过从来到现在,至少我看到了,就是,尚硅谷不是忽悠人的,而是实打实的做事

尚硅谷springboot学习14-自动配置原理

配置文件能配置哪些属性 配置文件能配置的属性参照 自动配置的原理 1).SpringBoot启动的时候加载主配置类,开启了自动配置功能 @EnableAutoConfiguration 2).@EnableAutoConfiguration 作用: 利用EnableAutoConfigurationImportSelector给容器中导入一些组件? 可以查看selectImports()方法的内容: List<String> configurations = getCandidateConfi

java学习笔记-尚硅谷0918班高宏*:康师傅,给力,太给力了

不知不觉来尚硅谷java培训已经一个月了,这一个月就这么悄悄地溜走了,无声无息,没给一点挽留的余地,只留下我们在这里感叹:时间都去哪了.就好像只有在写总结的时候才恍然明白:原来我们已经学习了一个多月了.这个月是忙碌的一个月,比上班还要忙:这个月是充实的一个月,比堕落时玩游戏还感觉充实:这个月更是收获的一个月,比上学时候感觉学的还要多,还要深.        1.教学方面 教学方面必须要说康师傅了,给力,太给力了,问的问题总是讲的很透彻,很深入,课堂气氛也搞得很好,经常性习惯性的来几个段子让我们捧

java学习笔记-0918班亓东*:尚硅谷班级的学习气氛浓厚

转眼来北京java培训一个月过去,在这一个月里我认识了很多老师和同学,让我有种重新回到学生时代上学时感觉,这的学习气氛很好,每个同学都很用功的学习,有些基础好的同学也很愿意帮助别人,同学之间的相互关心,相互帮助,解决了很多学习上的问题,说起来还要感谢我的同桌,没有他的帮助我想我也会学的很吃力,每次遇到问题他都能及时帮同学解决,同学之间的彼此帮助,让班级的学习气氛更加浓厚,营造一个良好的学习氛围,对于将来的学习会大有帮助,好的学习氛围是大家共同努力的成果. 在尚硅谷java培训每个阶段都会有阶段性

java学习笔记-尚硅谷0918班刘*:我和宋老师建立了亲密无间的基友关系

时光冉冉,岁月如歌,时光如酒,转眼间我就已经步入了人生的第24个年头选择在北京尚硅谷java培训机构来学校.亦或时,我也会在寂寞无人的夜晚,冰冷孤寂的房间,点燃一根香烟,在烟雾袅袅中,深深的问自己,你,有考虑过自己的人生么!!!!亦或时,躺在床上辗转难眠之后,默默的对自己说,你!不能再这么下去了!!!! 是的,我已经二十四岁了,二十四岁的年纪,当周围邻居的小孩开始叫你叔叔的时候,你有木有感觉到一种~~~啊!人生!还真是失败呀!是的,我不能再这么下去了! 我走过风,走过雨,走过那条无人经过的小巷,

java学习笔记-0918班林代*:感谢尚硅谷给我这样一次改造的机会

时间的长河缓缓流淌,在不经意之间,我已经来到尚硅谷java培训一个多月了.还记得,当初义无反顾的报名参加了尚硅谷北京java培训.带着刚离职的失意以及对未来殷勤的企盼来到了北京,来到了这陌生的都市.陌生的学校. 一个多月了,说长不长,说短不短.在这里我认识了很多爱我的和我敬爱的老师们.同学们.喜欢和他们一起疯狂的玩闹,更享受和他们一起交流学习.我相信,有他们的陪伴我可以斗志昂扬的战胜学习路上的困难.而一个多月的学习也达成了我的目的,梳理自己原来会的知识,让那些知识更稳固的印刻在我的脑海里. 规划

java学习笔记-尚硅谷0918班史营营:学习并不难,难就难在坚持

我来到尚硅谷是被尚硅谷北京java培训的课程体系深深的吸引着,之前有看过佟老师的视频,讲课内容非常丰富,也很风趣,当时就在想如果我能达到佟老师一半的技术水平,那我就相当牛了.当然我现在已经身在尚硅谷了,我的第一位导师是宋老师,很帅气,讲课也很风趣,与很多培训机构不同,尚硅谷的课程设置为每天上下午各三小时,以讲解和宋老师现场编码为主.每上两三天课休息一天,进度安排也很合理.这样毫无水分的课程安排,好处自然是不言而喻的.时间安排紧凑,学生能够跟着老师的思路,模仿着进行操作,体会到真实项目中编程的感觉