Implement the Dao layer with custom annotations

Definition (Baidu entry)

Annotation ( Annotation ), also called metadata. A code-level description. It is a feature introduced by JDK1.5 and later versions, and it is at the same level as classes, interfaces, and enumerations. It can be declared in front of packages, classes, fields, methods, local variables, method parameters, etc. to describe and annotate these elements.

 

       For example, our most common @Override is annotation. In addition to JDK and third-party annotations, some unexpected effects can be achieved through custom annotations. Here we use custom annotations to implement the Dao layer in JDBC, and you can experience the magic of custom annotations through examples.

 

First look at the syntax requirements of custom annotations

@Target({Element.METHOD,Element.TYPE}) //The location of the annotation
@Retention(RUNTIME)//The time of the annotation

//Use the @interface key to define annotations
Public @interface Description{
//Members are declared with no arguments and no exceptions
   String desc();
   String author();
//You can use default to specify a default value for the member
   Int age() default 18;
}

There are also the following notes about custom annotations:

1. Member types are limited, and legal types include primitive types and String Class Annotation Enumeration

2. If the annotation has only one member, the member must be named value(). The member name and assignment number (=) can be ignored when using it.

3. An annotation class can be an annotation that has no members and no members.


The following is an example of querying student information to show the magic of custom annotations.

//Annotation about the table name
package test;

import static java.lang.annotation.ElementType.TYPE;
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(TYPE)
/**
*@author Nut
*@version on March 26, 2018 at 10:48:49 PM
*Custom annotations:
* By getting the value of value, you can get the table name in the database to be used
* Annotation describing the user table
*/
public @interface TableName {

	String value();
}
Notes on column names in tables
package test;

import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.RetentionPolicy.RUNTIME;

import java.lang.annotation.Retention;
import java.lang.annotation.Target;

@Retention(RUNTIME)
@Target(FIELD)
/**
*@author Nut
*@version on March 26, 2018 at 10:51:47 PM
*Custom annotations:
*By getting the value of value, you can get the column name of the database table
* Annotation describing the attribute field of the user table
*/
public @interface ColumnName {

	String value();
}


//A Student class
package test;

/**
 * @author Nut
 * @version on March 26, 2018 at 10:37:12 PM about students
 */

@TableName("student")
public class Student {

	// student ID
	@ColumnName("ID")
	private String stuid;
	// student name
	@ColumnName("name")
	private String stuname;
	// student age
	@ColumnName("age")
	private int stuage;
	// student's birthplace
	@ColumnName("birthcity")
	private String stubirthcity;
	// student email
	@ColumnName("email")
	private String stuemail;

	public Student() {
	}

	public Student(String stuID, String stuName, int stuAge, String stuBirthCity, String email) {
		super();
		this.stuid = stuID;
		this.stuname = stuName;
		this.stuage = stuAge;
		this.stubirthcity = stuBirthCity;
		this.stuemail = email;
	}

	public String getStuid() {
		return stuid;
	}

	public void setStuid(String stuid) {
		this.stuid = stuid;
	}

	public String getStuname() {
		return stuname;
	}

	public void setStuname(String stuname) {
		this.stuname = stuname;
	}

	public int getStuage() {
		return stuage;
	}

	public void setStuage(int stuage) {
		this.stuage = stuage;
	}

	public String getStubirthcity() {
		return stubirthcity;
	}

	public void setStubirthcity(String stubirthcity) {
		this.stubirthcity = stubirthcity;
	}

	public String getStuemail() {
		return stuemail;
	}

	public void setStuemail(String stuemail) {
		this.stuemail = stuemail;
	}

}
// Below is the most important! ! !

Some related functions (Class class)

getAnnotation(Class<A> annotationClass)

          Returns annotations of the specified type for this element if they exist, otherwise returns null.

getAnnotations()

          Returns all annotations present on this element.

getDeclaredAnnotations()

          Returns all annotations that exist directly on this element.

