案例:
1. 已知类Student拥有属性int id,String name,int age,String email,自定义注解解析模拟Hibernate的ORM,条件:
(1)给定Student属性name为xiaoming时,相应的查询语句转为select * from student where name=’xiaoming’
(2)给定Student属性name为xiaoming,age为2时,相应的查询语句转换为select * from student where name=’xiaoming’and age=2
(3)给定Student属性为name为xiaoming,email为123@qq.com,456@qq.com时,相应的查询语句转换为select * from student where name=’xiaoming’and email in (123@qq.com,456@qq.com)
ORM映射:指的就是数据库表与javaBean的映射,在数据库中的每一张表都javabean中都有唯一的bean与之对应。
数据库的字段 对应的是 实体bean中的属性
数据表的表名称 对应的是实体类bean的类名
持久层框架底层就是采用了注解和反射来完成表和实体类的映射!!!!
会根据实体类自动生成sql语句 不需要与数据库交互 提高了程序的执行效率
解题思路:创建两个注解对象,一个修饰类,一个修饰属性
修饰类的注解TableAnnotation 定义一个属性 属性名table = tb_student
修饰属性的注解ColmunAnnotation 定义一个属性 属性名 指定多个属性
实体类中有多少属性,在注解中定义一样的属性
Student类
package com.jy.anli;@Table("")public class Student {@Columnprivate int id;@Column(name = "xiaoming")private String name;@Column(age = 20)private int age;@Column(email = {"123@qq.com", "456@qq,com"})private String email;......get和set,constructor}
Table注解
@Target(ElementType.TYPE)@Retention(RetentionPolicy.RUNTIME)public @interface Table {//指定数据库表名String value();}
Column注解
@Target(ElementType.FIELD)@Retention(RetentionPolicy.RUNTIME)public @interface Column {int id() default 0;String name() default "";int age() default 0;String[] email()default "";}
工具类
/*** @author shizi 2022/1/24*/public class AnnotationUtil {private AnnotationUtil(){}//通过反射和注解解析ORM,从而获得sql语句public static String getSqlByOrm(Object object){//获取字节码对象Class objClass = object.getClass();//获取类上的注解Table table = (Table)objClass.getAnnotation(Table.class);//创建字符串对象StringBuilder stringBuilder = new StringBuilder();if(table != null){stringBuilder.append("select * from");stringBuilder.append(table.value()+" ");stringBuilder.append("where ");//获取属性Field[] declaredFields = objClass.getDeclaredFields();//遍历循环for (Field declaredField : declaredFields) {//获取属性上的注解Column annotation = declaredField.getAnnotation(Column.class);if(declaredField.getName().equals("name") && !annotation.name().equals("")){stringBuilder.append(declaredField.getName()+" = ");stringBuilder.append("\'"+annotation.name()+"\'");}if(declaredField.getName().equals("age") && annotation.age()!=0){stringBuilder.append(" and ");stringBuilder.append(declaredField.getName()+" = ");stringBuilder.append(annotation.age()+" ");}//用!annotation.email()[0].equals("") 判空是因为数组无法用equals方法比较,所以指定下标if(declaredField.getName().equals("email") && !annotation.email()[0].equals("")){stringBuilder.append(" and ");stringBuilder.append(declaredField.getName()+" in(");stringBuilder.append("\'"+annotation.email()[0]+"\'"+",");stringBuilder.append("\'"+annotation.email()[1]+"\'"+")");}}}return stringBuilder.toString();}}
Test测试
public class Test {public static void main(String[] args) {String sqlByOrm = AnnotationUtil.getSqlByOrm(new Student());System.out.println(sqlByOrm);}}
