Class. forName ("com. mysql. jdbc. Driver");, jdbcclass. forname
Try {Class. forName ("com. mysql. jdbc. driver ");} catch (ClassNotFoundException e) {System. out. println ("The driver class cannot be found. Failed to load the driver! "); // TODO}
In the above Code, class. forName ("com. mysql. jdbc. driver "); the main function is to check the main class com. mysql. jdbc. indicates whether the Driver exists. If it is not stored, the Driver is not in the running environment and enters the catch section. If you are sure it exists, you can directly write it as import com. mysql. jdbc. driver; the effect is basically the same (only ensure that this class exists in classpath during compilation and runtime). Therefore, one advantage of loading in reflection mode is that when the Driver jar package does not exist, we can do more operations. (You know, a long time ago, jdbc drivers were generally placed in the classpath of the runtime environment, as shown intomcat/lib
).
Another important reason is decoupling. First of all, we must understand that JDBC is a Java specification. In other words, JDKjava.sql.*
Provides a series of interfaces, but does not provide any implementation (that is, class ). Therefore, anyone can write their own JDBC implementation (such as MySQL) under the interface specification ). If the caller only calls methods on the interface (for example, We), when there is any need for future changes (for example, migrating from MySQL to Oracle ), in theory, you can switch directly without making any changes to the Code (unfortunately, the SQL syntax is not standardized). What does this mean? This means that your code should not reference anything related to implementation. Your code only knowsjava.sql.*
Instead of knowingcom.mysql.*
Orcom.oracle.*
To avoid or reduce code changes when data sources are switched in the future. Note that all other APIs we use includeConnection
/Statement
/ResultSet
Alwaysjava.sql.*
Or evencom.mysql.jdbc.Driver
Class: Therefore, directimport com.mysql.jdbc.Driver;
Violation of the open/closed principle (OCP, open to extensions, and closed to modifications ). (Some people say that I have to modify the code when using reflection. In fact, you can store the class name string. properties file, which is put together with the database username and password, just like what Hibernate does ).
If I can ensure that the JDBC Driver must be under classpath, can I not write this reflection code or reference any Driver class? The answer is no. Please refer to the following code source:com.mysql.jdbc.Driver
:
package com.mysql.jdbc;public class Driver extends NonRegisteringDriver implements java.sql.Driver { // // Register ourselves with the DriverManager // static { try { java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } } ...}
The static code block will be executed when the class is loaded, that is, when we executeClass.forName("com.mysql.jdbc.Driver")
Hour (orimport com.mysql.jdbc.Driver
)
The use of reflection makes Java more dynamic. Query an SQL statement to obtain a query result, such as select * from user where id = 1; obtain fields such as id, userName, email, and pwd, and their corresponding values, however, your goal is not only to obtain these fields, but to encapsulate these fields into User objects for future use.
If you only have one User class, you can write an util class to assign these fields to each attribute of the User object. However, you still have many entity classes in project development. What should you do? Every one writes an util class? When the object property changes, must it be rewritten? At this time, the reflection mechanism can implement this general method, pass in the queried ResultSet and the Class of the object you want, get the field list in the Class through reflection, and get the corresponding value from the ResultSet, use reflection to call the set method corresponding to the filed in the Class to encapsulate the object.