reflection

Reflection: Encapsulating the components of a class into other objects is a reflection mechanism * advantage 1. These objects can be operated during the running of the program. 2. It can be decouple to improve the scalability of the program

Three ways to get a class object

  1. Class.forname (” full Class name “) : Loads the bytecode file into memory and returns a Class object
    • The class name is defined in the configuration file. Read the file and load the class
  2. Class: obtained from the class attribute of the class name
    • Mostly used for passing parameters
  3. Object. GetClass () : The getClass() method is defined in the Object class.
    • A method of obtaining bytecode for an object
  • Conclusion:

The same bytecode file (*.class) is loaded only once during a program run, and the class object is the same regardless of which way it is retrieved.

The functionality of the class object

  • Class object features:
    • Access function:
      1. Get the member variables

        • Field[] getFields() : Gets all public decorated member variables

        • Field getField(String name) Gets the public decorated member variable of the specified name

        • Field[] getDeclaredFields() retrieves all member variables, regardless of modifiers

        • Field getDeclaredField(String name)

      2. Get the constructors

        • Constructor<? >[] getConstructors()

        • Constructor getConstructor (class <? >… parameterTypes)

        • Constructor getDeclaredConstructor (class <? >… parameterTypes)

        • Constructor<? >[] getDeclaredConstructors()

      3. Get member methods:

        • Method[] getMethods()

        • Method getMethod(String name, class <? >… parameterTypes)

        • Method[] getDeclaredMethods()

        • Method getDeclaredMethod(String name, class <? >… parameterTypes)

      4. Gets the full class name

        • String getName()

Member variables

  • Field: member variable
    • Operation:
      1. Set the value

        • void set(Object obj, Object value)
      2. Get the value

        • get(Object obj)
      3. Ignore security checks for access modifier

        • SetAccessible (True): Violent reflex

A constructor

  • (4) Constructor
    • Create an object:
      • T newInstance(Object… initargs)

      • If you use the null parameter constructor to create an object, the operation can be simplified: newInstance on a Class object

Method Method object

  • Method: Method object
    • Execution method:

      • Object invoke(Object obj, Object… args)
    • Obtain method name:

      • String getName: Gets the method name

Case examples

  • Case study:
    • Requirement: Write a “framework” that can help us create objects of any class and execute any of its methods without changing any code of the class
      • Implementation:
        1. The configuration file
        2. reflection
      • Steps:
        1. Define the full class name of the object you want to create and the method you want to execute in the configuration file
        2. Load the read configuration file in the program
        3. Use reflection to load class files into memory
        4. Create an object
        5. Execution method

The specific implementation

test.properties

className=com.mayishijie.reflect.domain.Demo
publicMethodName=show
privateMethodName=show1
privateFiledName=name
Copy the code

domain

/ * * *@author tty
 * @dateThe 2020-03-15 19:28 * /
public class Demo {
    private String name ;

    public void show(String age) {
        System.out.println("show ....."+age);
    }

    private void show1(int age) {
        System.out.println("show1 ......."+age);
    }
    public String getName(a) {
        return name;
    }

    public void setName(String name) {
        this.name = name; }}Copy the code

TestDemo

import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Properties;

/ * * *@author tty
 * @dateThe 2020-03-15 15:49 * /
