案例:
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 {
@Column
private 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);
}
}