Java implements simple BaseDao with custom annotations and Reflections

In common ORM frameworks, annotations are mostly used to map entity to database. Here, we simply use custom annotations and reflections to generate executable sql statements.

This is the overall directory structure, which was originally established for reviewing annotations.^

Okay, let's first determine the idea.

1. Customize the @Table@Column annotation,

We mimic hibernate slightly and let @Table act on classes to express the mapping relationship between entity classes and tables, and let @Table's attribute value be mapped to the name tableName of the tables; let @Column act on attributes (which is not implemented on set method here), indicating the mapping relationship between attributes and tables fields, and let @Column's attribute value be mapped to some part of the tables. Column Name.

2. We need to imitate a Dao layer.

At this point, we first define an entity User with name and password attributes, and then define a UserDao. There is a method of save (User user) in UserDao. When we instantiate a UserDao and User, we call the save method of UserDao, pass in our User object and return a section of sql, which we simply set as "insert into user (name,password). ) VALUES ('cai','123456'), where user is our data table name, name,password is the data table field,'cai','123456'is the attribute of the user object.

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

//Column.java
package com.shu.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Column {
    String value();
}
//Table.java
package com.shu.annotation;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.METHOD,ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Table {
    String value();
    
}
//User.java
package com.shu.entity;
import com.shu.annotation.Column;
import com.shu.annotation.Table;

@Table("t_user")
public class User {
    
    @Column("name")
    private String name;
    @Column("password")
    private String password;
    
    public String getName() {
        return name;
    }
    public String getPassword() {
        return password;
    }
    public void setName(String name) {
        this.name = name;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    
}
//IBaseDao.java
package com.shu.dao;
import java.lang.reflect.Field;

import com.shu.annotation.Column;
import com.shu.annotation.Table;

public interface IBaseDao<T> {
    
    //The ultimate goal is: insert into user (NAME,password) VALUES('cai','123456');
    default String save(T entity) throws IllegalArgumentException, IllegalAccessException{
        //sql Used to store the final returned sql Sentence
        StringBuilder sql = new StringBuilder("insert into ");
        //tableName Used for storing sql Table Name Section in Statement
        StringBuilder tableName;
        //columnName Used for storing sql The field part of the statement
        StringBuilder columnName = new StringBuilder("(");
        //values Used for storing sql The assignment part of a statement
        StringBuilder values = new StringBuilder("(");
        //Get objects user Of class object
        Class clazz = entity.getClass();
        //Judge the User Are there any classes?@Table annotation
        boolean isTable = clazz.isAnnotationPresent(Table.class);
        if(isTable) {
            //Obtain User class@Table Explanatory value value,This value is defined as User Table name of table
            Table t = (Table) clazz.getAnnotation(Table.class);
            tableName = new StringBuilder(t.value());
            //Splice table name
            sql.append(tableName+" ");
            //Obtain user Object property list
            Field[] fieldList = clazz.getDeclaredFields();
            //Traverse the list of attributes and take out the list of attributes.@Column Annotated attributes and get the value of attributes
            for(int i=0;i<fieldList.length;i++){
                Field f =  fieldList[i];
                boolean isColumn = f.isAnnotationPresent(Column.class);
                if(!isColumn){
                    continue;
                }
                Column column = f.getAnnotation(Column.class);
                 f.setAccessible(true); 
                Object columnValue = f.get(entity);
                if(i==fieldList.length-1){
                    columnName.append(column.value()+") VALUES ");
                    values.append("'"+columnValue+"')");
                    sql.append(columnName);
                    sql.append(values);
                    continue;
                }
                columnName.append(column.value()+", ");
                values.append("'"+columnValue+"',");
            }
            
//            boolean isColumn = clazz.isAnnotationPresent(annotationClass);
        }
        return sql.toString();
    }


}
//UserDao.java
package com.shu.dao;

import com.shu.entity.User;

public class UserDao implements IBaseDao<User> {

}
//UserService.java
package com.shu.service;
import com.shu.dao.UserDao;
import com.shu.entity.User;

public class UserService {
    
    public static void main(String[] args) {
        // TODO Auto-generated constructor stub
UserDao userDao = new UserDao(); User user = new User(); user.setName("cai"); user.setPassword("123456"); try { System.out.println(userDao.save(user)); } catch (IllegalArgumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

 

Here we finally define a Service layer, which calls the dao layer and generates corresponding sql statements. You can customize other Entity, such as Order in my directory, then define an OrderDao to implement IBaseDao interface, define an OrderService to call the save method of OrderDao, and also generate sql statements corresponding to the order table.

 

Here we summarize the shortcomings:

1.hibernate's annotations can be obtained without assignment, so I think that in order to obtain the names of tables or fields directly without assignment, we can use reflection method to obtain them.

2. Only save method is done here, and sql statements are generated dynamically, without interacting with the database. A factory can be packaged to provide persistence method to implement the execution of sql statements.

3. The splicing of sql is rough here. You may wonder if there are other more efficient methods.

Above.

Keywords: Java SQL Attribute Database

Added by hucklebezzer on Wed, 29 May 2019 20:40:50 +0300