public class TestDemo {
    public static void main(String[] args) throws Exception{
        /** * Examples of the use of reflection, fully qualified class names are configured in configuration files (the underlying core principle of the framework is reflection, * most frameworks are in the form of configuration XML files or annotations, but the basic principle is the same, this example is a sample framework) * Most configuration files are read by the Properties class */
        Properties properties = new Properties();
        InputStream resourceAsStream =  TestDemo.class.getClassLoader().getResourceAsStream("test.properties");
        properties.load(resourceAsStream);
        //1. Obtain permission set class name
        String className = properties.getProperty("className");
        String publicMethodName = properties.getProperty("publicMethodName");
        String privateMethodName = properties.getProperty("privateMethodName");
        String privateFiledName = properties.getProperty("privateFiledName");
        //2. Load the class into memory
        Class cls = Class.forName(className);
        //3. Create an object
        Object obj = cls.newInstance();
      
        //4. Get the class method (currently a public modified method, and the argument type is String)
        Method publicMethod = cls.getMethod(publicMethodName,String.class);
        //4.1 Executes public methods and passes in arguments
        publicMethod.invoke(obj,"23");
      
        //5. Get the private method (the current method is private and the type is int)
        Method declaredMethod = cls.getDeclaredMethod(privateMethodName, int.class);
        //5.0 sets security checks to ignore access modifiers
        declaredMethod.setAccessible(true);
        //5.1 Executes a private method and passes in parameters
        declaredMethod.invoke(obj, 22);
      
        //6. Set values for private attributes
        Field declaredField = cls.getDeclaredField(privateFiledName);
        declaredField.setAccessible(true);
        declaredField.set(obj, "mayi"); System.out.println(declaredField.get(obj)); }}Copy the code

Personal understanding of reflection

1. Reflection is the cornerstone of the framework. The framework can be configured to achieve object generation and mapping based on reflection principle 2. Study mybatis and Spring source code, you can understand the reflection mechanismCopy the code

JDBC

1.Java DataBase Connectivity is a set of rules that operate all relational databases, that is, interfaces. Each database vendor to implement this interface, provide the database driver JAR package. We can program using this set of interfaces (JDBC), and the actual code that executes is the implementation class in the driver JAR package.2.Quick Start: * Steps:1.Import the driver jar package mysql-connector-java-5.137.-bin.jar
			1.Copy the mysql connector - Java -5.137.-bin. Jar to the libs directory of the project2.Right click -->Add As Library2.Registration drive3.Gets the database Connection object Connection4.Define the SQL5.Gets the Statement object where the SQL Statement is executed6.Execute the SQL and accept the return results7.The processing results8.Free resources * code implementation:Import the driver JAR package
        //2. Register the driver
        Class.forName("com.mysql.jdbc.Driver");
        //3. Obtain the database connection object
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3"."root"."root");
        //4. Define SQL statements
        String sql = "update account set balance = 500 where id = 1";
        //5. Obtain Statement
        Statement stmt = conn.createStatement();
        / / 6. Execute SQL
        int count = stmt.executeUpdate(sql);
        //7. Processing result
        System.out.println(count);
        //8. Release resources
        stmt.close();
        conn.close();

