Java annotation practice

Posted by Bikkebakke on Sun, 26 Jan 2020 17:40:58 +0100

Annotation practice

Roughly make a simple practice, make an ORM small scheme, and realize it by annotation

  • A user table information, field: id, user name, nickname, age, gender, address, email, mobile number
  • Simply retrieve each field or combination of conditions and print SQL to display the results

When retrieving data, we need to consider how to map with the database. The data corresponds to the Table name and field name. The user defined by human is also most similar to the database Table, such as JPA or others. You can add @ Table, @ Entry, @ Column and other annotation marks on the user object to correspond to the Table information of the database

Create an annotation below @MyTable , which can be applied to a class and can specify a table name with only one value, as follows:

import java.lang.annotation.*;

@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyTable {
    String value();
}

To define a @ MyColumn annotation for fields, you need a value, as follows:

import java.lang.annotation.*;

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface MyColumn {
    String value();
}

Annotate entity objects

@Data
@MyTable("user_info")
public class User {
    @MyColumn("id")
    private Integer id;
    @MyColumn("user_name")
    private String userName;
    @MyColumn("nick_name")
    private String nickName;
    @MyColumn("age")
    private Integer age;
    @MyColumn("address")
    private String address;
    @MyColumn("email")
    private String email;
}

Now that you have the basic object, you need to create SQL, define a query method, and roughly implement the following to return a string

package com.cloud.eureka.Practice;

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

public class UserMain {

    public static void main(String[] args) throws Exception {
        User user = new User();
        user.setId(9527);
        user.setNickName("Huaan");
        user.setAddress("Xiasha");
        user.setEmail("hello@163.com,hi@qq.com,biu@sina.com");
        user.setUserName("HaHaHa");
        String sql = query(user);
        System.out.println(sql);
    }

    public static String query(User user) throws Exception {
        String SQL_MODEL = "select %s from %s where 1=1%s";
        //1. Get the class test, get the User object directly, or the Class.forName() method
        Class c = user.getClass();

        //2. Get the name of Table
        boolean b = c.isAnnotationPresent(MyTable.class);
        if (!b) {
            return "Not Exist Table!";
        }
        MyTable myTable = (MyTable) c.getAnnotation(MyTable.class);
        String tableName = myTable.value();

        //3. Get all fields
        StringBuilder sbField = new StringBuilder();
        StringBuilder sbWhere = new StringBuilder();
        Field[] fields = c.getDeclaredFields();
        for (Field field : fields) {
            boolean b1 = field.isAnnotationPresent(MyColumn.class);
            if (!b1) {
                return "Not Exist Field!";
            }

            //4. Splicing field
            MyColumn myColumn = field.getAnnotation(MyColumn.class);
            String columnName = myColumn.value();
            sbField.append(columnName).append(",");

            //4.1 get the value of the field, get the get method first, and then get the value
            String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + 
                                   field.getName().substring(1);
            Method getMethod = c.getMethod(getMethodName);
            Object getValue = getMethod.invoke(user);

            //5. Conditions behind splicing where
            //int basic type judgment
            if (getValue == null || (getValue instanceof Integer) && (Integer) getValue == 0) {
                continue;
            }

            sbWhere.append(" and ").append(columnName);

            if (getValue instanceof String) {
                //in query
                if (((String) getValue).contains(",")) {
                    String[] strings = ((String) getValue).split(",");
                    sbWhere.append(" in(");
                    for (String str : strings) {
                        sbWhere.append("'").append(str).append("',");
                    }
                    //Delete last comma
                    sbWhere.deleteCharAt(sbWhere.length() - 1);
                    sbWhere.append(")");
                } else {
                    //General query
                    sbWhere.append("=").append("'").append(getValue).append("'");
                }
            } else if (getValue instanceof Integer) {
                sbWhere.append("=").append(getValue);
            }

        }

        //Splicing complete sql output
        String sql = String.format(SQL_MODEL, sbField.deleteCharAt(sbField.length() - 1), 
                                   tableName, sbWhere);
        return sql;
    }
}

In the above experiment for User, the field type is also relatively small. You can change the input parameter to Object or template, and only add = and in query conditions, JDBC will not write, mainly for the practice of annotation

 

The final output is: select id,user_name,nick_name,age,address,email from user_info where 1=1 and id=9527 and user_name='HaHaHa' and nick_name = 'Hua'an' and address = 'Xiasha' and email in('hello@163.com','hi@qq.com','biu@sina.com ')

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

Topics: SQL Java Database Mobile