"JDBC总结"思维导图:
手动实现篇:
第一部分:获取数据库连接( 具体可以参照我的另一篇随笔:https://www.cnblogs.com/xiaofeng338/p/13539536.html)
配置文件( jdbc.properties ):
1 user=root 2 password=password 3 url=jdbc:mysql://localhost:3306/test?serverTimezone=GMT%2B8 4 driverClass=comysql.cj.jdbc.Driver
注:我的mysql版本为8.0.18,需要在 url 后面加上” ?serverTimezone=GMT%2B8 “,保证时区为东八区。
代码实现:
1 @Test 2 public void testManualConnection() throws IOException, Exception { 3 // 步骤一:加载配置文件 4 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties") ; 5 Properties pros = new Properties() ; 6 pros.load(is); 7 8 // 步骤二:读取配置文件 9 String user = pros.getProperty("user") ; 10 String password = pros.getProperty("password") ; 11 String url = pros.getProperty("url") ; 12 String driver = pros.getProperty("driverClass") ; 13 14 // 步骤三:加载驱动 15 Class.forName(driver) ; 16 17 // 步骤四:获取数据库连接 18 Connection conn = DriverManager.getConnection(url, user, password) ; 19 20 }
注:因还没有涉及资源的关闭故此处只是抛出异常并没有处理异常。
第二部分:操作数据库( 考虑事务 )
对数据库的“增删改”操作:
1 public void testUpdate(Connection conn,String sql,Object...args) throws Exception { 2 // "事务"的开头:取消DML语句的自动提交属性 3 conn.setAutoCommit(false); 4 5 // 预编译sql语句并返回PreparedStatement实例对象 6 PreparedStatement ps = conn.prepareStatement(sql) ; 7 // 填充sql语句中的占位符 8 for(int i = 0;i < args.length;i++) { 9 ps.setObject(i + 1, args[i]); 10 } 11 12 // 执行传入prepareStatement()中的sql语句 13 ps.execute() ; 14 // "事务"的中间处理:手动提交数据 15 conn.commit(); 16 }
注:因为”数据库连接“是以形参的形式传入故此方法内也不涉及资源的关闭,我们只是抛出异常并没有处理异常。
对数据库的”查询“操作:
1 public <T> List<T> testQuery(Class<T> cla,Connection conn,String sql,Object...args) throws Exception{ 2 // "事务"的开头:取消DML语句的自动提交属性 3 conn.setAutoCommit(false); 4 // 预编译sql语句并返回PreparedStatement实例对象 5 PreparedStatement ps = conn.prepareStatement(sql) ; 6 // 填充sql语句中的占位符 7 for(int i = 0 ;i < args.length ; i++) { 8 ps.setObject(i + 1, args[i]); 9 } 10 // 执行传入prepareStatement()中的sql语句并返回结果集 11 ResultSet rs = ps.executeQuery() ; 12 13 // 调用结果集的元数据 14 ResultSetMetaData rsmd = rs.getMetaData() ; 15 // 获取结果集中每一行的列数 16 int columnCount = rsmd.getColumnCount() ; 17 18 // list用于存储结果集中的多个对象 19 ArrayList<T> list = new ArrayList<T>() ; 20 while(rs.next()) { 21 T t = cla.newInstance() ; 22 // 循环遍历每一行的每一列 23 for(int i = 0 ;i < columnCount ;i++ ) { 24 Object columnValue = rs.getObject(i + 1) ; 25 26 // 通过结果集的元数据获取对应列的列名(别名) 27 String columnLabel = rsmd.getColumnLabel(i + 1) ; 28 // 以反射的方式以列名(别名)获取对应类的对应属性的类型 29 Field columnField = t.getClass().getDeclaredField(columnLabel) ; 30 // 设置属性为"可修改" 31 columnField.setAccessible(true); 32 // 将对象的对应属性赋值 33 columnField.set(t, columnValue); 34 } 35 // 将每一行对应的对象添加到集合中 36 list.add(t) ; 37 } 38 conn.commit(); 39 return list ; 40 }
注:因为”数据库连接“是以形参的形式传入故此方法内也不涉及资源的关闭,我们只是抛出异常并没有处理异常。
第三部分:关闭资源 ;
1 public static void closeResource(Connection conn,Statement ps,ResultSet rs) { 2 if (ps != null) { 3 try { 4 ps.close(); 5 } catch (SQLException e) { 6 e.printStackTrace(); 7 } 8 } 9 if (conn != null) { 10 try { 11 conn.close(); 12 } catch (SQLException e) { 13 e.printStackTrace(); 14 } 15 } 16 if(rs != null) { 17 try { 18 rs.close(); 19 } catch (SQLException e) { 20 e.printStackTrace(); 21 } 22 } 23 }
汇总:创建一个手动完成的 JDBCUtils 工具类,实现提供数据库连接、对数据库的增删改查、关闭资源等功能 ;
1 package edu.cn.ahpu3.util; 2 3 import java.io.IOException; 4 import java.io.InputStream; 5 import java.lang.reflect.Field; 6 import java.sql.Connection; 7 import java.sql.DriverManager; 8 import java.sql.PreparedStatement; 9 import java.sql.ResultSet; 10 import java.sql.ResultSetMetaData; 11 import java.sql.SQLException; 12 import java.util.ArrayList; 13 import java.util.List; 14 import java.util.Properties; 15 16 public class JDBCUtils { 17 18 /** 19 * 20 * @Description 提供数据库的连接 21 * @author XiaoFeng 22 * @date 2020年8月28日下午3:05:59 23 * @return Connection 24 */ 25 public static Connection getConnection() { 26 try { 27 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties"); 28 Properties pros = new Properties(); 29 pros.load(is); 30 31 String user = pros.getProperty("user"); 32 String password = pros.getProperty("password"); 33 String url = pros.getProperty("url"); 34 String driver = pros.getProperty("driverClass"); 35 36 Class.forName(driver); 37 38 Connection conn = DriverManager.getConnection(url, user, password); 39 return conn ; 40 } catch (Exception e) { 41 e.printStackTrace(); 42 } 43 return null ; 44 } 45 46 /** 47 * 48 * @Description 对数据库进行增加、删除、修改操作 49 * @author XiaoFeng 50 * @date 2020年8月28日下午2:38:09 51 * @param conn 数据库连接 52 * @param sql 执行的SQL语句 53 * @param args 填充SQL语句中的占位符 54 */ 55 public static void update(Connection conn, String sql, Object... args) { 56 try { 57 conn.setAutoCommit(false); 58 PreparedStatement ps = conn.prepareStatement(sql); 59 for (int i = 0; i < args.length; i++) { 60 ps.setObject(i + 1, args[i]); 61 } 62 ps.execute(); 63 conn.commit(); 64 } catch (SQLException e) { 65 e.printStackTrace(); 66 try { 67 conn.rollback(); 68 } catch (SQLException e1) { 69 e1.printStackTrace(); 70 } 71 } 72 } 73 74 /** 75 * 76 * @Description 对数据库的查询操作 77 * @author XiaoFeng 78 * @date 2020年8月28日下午2:57:18 79 * @param <T> 80 * @param cla 81 * @param conn 82 * @param sql 83 * @param args 84 * @return 85 */ 86 public static <T> List<T> query(Class<T> cla, Connection conn, String sql, Object... args) { 87 ArrayList<T> list; 88 try { 89 conn.setAutoCommit(false); 90 PreparedStatement ps = conn.prepareStatement(sql); 91 for (int i = 0; i < args.length; i++) { 92 ps.setObject(i + 1, args[i]); 93 } 94 ResultSet rs = ps.executeQuery(); 95 96 ResultSetMetaData rsmd = rs.getMetaData(); 97 int columnCount = rsmd.getColumnCount(); 98 99 list = new ArrayList<T>(); 100 while (rs.next()) { 101 T t = cla.newInstance(); 102 for (int i = 0; i < columnCount; i++) { 103 Object columnValue = rs.getObject(i + 1); 104 105 String columnLabel = rsmd.getColumnLabel(i + 1); 106 Field columnField = cla.getDeclaredField(columnLabel); 107 columnField.setAccessible(true); 108 columnField.set(t, columnValue); 109 } 110 list.add(t); 111 return list; 112 } 113 conn.commit(); 114 } catch (Exception e) { 115 e.printStackTrace(); 116 try { 117 conn.rollback(); 118 } catch (SQLException e1) { 119 e1.printStackTrace(); 120 } 121 } 122 return null; 123 } 124 125 /** 126 * 127 * @Description 关闭资源 128 * @author XiaoFeng 129 * @date 2020年8月28日下午3:00:57 130 * @param conn Connection 131 * @param ps PreparedStatement 132 * @param rs ResultSet 133 */ 134 public static void closeResource(Connection conn, PreparedStatement ps, ResultSet rs) { 135 if (conn != null) { 136 try { 137 conn.close(); 138 } catch (SQLException e) { 139 e.printStackTrace(); 140 } 141 } 142 if (ps != null) { 143 try { 144 ps.close(); 145 } catch (SQLException e) { 146 e.printStackTrace(); 147 } 148 } 149 if (rs != null) { 150 try { 151 rs.close(); 152 } catch (SQLException e) { 153 e.printStackTrace(); 154 } 155 } 156 } 157 }
未完待续...