3.Detail each object:1.DriverManager: Driver managed object *1.Register driver: tells the program which database driver to usejar
				static void registerDriver(Driver driver): Registers with the given driver DriverManager. Write code using: Class.forName("com.mysql.jdbc.Driver"); Static code blocks are found in the com.mysql.jdbc.driver classstatic {
				        try {
				            java.sql.DriverManager.registerDriver(new Driver());
				        } catch (SQLException E) {
				            throw new RuntimeException("Can't register driver!"); }} Note: the driver JAR package after mysql5 can omit the step of registering the driver.2.Obtain database connection:static Connection getConnection(String url, String user, String password)Url: specifies the connection path.// IP address (domain name): port number/database nameExample: JDBC :mysql://localhost:3306/db3* Details: If you are connecting to a native mysql server and the default mysql service port is 3306, the URL can be shortened to: JDBC :mysql:// database name* user: user name * password: password 2. Connection: database Connection object 1. Run the following command to obtain the SQL StatementcreateStatement(a)
				* PreparedStatement prepareStatement(String sql)2. Manage transaction: * Start transaction:setAutoCommit(boolean autoCommit): Calls this method and sets the parameter tofalse, that is, start transaction * Commit transaction:commit(a)* Rollback transaction:rollback(a)3. Statement: object where SQL is executed 1.boolean execute(String sql): Can execute arbitrary SQL understand 2.int executeUpdate(String sql): Execute DML (INSERT, UPDATE, delete) statements,DDL(create, alter, drop)Statement * Return value: number of affected rows. You can determine whether the DML statement is successfully executed based on the number of affected rows. If the return value is greater than 0, the DML statement is successfully executed. 3. ResultSetexecuteQuery(String sql)Add a record to the account table. Modify a record to the account table. Delete a record from the account table= null;
		        Connection conn = null;
		        try {
		            //1. Register the driver
		            Class.forName("com.mysql.jdbc.Driver");
		            / / 2. Define the SQL
		            String sql = "Insert into account values(null,' h5 ',3000)";
		            //3. Obtain the Connection object
		            conn = DriverManager.getConnection("jdbc:mysql:///db3"."root"."root");
		            //4. Obtain Statement
		            stmt = conn.createStatement();
		            / / 5. Execute SQL
		            int count = stmt.executeUpdate(sql);// The number of rows affected
		            //6. Processing result
		            System.out.println(count);
		            if(count > 0){
		                System.out.println("Added successfully!");
		            }else{
		                System.out.println("Add failed!"); }}catch (ClassNotFoundException e) {
		            e.printStackTrace();
		        } catch (SQLException e) {
		            e.printStackTrace();
		        }finally {
		            //stmt.close();
		            //7. Release resources
		            // Avoid null pointer exceptions
		            if(stmt ! =null) {try {
		                    stmt.close();
		                } catch(SQLException e) { e.printStackTrace(); }}if(conn ! =null) {try {
		                    conn.close();
		                } catch(SQLException e) { e.printStackTrace(); }}}4.ResultSet: a ResultSet object that encapsulates query results *boolean next(a): Cursor moves down a line to determine if the current line is the end of the last line(Data available)If so, returnfalseIf not, returntrue
		* getXxx(parameters): Obtain data * Xxx: indicates the data type, such as:int getInt(a) ,	String getString(a)* Parameter: 1.int: indicates the column number, starting from 1.getString(1)2. String: indicates the column name. Such as:getDouble("balance")* Note: * Use steps: 1. Move the cursor down a line 2. Check whether there is data 3. To get the data// Loop to determine if the cursor is the end of the last line.
	            while(rs.next()){
	                // Get data
	                6.2 Obtaining Data
	                int id = rs.getInt(1);
	                String name = rs.getString("name");
	                double balance = rs.getDouble(3);
	
	                System.out.println(id + "-" + name + "-"+ balance); } * Exercise: * Define a method to query the data of the EMP table and encapsulate it as an object, then load the collection and return.1.Define the Emp class2.Define methodspublic List<Emp> findAll(a){}
				3.Select * from emp;5.PreparedStatement: An object for executing SQL1.SQL injection problem: When concatenating SQL, there are some special SQL keywords involved in concatenating strings. This can cause security problems1.Enter the user casually, enter the password: A' or 'a'='a
			2.SQL: SELECT * from user where username ='fhdsjkf' and password = 'a' or 'a' = 'a' 

		2.Fix SQL injection problems: Use PreparedStatement objects3.Precompiled SQL: parameter use? As a placeholder4.Steps:1.Import the driver jar package mysql-connector-java-5.137.-bin.jar
			2.Registration drive3.Gets the database Connection object Connection4.Define SQL * Note: SQL parameters use? As a placeholder. Select * from user where username =? and password = ? ;5.Access to execute SQL statements PreparedStatement object Connection. PrepareStatement (String SQL)6.Give? Assignment: * Method: setXxx(argument1, the parameter2) * parameter1:? The location number is from1Start * parameters2:? The value of the7.Execute the SQL and accept the results returned without passing the SQL statement8.The processing results9.Release resources5.Note: PreparedStatement will be used to complete all operations of adding, deleting, modifying and checking1.You can prevent SQL injection2.More efficientCopy the code

Extract the JDBC utility class: JDBCUtils

* Purpose: simplify writing * analysis: 1. Register driver also extract 2. Extract a method to get the connection object * Requirement: do not want to pass parameters (trouble), but also ensure the universality of the utility class. Jdbc.properties url= user= password= 3. Extract a method to release the resourceCopy the code

Code implementation

