注解和反射实现dao层增删改查

    技术2023-09-16  108

    注解和反射写dao

    1. 注解的使用2. 使用注解体现映射关系

    针对上一篇文章,使用xml映射文件和反射实现dao,提出了扩展功能,利用注解来体现实体类和表的映射关系本文是上一篇文章的扩展使用反射和xml实现dao

    1. 注解的使用

    什么是注解? @Override public String toString() { return super.toString(); } @Override 就是一个注解,表示此方法是重写了父类的方法,此外还有许多Java里面的内置注解元注解(Retention, ElementType,Documented,Inherited)常用的两个元注解 (Retention, ElementType) //定义注解在代码中的保留策略 @Retention(RetentionPolicy.RUNTIME) //RetentionPolicy.RUNTIME 当前注解存在于源代码和编译后的class文件中,并加载到jvm中,可以在运行时获取 //RetentionPolicy.CLASS 当前注解存在于源代码和编译后的class文件中,但不会加载到jvm虚拟机 //RetentionPolicy.SOURCE 当前注解只存在于源代码中,不会编译到class文件中,也不会加载到jvm虚拟机 @Target(ElementType.TYPE) //指定当前注解能够用在什么地方 //ElementType.ANNOTATION_TYPE 当前注解可以使用在其他注解上 //ElementType.CONSTRUCTOR 当前注解可以用在构造函数上 //ElementType.FIELD 当前注解可以用在全局变量上 //ElementType.LOCAL_VARIABLE 当前注解可以用在局部变量上 //ElementType.METHOD 当前注解可以用在方法上 //ElementType.PACKAGE 当前注解可以用在包上 //ElementType.PARAMETER 当前注解可以用在参数上 //ElementType.TYPE 当前注解可以用在类型上 自定义注解 package com.lovely.test; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) @Target({ElementType.FIELD, ElementType.TYPE}) // 此注解只可用于属性 类型(接口,类...) public @interface MyAnnotation { // 默认值 // String name() default "default value: 123"; String name(); }

    2. 使用注解体现映射关系

    表注解,实体主键属性注解,实体类其它属性注解 package com.lovely.base; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Retention(RetentionPolicy.RUNTIME) // 运行时jvm可取到值 @Target(ElementType.TYPE) // 用来描述类 public @interface Table { String name(); // 定义属性 } package com.lovely.base; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) // 用来描述属性的注解 public @interface Id { String idName(); String idColumn(); String seqName(); } package com.lovely.base; @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) public @interface Column { String columnName(); } 以实体类goods为例 package com.lovely.entity; import java.sql.Date; import com.lovely.base.Column; import com.lovely.base.Id; import com.lovely.base.Table; /** * * @author echo lovely * * 注解的缺点 修改代码 要改变对应的列名 * */ @Table(name="goods_info") // 表的信息可以反射得到 public class Goods { @Id(idName="gid", idColumn="goods_id", seqName="goods_seq") private Integer gid; @Column(columnName="goods_name") private String gname; @Column(columnName="goods_price") private Double gprice; @Column(columnName="goods_date") private Date gdate; @Column(columnName="goods_factory") private String gfactory; // 为减少代码/我去掉了set/get/构造 BaseDao里面增加了, 注解加载映射数据 public static HashMap<String, MapperData> map = new HashMap<String, MapperData>(); static { // 利用注解解析 实体类和表的映射关系 try { // 通过BaseDao 类的信息 拿到entity里面的所有类 Class<?> baseDaoClass = Class.forName("com.lovely.dao.BaseDao"); String filePath = baseDaoClass.getResource("/com/lovely/entity/").getFile(); // System.out.println(filePath); File dir = new File(filePath); // 拿到所有类文件 File[] files = dir.listFiles(); for (File file : files) { // 类的全路径 String className = "com.lovely.entity." + file.getName().substring(0, file.getName().indexOf(".")); Class<?> entityClass = Class.forName(className); // 注解类型 Table table = entityClass.getAnnotation(Table.class); // 实体类有注解 就可配置映射关系 if (table != null) { MapperData mapperData = new MapperData(); mapperData.setClassName(className); // 设置表名 mapperData.setTableName(table.name()); Field[] fields = entityClass.getDeclaredFields(); for (int i = 0; i < fields.length; i++) { // id的注解 Id id = fields[i].getAnnotation(Id.class); // System.out.println(id); if (id != null) { MapperId mapperId = new MapperId(); mapperId.setIdName(id.idName()); mapperId.setIdColumn(id.idColumn()); mapperId.setSeqName(id.seqName()); // 设置 主键映射关系到映射类 mapperData.setMapperId(mapperId); } // 得到每个列的注解 Column column = fields[i].getAnnotation(Column.class); if (column != null) { mapperData.getProperties().put(fields[i].getName(), column.columnName()); } } map.put(className, mapperData); } } } catch (Exception e) { e.printStackTrace(); } } // 有了注解加载映射数据,就不要添加xml映射数据了。
    Processed: 0.011, SQL: 9