[Review Knowledge Article] Reviewing JDBC related knowledge points for the first time

Table of contents

Get database connection steps:

Create a lib folder under the src of the project and import the jdbc jar package;

Create a new class under the src of the project, and load and register the database driver in the class,

Call the preparedStatement(sql) method of the obtained connection object conn to obtain the preparedstatement object - pass in the sql statement;

Fill placeholders: Use a for loop to fill placeholders

Call the excute() or excuteQuery() method of the PS object to execute the sql statement,

get result set

To close each resource, this operation is also encapsulated in the JDBCUtils tool class;


At present, I have just finished learning the servlet knowledge points. When completing a web project that uses pure servlet to add, delete, modify and query the dept1 table, it needs to use jdbc to connect to the database and modify the data in it, so review the knowledge points;


Existing problems: review the knowledge points related to jdbc, only to find that I have forgotten most of the knowledge points;

Get database connection steps:

Create a lib folder under the src of the project and import the jdbc jar package;

Create a new class under the src of the project, and load and register the database driver in the class,

Usually we will encapsulate the operation of obtaining the database connection into the [JDBCUtils] class ;

  • Load and use the reflection mechanism【class.forname(类名);

    1. Question introduction: what is the reflection mechanism? How does the reflection mechanism work?

    2. Question answer: The reflection mechanism is the ability to dynamically obtain class information and dynamically call methods and properties of objects during the runtime of Java code. The reflection mechanism of Java is to directly obtain or modify any Properties and methods of a class or any object

  • Before obtaining the database connection, we will also use the database password, user and other information, and we usually encapsulate this information into a file with the suffix name properties , the content of the file is as follows;

     url=jdbc:mysql://localhost:3306/user
     user=root
     password=123456
     driverClass=com.mysql.cj.jdbc.Driver
  • However, before obtaining the database connection, after we put these attribute information into the properties file, we need to read them out one by one, so how do we read out these information?
 InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");
 //getResourceAsStream:返回用于读取指定资源的输入流。
 Properties pros = new Properties();
 pros.load(is);
 //读取配置文件
 String user = pros.getProperty("user");
 String password = pros.getProperty("password");
 String url = pros.getProperty("url");
 String driverClass = pros.getProperty("driverClass")
  • An input stream is used here

    InputStream is = ClassLoder.getSystemClassLoader().getResourceAsStream("jdbc.properties");
  • This input stream is different from the way we obtained the input stream before. This is the loader used to load the class [a loader used to load Java classes into the Java virtual machine. 】;

  • Then new a properties [property configuration file] object pros, and then usepros.load(is);

  • load(); method function [ read the property list (key and element pair) from the specified input stream to the map collection in the pros object ], if we want to get the corresponding value, we must use the method getProperties("key" ) 值=pros.getProperties("键") ;

    • Registration is used in the static code block in the driver class

      Connection conn=DriverManager.getConnection(url,user,password);
      1. Question introduction: What is the driver class?

      2. Questions Answered: Drivers

Call the preparedStatement(sql) method of the obtained connection object conn to obtain the preparedstatement object - pass in the sql statement;

  • Knowledge point: Why not use the Statement object? What is the role of preparedstatement?

  • Explanation 1: Because Statement cannot avoid SQL injection problems;

  • Explanation 2: Preparedstatement has the same function as Statement, both of which send SQL statements to be executed to the database;

Fill placeholders: Use a for loop to fill placeholders

  • for (int i = 0; i < args.length; i++) {
         ps.setObject(i+1,args[i]);//有注意点、易出错,第一个参数是从1开始
     }
  • Here is a note: the first parameter to fill the placeholder starts from 1;

Call the excute() or excuteQuery() method of the PS object to execute the sql statement,

        The difference between these two methods is that one cannot get the result set and the other can get the result set, or one has a return value and the other has no return value;

  • A question is involved here: Are the rows and columns of the result set in rs? What is result set metadata?

  • Problem solving 1: How do we output the result set on the screen after we get it? If we want to output the result set, we need to know the number of rows and columns of the result set? Solution: The number of columns in the result set is not encapsulated in rs but in a metadata (metaData) called the result set;

  • Problem solution 2: *The result set stores pure data, while the metadata of the result set stores the modification of the data, such as the number of rows and columns of the data. . .

get result set

After getting the result set, we need to assign the data in the result set to the specified properties of the corresponding object and output them;

  1. At this point, we encounter two problems. When we output the metadata of the result set, ① first, we need to know which object the result set corresponds to; ② secondly, we need to know the number of rows and columns of the result set so that we can control the number of output and assignment , ③We also need to use the data type of the result set to judge which attribute of the class it corresponds to so that it can be assigned correctly;

    • Question ①: Through the generic mechanism (?)

    • Question ②: The result set and the number of rows and columns are encapsulated in the metadata of the result set. You can get the number of columns in the result set through getColumnCount(), and then use rs.next() to determine whether there is the next piece of data;

    • Field field = clazz.getDeclaredField(columnName);Question ③: Obtain the attribute value corresponding to the data through reflection technology , and then set the access permission of the attribute, in case the attribute is private and cannot be modified, and finally assign the corresponding value field.set(t, columnvalue);;

To close each resource, this operation is also encapsulated in the JDBCUtils tool class;

Complete code example:

public <T> List<T> getForList(Class<T> clazz, String sql, Object ... args) {
         /*
          *@auther 卢永鹏
          *Description 针对不同表,写一个通用的查询操作,返回多条记录;
          *@Date 10:39 2023/1/3
          *@param [sql, args]
          *@Return void
          **/
         Connection conn = null;
         PreparedStatement ps = null;
         ResultSet rs = null;
         try {
             conn = JDBCUtils.getConnection();
             ps = conn.prepareStatement(sql);
             for (int i = 0; i < args.length; i++) {
                 ps.setObject(i + 1, args[i]);
             }
             //执行
             rs = ps.executeQuery();
             //遇见问题:获得结果集之后我们如何将它输出在屏幕上,如何获取他的行和列数?
             //解决:结果集的列数没有封装在rs中而是封装在一个叫结果集的元数据(metaData)中;
             ResultSetMetaData metaData = rs.getMetaData();
             int col = metaData.getColumnCount();
             //rs.next():判断结果集的下一条是否有元数据,有返回true,否则返回false;
 //        emp emp = new emp();错误:写到这里不妥,如果没查到数据,那么对象还是会被创造,有点浪费;
             //创建集合
             ArrayList<T> list = new ArrayList<>();
             while (rs.next()) {
 //        emp emp = new emp();
                 T t = clazz.newInstance();
                 //处理一行数据中的每一个列
                 for (int i = 0; i < col; i++) {
                     Object columnvalue = rs.getObject(i + 1);
                     //遇见问题:我们如何将value保存到对应的属性中;
                     //解决。先建造一个空参的对象,然后通过value的列名判断出对应属性并赋值
                     //获取每个列的列名,rs中也是没有封装这个获取列名的方法,所以我们还是通过结果记得元数据来获取列名;
                     String columnName = metaData.getColumnName(i + 1);
                     //遇见问题:如何通过列名拿到Emp对象中与之对应的属性
                     //解决:使用反射技术来获取属性名
                     Field field = clazz.getDeclaredField(columnName);
                     field.setAccessible(true);//这个属性可能是私有的,所以设置访问权限
                     field.set(t, columnvalue);
                 }
                 list.add(t);
             }
             return list;
         } catch (Exception e) {
             e.printStackTrace();
         } finally {
             JDBCUtils.closeResource(conn, ps, rs);
         }
         return null;
     }

Roughly state the above process:

We first obtained the metadata object of the result set, and then obtained the number of columns of the rs result set data (function, controlling the number of for loops), and then controlled the number of while loops through if(rs.next()) , and then get the columnValue in the while loop, then get the corresponding column name columnName through columnValue, and then find the corresponding property name Field field = clazz.getDeclaredFiled(columnName); then set the property through filed.setAccessible(true); Setting permissions to prevent private properties from being set from the outside;


Guess you like

Origin blog.csdn.net/m0_64231944/article/details/129152872