getDeclaredMethod(String name, Class<?>... parameterTypes)

          Returns an Methodobject that reflects Classthe specified declared methods of the class or interface represented by this object.

getDeclaredMethods()

MethodReturns           an array of objects that reflect Classall methods declared by the class or interface represented by this object, including public, protected, default (package) access, and private methods, but not inherited methods.

getMethod(String name, Class<?>... parameterTypes)

          Returns an Methodobject that reflects Classthe specified public member methods of the class or interface represented by this object.

getMethods()
          Returns an array containing Methodobjects that reflect the public member methods Classof the class or interface represented by this object (including those declared by that class or interface and those inherited from superclasses and superinterfaces) .

getDeclaredField(String name)

          Returns an Fieldobject that reflects Classthe specified declared fields of the class or interface represented by this object.

getDeclaredFields()

FieldReturns           an array of objects reflecting Classall the fields declared by the class or interface represented by this object.

getField(String name)

          Returns an Fieldobject that reflects Classthe specified public member fields of the class or interface represented by this object.

getFields()
          Returns an array containing Fieldobjects that reflect Classall accessible public fields of the class or interface represented by this object.

getName()

Returns the name of the entity (class, interface, array class, primitive type, or void) represented by this Class object as           a String.

isAnnotation()

Returns true           if this Class object represents an annotation type.

isAnnotationPresent(Class<? extends Annotation> annotationClass)
          Returns true if an annotation of the specified type exists on this element, false otherwise.


package test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 * @author Nut
 * @version on March 27, 2018 at 8:48:26 AM
 * Return the sql statement by passing in the conditions to be queried
 * The advantage is that you only need to use one function whether it returns the ID or the name.
 */
public class returnSql {

	/**
	 * @param obj
	 * @return returns the query statement
	 */
	public static String testQuery(Object obj) {
		// store the sql statement to return
		StringBuilder sb = new StringBuilder();
		Class<?> c1 = obj.getClass();
		/*
		 * Whether to include the annotation of TableName type is guaranteed for the database to include the table in the database
		 */
		if (!c1.isAnnotationPresent(TableName.class)) {
			return null;
		}
		// Get the name of the table
		TableName t = (TableName) c1.getAnnotation(TableName.class);
		String tableName = t.value();
		// Concatenate the table name into the sql statement
		// 1=1 ensures that the sql statement is normal when there is no query condition
		sb.append("select * from ").append(tableName).append(" where 1=1");
		//
		Field[] fields = c1.getDeclaredFields();
		// By judging the different types of fields, process them separately, and splicing sql statements
		for (Field field : fields) {
			/*
			 * Whether to include the ColumnName annotation for the database is whether to include the column name in the table
			 */
			if (!field.isAnnotationPresent(ColumnName.class)) {
				continue;
			}
			// get the column name
			ColumnName cn = (ColumnName) field.getAnnotation(ColumnName.class);
			String columName = cn.value();
			// Get the value through the get method
			Object methodValue = null;
			String methodName = field.getName();
			String getMethodName = "get" + methodName.substring(0, 1).toUpperCase()
					+ methodName.substring(1).toLowerCase();
			try {
				Method method = c1.getMethod(getMethodName);
				methodValue = method.invoke(obj);
			} catch (Exception e) {
				e.printStackTrace ();
			}
			if (methodValue == null || (methodValue instanceof Integer && (Integer) methodValue == 0)) {
				continue;
			}
			sb.append(" and ").append(columName);
			if (methodValue instanceof String) {
				if (((String) methodValue).contains(",")) {
					String[] s = ((String) methodValue).split(",");
					sb.append(" in(");
					for (String string : s) {
						sb.append("'").append(string).append("',");
					}
					sb.deleteCharAt(sb.length() - 1);
					sb.append(")");
				} else {
					sb.append("='").append(methodValue).append("'");
				}
			} else if (methodValue instanceof Integer) {
				sb.append("=").append(methodValue);
			}
		}
		return sb.toString();
	}

}
//This is a database connection Class