public class JDBCUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    /** * file read, only need to read once to get these values. Use static code blocks */
    static{
        // Read the resource file to get the value.

        try {
            // create the Properties collection class.
            Properties pro = new Properties();

            // how to get files in SRC path -->ClassLoader ClassLoader
            ClassLoader classLoader = JDBCUtils.class.getClassLoader();
            URL res  = classLoader.getResource("jdbc.properties");
            String path = res.getPath();
            System.out.println(path);///D:/IdeaProjects/itcast/out/production/day04_jdbc/jdbc.properties
            //2. Load the file
           // pro.load(new FileReader("D:\\IdeaProjects\\itcast\\day04_jdbc\\src\\jdbc.properties"));
            pro.load(new FileReader(path));

            //3. Get data, assign value
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //4. Register drivers
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
      
      
       /** * get connection *@returnConnection object */
    public static Connection getConnection(a) throws SQLException {

        return DriverManager.getConnection(url, user, password);
    }

    /** * Release resources *@param stmt
     * @param conn
     */
    public static void close(Statement stmt,Connection conn){
        if( stmt ! =null) {try {
                stmt.close();
            } catch(SQLException e) { e.printStackTrace(); }}if( conn ! =null) {try {
                conn.close();
            } catch(SQLException e) { e.printStackTrace(); }}}}Copy the code

case

demand

* select * from user where username = "" and password = ""; * If the SQL query has a result, it succeeds; otherwise, it fails. CREATE TABLE user CREATE TABLE user (id INT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(32), PASSWORD VARCHAR(32)); INSERT INTO USER VALUES(NULL,'zhangsan','123'); INSERT INTO USER VALUES(NULL,'lisi','234');Copy the code
public class JDBCDemo9 {

			    public static void main(String[] args) {
			        //1. Keyboard input, accept user name and password
			        Scanner sc = new Scanner(System.in);
			        System.out.println("Please enter user name:");
			        String username = sc.nextLine();
			        System.out.println("Please enter your password:");
			        String password = sc.nextLine();
			        //2. Call the method
			        boolean flag = new JDBCDemo9().login(username, password);
			        //3. Check the result and output different statements
			        if(flag){
			            // Login succeeded
			            System.out.println("Login successful!");
			        }else{
			            System.out.println("Wrong username or password!"); }}/** * Login method */
			    public boolean login(String username ,String password){
			        if(username == null || password == null) {return false;
			        }
			        // Connect to the database to check whether the login is successful
			        Connection conn = null;
			        Statement stmt =  null;
			        ResultSet rs = null;
			        //1. Obtain the connection
			        try {
			            conn =  JDBCUtils.getConnection();
			            / / 2. Define the SQL
			            String sql = "select * from user where username = '"+username+"' and password = '"+password+"'";
			            //3. Get the object to execute the SQL
			            stmt = conn.createStatement();
			            //4. Execute the query
			            rs = stmt.executeQuery(sql);
			            / / 5. Judgment
			           /* if(rs.next()){// If there is a next line, return true; }else{ return false; } * /
			           return rs.next();// Returns true if there is a next line
			
			        } catch (SQLException e) {
			            e.printStackTrace();
			        }finally {
			            JDBCUtils.close(rs,stmt,conn);
			        }
            			        return false; }}Copy the code

JDBC Control transactions

/* 1. Transaction: a business operation consisting of multiple steps. If the business operation is transaction-managed, these steps will either succeed or fail at the same time. Operation: 1. Start transaction 2. Commit transaction 3. SetAutoCommit (Boolean autoCommit) : Call this method and set the parameter to false, i.e. start transaction * Start transaction before SQL execution * Commit transaction: Commit () * When all SQL has executed commit transaction * Rollback transaction: rollback() * Rollback transaction in catch 4. Code: * /
	public class JDBCDemo10 {
	    public static void main(String[] args) {
	        Connection conn = null;
	        PreparedStatement pstmt1 = null;
	        PreparedStatement pstmt2 = null;
	        try {
	            //1. Obtain the connection
	            conn = JDBCUtils.getConnection();
	            // Start the transaction
	            conn.setAutoCommit(false);
	            / / 2. Define the SQL
	            //2
	            String sql1 = "update account set balance = balance - ? where id = ?";
	            //2.2 + 500
	            String sql2 = "update account set balance = balance + ? where id = ?";
	            //3. Obtain the execution SQL object
	            pstmt1 = conn.prepareStatement(sql1);
	            pstmt2 = conn.prepareStatement(sql2);
	            //4. Set parameters
	            pstmt1.setDouble(1.500);
	            pstmt1.setInt(2.1);
	
	            pstmt2.setDouble(1.500);
	            pstmt2.setInt(2.2);
	            / / 5. Execute SQL
	            pstmt1.executeUpdate();
	            // Manually create an exception
	            int i = 3/0;
	
	            pstmt2.executeUpdate();
	            // Commit the transaction
	            conn.commit();
	        } catch (Exception e) {
	            // Transaction rollback
	            try {
	                if(conn ! =null) { conn.rollback(); }}catch (SQLException e1) {
	                e1.printStackTrace();
	            }
	            e.printStackTrace();
	        }finally {
	            JDBCUtils.close(pstmt1,conn);
	            JDBCUtils.close(pstmt2,null); }}}Copy the code

annotations

  • Concept: Describing a procedure. It’s for the computer

  • Note: Describing a program in words. For programmers

  • Definition: Annotations, also called metadata. A code level specification. It is a feature introduced in JDK1.5 and later and is on the same level as classes, interfaces, and enumerations. It can be declared in front of packages, classes, fields, methods, local variables, method parameters, etc., used to describe and comment these elements.

  • Concept Description:

    • New features after JDK1.5
    • Illustrative of procedure
    • Use annotation: @ annotation name
  • Code analysis: Analyze code by using annotations identified in the code. Compile check: Enable the compiler to implement basic compile checks by using annotations identified in the code.

  • Predefined annotations in the JDK

    • Override: tests whether the method marked by this annotation inherits from the parent class (interface)
    • Deprecated: Indicates the Deprecated content of this annotation
    • @suppresswarnings: SuppressWarnings
      • General pass parameter all@suppressWarnings (“all”)
  • Custom annotations

    • Format: meta annotation public @interface annotation name {attribute list; }

    • Essence: An Annotation is essentially an interface that inherits the Annotation interface by default

      • public interface MyAnno extends java.lang.annotation.Annotation {}
    • Properties: Abstract methods in an interface

      • Requirements:
        1. The return value type of the property has the following values

          • Basic data types
          • String
          • The enumeration
          • annotations
          • An array of the above types
        2. Defines attributes that need to be assigned when used

          1. If the default keyword is used to define the default initialization value of an attribute, the attribute assignment can be omitted when annotations are used.
          2. If only one attribute needs to be assigned and the attribute name is value, the value can be omitted and the value can be defined directly.
          3. When an array is assigned, the value is wrapped in {}. If there is only one value in the array, {} can be omitted
    • Meta-annotation: a annotation used to describe the annotation

      • @target: Describes where the annotation can be used
        • ElementType values:
          • TYPE: applies to classes
          • METHOD: Applies to methods
          • FIELD: Can be applied to member variables
      • @Retention: Describes the phase in which annotations are retained
        • @Retention(retentionPolicy.runtime) : The currently described annotations are retained in the class bytecode file and read by the JVM
      • Documented: Describe whether an annotation is extracted into an API document
      • Inherited: Describes whether an annotation is Inherited by a child class
  • Use (parse) annotations in the program: Get the values of the attributes defined in the annotations

    1. Gets the object (Class, Method,Field) where the annotation is defined

    2. Gets the specified annotation

      • getAnnotation(Class)

      // A subclass of the annotation interface is generated in memory

          public class ProImpl implements Pro{
              public String className(a){
                  return "cn.itcast.annotation.Demo1";
              }
              public String methodName(a){
                  return "show"; }}Copy the code
    3. Call the abstract method in the annotation to get the configured property values

  • Example: A simple testing framework

  • Summary:

    1. Most of the time, we will use annotations rather than custom annotations
    2. Who are the notes for?
      1. The compiler
      2. For the parser
    3. Annotations are not part of the program, and can be interpreted as a tag