Dictionary query is realized through custom annotation, reflection and spring AOP

Time:2022-5-19

In a development process, I found that the work of the back-end process can be completed quickly, and the progress of the front-end almost determines the progress of development. Therefore, I think that when the back-end developers return the data, try to let the front-end get the data and use it directly, rather than let the front-end turn again. Dictionary data is a typical example. For example, the status of the contract is in signing, execution, execution completed and abolished. The positions of employees are ordinary employees, department managers, general managers, etc. These data are stored in the database as numbers, but they need to be converted into Chinese characters when displayed on the page.

It is also very simple for the back-end personnel to convert these data into numbers. For example, rewriting the setter method of the entity class can directly judge when setting the corresponding properties, and then convert it into the data we want. However, if the system is larger, it is not easy to manage. For example, if an employee’s position wants to be added, but there are multiple views using the employee’s position, then multiple classes need to be changed when changing the setter method. Moreover, it is difficult to deal with the situation that both the original data and the converted data are needed. I won’t repeat all the inconveniences. Here is a method to solve this problem by implementing dictionary query through custom annotation, reflection and spring AOP.

First look at the effect:

Student entity class

A @ dict annotation is added to the teacherid, sex and type attributes in the student entity class.

StudentController

The @ querydict annotation is added to getstudent and studentbyid.

The result obtained after requesting the getstudent method

As you can see, we didn’t rewrite any setter method, but we can see more sex in the final request result_ dictText,type_ dictText,teacherId_ Dictext these three data, and these three data look like the attributes in the original entity class. Let’s talk about how to achieve this effect.

First, let’s take a look at the custom annotation:

@Dict annotation

Dictext and dicttable have default values, which can be used without passing, but passing or not will make the function of diccode attribute different, which will be discussed later.

@Querydict annotation

This annotation has no attributes. It is only used as an identifier for dictionary query.

The next step is to implement it using spring AOP and Reflection:

The first step is to define the tangent point

The second annotation @ querydict is used to define the tangent point. When the annotation @ querydict is used, it will enter this aspect. You can see that the return value of the target method has been changed.

Here’s how to change it:

The result is divided into two categories for processing

There are only two ways to query the dictionary. One is to query the page by page, and the other is to query the specific data. If you use instanceof to judge whether it is an iPage type, you can judge whether it is a paging query (because the query is implemented through mybatis plus). If it is a paging query, you have to iterate, and then call eachfield to make the next judgment and change.

However, I need to insert a paragraph of my result class first:

Result return result class

Just look at its properties. Then there is the eachfield method

Eachfield method

In fact, this method redefines a JSON, adds the original result returned data directly, and then obtains each attribute of the returned data. If @ dict annotation is added to this attribute, translatedicvalue is used for dictionary translation (it can be realized by querying the database or by querying enumeration), Then add the translated data into the JSON defined above. In the above code, oconvertutils Getallfiles is to obtain all the attributes of the returned data. The specific implementation is realized through the getdeclaraedfields method. field. getName()+CommonConstant. DICT_ TEXT_ Suffix is to define a key name for the translated data, which is XXX seen in the previous test results_ dictText。

Translatedictvalue translation dictionary method

Dictservice is called here Querydict method:

Querydict method

It can be seen that the SQL invoked when dicttable and dicttext are empty strings and not empty strings are different. When dicttable and dicttext are not empty strings, it means to go to other basic tables for query.

For example, @ dict (dicttable = “teacher”, dictext = “teacher. Teacher_name”, diccode = “Id”) is added to the attribute of teacherid, which means to check the teacher in the teacher table_ Name field. The query condition is that the value of the teacherid attribute is equal to the ID in the teacher table.

If dicttext is an empty string, you need to look it up in a special dictionary table.

Finally, let’s look at SQL statements

SQL statement of dictionary query

In this way, the method of dictionary query through custom annotation, reflection and spring AOP is almost clear.