For this part, please refer to my other blog JDBC detailed explanation

package test;

/**
*@author Nut
*@version March 26, 2018 at 10:58:37 PM
*/
import java.sql.*;

public class DBhelper {

	// SqlServer database driver
	private static String driverName = "com.microsoft.sqlserver.jdbc.SQLServerDriver";

	// SqlServer database link address
	private static String dbURL = "jdbc:sqlserver://localhost:1433;DatabaseName=Stu";// ? name for your database

	// Name database
	private static String userName = "sa";// ? = your database name

	// database password
	private static String userPwd = "*****";// ? = your database password

	private static Connection conn = null;

	// static code block to load database driver
	static {
		try {
			Class.forName(driverName);
		} catch (ClassNotFoundException e) {
			e.printStackTrace ();
		}
	}

	// return database connection via singleton pattern
	public static Connection getConnection() throws SQLException {

		if (conn == null) {
			conn = DriverManager.getConnection(dbURL, userName, userPwd);
		}
		return conn;

	}

	public static void main(String[] args) {

		Connection conn;
		try {
			conn = DBhelper.getConnection();
			if (conn != null) {
				System.out.println("Database connection is successful");
			} else {
				System.out.println("Database connection failed");
			}
		} catch (SQLException e) {
			e.printStackTrace ();
		}

	}
}
//run sql statement
package test;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * @author Nut
 * @version March 27, 2018 1:02:23 PM Query the database through the query statement returned by returnSql
 */
public class executeSql {
	/*
	 * select statement query
	 */
	public static Student executeQuerySql(Object obj) {
		Connection conn = null; // database connection
		PreparedStatement stmt = null; // precompiled execution is relatively fast
		ResultSet rs = null; // result set

		try {
			conn = DBhelper.getConnection();// Implement database connection
			String sql = returnSql.testQuery(obj);
			// Enter the SQL statement, and use + to realize the dynamic transfer of data
			stmt = conn.prepareStatement(sql); // Prepare SQL statement
			rs = stmt.executeQuery();

			// Statements that produce a single result set, such as a SELECT statement. The most used method of executing SQL statements is
			// executeQuery. This method is used to execute the SELECT statement, which is almost the most used SQL statement

			if (rs.next()) {
				Student student = new Student();// Instance an object
				student.setStuid(rs.getString("ID"));
				student.setStuname(rs.getString("name"));
				student.setStuage(rs.getInt("age"));
				student.setStubirthcity(rs.getString("birthcity"));
				student.setStuemail(rs.getString("email"));
				// rs.getString("D#") gets the value in the result set and copies it through the SETTER function
				return student;// return object
			}
			return null;
		} catch (SQLException e) {
			e.printStackTrace ();
			return null;
		} finally {
			// close the result set
			if (rs != null) {
				try {
					rs.close();
					rs = null; // Assigning to null is equivalent to deleting
				} catch (SQLException e) {
					e.printStackTrace ();
				}
			}
			if (stmt != null) {
				try {
					stmt.close();
					stmt = null;
				} catch (SQLException e) {
					e.printStackTrace ();
				}
			}
		}
	}//end

}
// test class
package test;
/**
*@author Nut
*@version on March 27, 2018 at 1:00:53 PM
*/
public class test {

	public static void main(String[] args) {
		Student s1 = new Student();
		s1.setStuname("A");
		Student newStu1 = executeSql.executeQuerySql(s1);
		System.out.println(newStu1.getStuid());
		
		Student s2 = new Student();
		s2.setStuid("s003");
		Student newStu2 = executeSql.executeQuerySql(s2);
		System.out.println(newStu2.getStuname());
 
	}

}

result:



Database Design and Data



Finally: it can be seen that custom annotations can provide us with a new idea for writing database connections. Compared with the method I provided before, it has better compatibility.

The last one: It is not easy to write, if it is useful to you, please give it a like!




Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325495969&siteId=291194637