注解实践
粗略的做一个简单实践,做一个ORM小方案,通过注解来实现
- 一张user表信息,字段: id、用户名、昵称、年龄、性别、地址、邮箱、手机号
- 简单的对每个字段或组合条件进行检索,打印SQL方式来显示结果
对数据执行检索,就要考虑怎么和数据库进行映射,数据对应有表名,字段名,人为定义的user也最相似于数据库表,比如JPA或其他,在user对象上可以加@Table、@Entry、@Column等注解标识,以对应数据库的表信息
下面创建注解,应用在类上,并且可以指定表名,只有一个值,如下:
import java.lang.annotation.*;@Target({ElementType.TYPE})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface MyTable { String value();}
再来定义一个@MyColumn注解,用在字段上,也需要一个值,如下:
import java.lang.annotation.*;@Target({ElementType.FIELD})@Retention(RetentionPolicy.RUNTIME)@Inherited@Documentedpublic @interface MyColumn { String value();}
在实体对象加上注解
@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;}
基本对象有了,那么接下来,需要创建SQL,定义一个query方法,下面粗略的实现,返回字符串即可
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("华安"); user.setAddress("下沙"); 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. 获取class试验,直接获取User对象,也可以Class.forName()方式 Class c = user.getClass(); //2. 获取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. 获取所有字段 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. 拼接字段 MyColumn myColumn = field.getAnnotation(MyColumn.class); String columnName = myColumn.value(); sbField.append(columnName).append(","); //4.1 获取字段的值,先获取get方法,再获取值 String getMethodName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1); Method getMethod = c.getMethod(getMethodName); Object getValue = getMethod.invoke(user); //5. 拼接where后面的条件 //int基本类型判断 if (getValue == null || (getValue instanceof Integer) && (Integer) getValue == 0) { continue; } sbWhere.append(" and ").append(columnName); if (getValue instanceof String) { //in 查询 if (((String) getValue).contains(",")) { String[] strings = ((String) getValue).split(","); sbWhere.append(" in("); for (String str : strings) { sbWhere.append("'").append(str).append("',"); } //删除最后一个逗号 sbWhere.deleteCharAt(sbWhere.length() - 1); sbWhere.append(")"); } else { //普通查询 sbWhere.append("=").append("'").append(getValue).append("'"); } } else if (getValue instanceof Integer) { sbWhere.append("=").append(getValue); } } //拼接完整sql输出 String sql = String.format(SQL_MODEL, sbField.deleteCharAt(sbField.length() - 1), tableName, sbWhere); return sql; }}
以上针对User做一个试验,字段类型也比较少,可以将入参改成Object或者范型,条件也只加了=与in查询,JDBC就不写了,主要对注解的实践
最后输出: 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='华安' and address='下沙' and email in('hello@163.com','hi@qq.com','biu@sina.com')
总结: 看到一个注解,现在就可以认识注解,知道注解的作用域,应用的场景范围,最后其功能所在,如果在开发中,能实际简化程序,那就再好不过的了
-------------------------------------------------------------------