案例:
    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类

    1. package com.jy.anli;
    2. @Table("")
    3. public class Student {
    4. @Column
    5. private int id;
    6. @Column(name = "xiaoming")
    7. private String name;
    8. @Column(age = 20)
    9. private int age;
    10. @Column(email = {"123@qq.com", "456@qq,com"})
    11. private String email;
    12. ......getsetconstructor
    13. }

    Table注解

    1. @Target(ElementType.TYPE)
    2. @Retention(RetentionPolicy.RUNTIME)
    3. public @interface Table {
    4. //指定数据库表名
    5. String value();
    6. }

    Column注解

    1. @Target(ElementType.FIELD)
    2. @Retention(RetentionPolicy.RUNTIME)
    3. public @interface Column {
    4. int id() default 0;
    5. String name() default "";
    6. int age() default 0;
    7. String[] email()default "";
    8. }

    工具类

    1. /**
    2. * @author shizi 2022/1/24
    3. */
    4. public class AnnotationUtil {
    5. private AnnotationUtil(){}
    6. //通过反射和注解解析ORM,从而获得sql语句
    7. public static String getSqlByOrm(Object object){
    8. //获取字节码对象
    9. Class objClass = object.getClass();
    10. //获取类上的注解
    11. Table table = (Table)objClass.getAnnotation(Table.class);
    12. //创建字符串对象
    13. StringBuilder stringBuilder = new StringBuilder();
    14. if(table != null){
    15. stringBuilder.append("select * from");
    16. stringBuilder.append(table.value()+" ");
    17. stringBuilder.append("where ");
    18. //获取属性
    19. Field[] declaredFields = objClass.getDeclaredFields();
    20. //遍历循环
    21. for (Field declaredField : declaredFields) {
    22. //获取属性上的注解
    23. Column annotation = declaredField.getAnnotation(Column.class);
    24. if(declaredField.getName().equals("name") && !annotation.name().equals("")){
    25. stringBuilder.append(declaredField.getName()+" = ");
    26. stringBuilder.append("\'"+annotation.name()+"\'");
    27. }
    28. if(declaredField.getName().equals("age") && annotation.age()!=0){
    29. stringBuilder.append(" and ");
    30. stringBuilder.append(declaredField.getName()+" = ");
    31. stringBuilder.append(annotation.age()+" ");
    32. }
    33. //用!annotation.email()[0].equals("") 判空是因为数组无法用equals方法比较,所以指定下标
    34. if(declaredField.getName().equals("email") && !annotation.email()[0].equals("")){
    35. stringBuilder.append(" and ");
    36. stringBuilder.append(declaredField.getName()+" in(");
    37. stringBuilder.append("\'"+annotation.email()[0]+"\'"+",");
    38. stringBuilder.append("\'"+annotation.email()[1]+"\'"+")");
    39. }
    40. }
    41. }
    42. return stringBuilder.toString();
    43. }
    44. }

    Test测试

    1. public class Test {
    2. public static void main(String[] args) {
    3. String sqlByOrm = AnnotationUtil.getSqlByOrm(new Student());
    4. System.out.println(sqlByOrm);
    5. }
    6. }