• JDBC总结


    "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 }

    未完待续...

  • 相关阅读:
    arthas Java诊断工具
    tomcat结构 请求处理过程 和 常见参数
    Dubbo 测试用例 获取注册中心的其他服务
    Vue3 父子组件传值,defineProps,defineEmits,以及父组件调用子组件的方法 defineExpose
    Snowflake
    js中Array和Object的keys(),values()和entries()方法
    深度拷贝
    deepin系统解决增删改文件没有变化
    文献的类别与引用方式
    读万卷书不如行万里路
  • 原文地址:https://www.cnblogs.com/xiaofeng338/p/13577623.html
Copyright © 2020-2023  润新知