1 为什么需要反射?(reflect)
Person p = new Student();
p在编译时的类型是person,但是在运行时是student。
为了让程序在运行时发现对象和类的真实信息,有两种做法:
1,假设我们知道类的具体信息,可以通过instanceof 运算符进行判断。
2,在编译的时候不知道对象和类的信息,可以通过反射获取。
三种获取class对象的方法。
//获取Class对象第一种class.forName /*try { Class clazz1 = Class.forName("com.aaa.entity.Person"); } catch (ClassNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); }*/ //获取Class对象第二种.class Class clazz2 = Person.class; //获取Class对象第三种getClass() /* Person p = new Person(); Class class3 = p.getClass();*/
使用反射获取构造器
/* Constructor[] constructors = clazz2.getConstructors(); System.out.println(constructors.length);*/ /* Constructor constructor = clazz2.getConstructor(String.class); System.out.println(constructor);*/
使用反射获取公共方法,注意不包括构造方法,但是包括Object中的方法
Method[] methods = clazz2.getMethods(); System.out.println(methods.length); for (Method method : methods) { System.out.println(method.getName()); }
使用反射获取所有包括私有方法,注意不包括构造方法,但是不包括Object中的(继承的)方法
/*Method[] methods2 = clazz2.getDeclaredMethods(); System.out.println(methods2.length); for (Method method : methods2) { System.out.println(method.getName());
使用反射获取属性,getFields只能获取公共属性
Field[] fields = clazz2.getFields(); System.out.println(fields.length);
如果想获取所有的,使用getDeclaredFields()
Field[] fields = clazz2.getDeclaredFields(); System.out.println(fields.length);
2 自建orm框架
第一步:创建注解(实体类标识注解MyEntity,主键标识注解MyId,列名标识注解 MyColumn)
package com.fyd.ann; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Fyd * @description 实体类标识注解 * @company FYD * 2017-12-22上午10:44:12 */ @Target(ElementType.TYPE)//修饰类 @Retention(RetentionPolicy.RUNTIME) public @interface MyEntity { String value(); } package com.fyd.ann; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Fyd * @description 主键标识注解 * @company FYD * 2017-12-22上午10:45:54 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MyId { String value(); } package com.fyd.ann; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; /** * @author Fyd * @description 列名标识注解 * @company FYD * 2017-12-22上午10:45:54 */ @Target(ElementType.FIELD) @Retention(RetentionPolicy.RUNTIME) public @interface MyColumn { String value(); }
第二步,创建实体类,并加上自定义注解
package com.fyd.entity; import com.fyd.ann.MyColumn; import com.fyd.ann.MyEntity; import com.fyd.ann.MyId; /** * @author Fyd * @description 部门表 * @company FYD * 2017-12-22上午10:50:17 */ @MyEntity("dept") public class Dept { @MyId("deptno") private Integer dpetno; @MyColumn("dname") private String dname; @MyColumn("loc") private String loc; public Integer getDpetno() { return dpetno; } public void setDpetno(Integer dpetno) { this.dpetno = dpetno; } public String getDname() { return dname; } public void setDname(String dname) { this.dname = dname; } public String getLoc() { return loc; } public void setLoc(String loc) { this.loc = loc; } }
第三步,创建通用dao层,接口(GenerricDao)和实现类(GenerricDaoImpl)
package com.fyd.dao; /** * @author Fyd * @description dao层,接口 * @company FYD * 2017-12-22上午10:54:05 */ public interface GenerricDao<T> { void save(T obj) throws Exception; }
package com.fyd.dao; import java.beans.IntrospectionException; import java.beans.PropertyDescriptor; import java.lang.annotation.Annotation; import java.lang.reflect.Field; import java.sql.Connection; import java.sql.PreparedStatement; import java.util.ArrayList; import java.util.List; import com.fyd.ann.MyColumn; import com.fyd.ann.MyEntity; import com.fyd.ann.MyId; import com.fyd.util.SqlConnectFactory; /** * @author Fyd * @description 通用dao实现类 * @company FYD * 2017-12-22上午10:56:14 */ public class GenericDaoImpl<T> implements GenerricDao<T> { @Override public void save(T obj) throws Exception { //获取表名 Class clazz = obj.getClass(); MyEntity annotation = (MyEntity) clazz.getAnnotation(MyEntity.class); String tableName = annotation.value(); List<Object> fieldValues= new ArrayList<Object>();//封装所有的属性值 StringBuilder fieldNames= new StringBuilder();//封装列名 //获取列名 Field[] fields = clazz.getDeclaredFields();//获取所有的属性 for (Field field : fields) { //PropertyDescriptor 描述 Java Bean 通过一对存储器方法导出的一个属性。 PropertyDescriptor pd = new PropertyDescriptor(field.getName(),clazz); //判断主键 if(field.isAnnotationPresent(MyId.class)){ fieldNames.append(field.getAnnotation(MyId.class).value()).append(","); fieldValues.add("'"+pd.getReadMethod().invoke(obj)+"'"); }else { fieldNames.append(field.getAnnotation(MyColumn.class).value()).append(","); fieldValues.add("'"+pd.getReadMethod().invoke(obj)+"'"); } } //截取最后一个逗号 fieldNames.deleteCharAt(fieldNames.length()-1); StringBuilder sql = new StringBuilder(); sql.append("insert into ").append(tableName).append("(").append(fieldNames).append(") values(").append(fieldValues).append(")"); //执行sql System.out.println(sql.toString()); String replace = sql.toString().replace("[", "").replace("]", ""); System.out.println(replace); Connection connection = SqlConnectFactory.getConnection(); PreparedStatement ps = connection.prepareStatement(replace); ps.execute(); SqlConnectFactory.closeConnection(connection, ps, null); } }
测试
Dept dept = new Dept(); dept.setDpetno(91); dept.setDname("ddd"); dept.setLoc("fdsaf"); GenerricDao<Dept> dao = new GenericDaoImpl<Dept> (); dao.save(dept);
版权付亚东笔记博客所有,禁止转载!!付亚东Java笔记博客