02_框架基础之反射

1 框架的概念

写好的程序的半成品:大师根据功能或者某层搭好的软件基础:
                程序员在框架的基础上进行开发
框架: 提高开发效率 降低开发难度    
常见的框架:
  hibernate:持久层(替代jdbc)
  mybatis:持久层(替代jdbc)
  springmvc:控制层(替代servlet)
  struts2:控制层(替代servlet)
  mybatisplus:持久层(替代jdbc)
  spring:中间层(整合其他层和技术)
  springsecurity:权限
  fastdfs:图片服务器
  oss:图片服务器
  sso:点单登录·

2 框架基础

框架底层的技术:
1 反射 reflect
2 注解 annotation
3 xml dom解析
4 代理 proxy
5 io
6 socket
7 序列化:ObjectStream

3 反射

反射:通过类的字节码文件 动态的创建对象和获取类的成员
参照:杀鸡取卵、守株待兔
反射相关的四个类:Class:类的字节码文件对象
               Constructor:类的构造方法对象
               Field:类的成员变量对象
               Method:类的普通方法对象

4 Class类

4.0 准备工作

package com.zhiyou100.demo012_reflect;

public class Student {
	private int sid;
	private String sname;
	private float score;
	private String sex;
	public int getSid() {
		return sid;
	}
	public void setSid(int sid) {
		this.sid = sid;
	}
	public String getSname() {
		return sname;
	}
	public void setSname(String sname) {
		this.sname = sname;
	}
	public float getScore() {
		return score;
	}
	public void setScore(float score) {
		this.score = score;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Student(int sid, String sname, float score, String sex) {
		System.out.println("构造方法:public Student(int sid, String sname, float score, String sex)");
		this.sid = sid;
		this.sname = sname;
		this.score = score;
		this.sex = sex;
	}
	public Student() {
		System.out.println("构造方法:public Student()");
	}
	public void hehe(){
		System.out.println("普通方法::public void hehe()");
	}
	public double haha(int a,float b){
		System.out.println("普通方法::public double haha(int a,float b)");
		return a+b;
	}
	private void hh(){
		System.out.println("普通方法::private void hh()");
	}
}

4.1 获取一个类的字节码文件对象的方式

Student student=new Student();
//获取Student类的Class对象的方式
//1:通过Obejct对象的getClasss
Class cla1=student.getClass();
System.out.println(cla1);
//2:通过Student类的class静态属性
Class cla2=Student.class;
System.out.println(cla2);
System.out.println(cla1==cla2);//true:::同一个类只有也给字节码文件对象
//3:通过Class类的静态forName方法
Class cla3=Class.forName("com.zhiyou100.demo012_reflect.Student");
System.out.println(cla3);

4.2 研究Class类中的方法

  /*
   * 类:提取数据作为变量 提取功能作为方法
   * Class类:对类的字节码文件对象的封装
   * 
   * Class类中常用的方法:
   *  1 获取类名:
   *     * String getName()  
   *     * String getSimpleName() 
   *      Package getPackage()   
   *  2 判断类型:
   *      boolean isArray() 
   *      boolean isInterface()  
   *      boolean isEnum()  
   *  3 获取Class对象
   *     * static Class<?> forName(String className) 
   *  4 获取类加载器
   *     * ClassLoader getClassLoader()  
   *  5 获取类的成员
   *      Constructor<?>[] getConstructors()  :获取所有public修饰的构造方法
   *     * Constructor<?>[] getDeclaredConstructors() :获取所有的构造方法
   *      Constructor<T> getConstructor(Class<?>... parameterTypes) :获取public修饰的指定参数的 某个构造方法   
   *     * Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes):获取指定参数的 某个构造方法    
   *      Method[] getMethods()  :获取所有的public修饰的普通方法
   *     * Method[] getDeclaredMethods()  :获取所有的普通方法
   *      Method getMethod(String name, Class<?>... parameterTypes) :获取某个public修饰的普通方法
   *     * Method getDeclaredMethod(String name, Class<?>... parameterTypes):获取某个普通方法
   *      Field[] getFields()  :获取所有public修饰的成员变量
   *     * Field[] getDeclaredFields()   :获取所有的成员变量
   *      Field getField(String name)   :获取指定变量名的public修饰的成员变量
   *     * Field getDeclaredField(String name)  :获取指定变量名的成员变量
   *  6 创建实例
   *     * T newInstance()   创建实例
   *      
   * */
  • 代码
//普通方法
//1 获取类名
System.out.println("获取类名(包名.类名):getName::"+cla1.getName());
System.out.println("获取类名:getSimpleName::"+cla1.getSimpleName());
//6 创建实例
Student s2=(Student)cla1.newInstance();
System.out.println(s2);
//5获取类的成员
System.out.println("获取所有的public修饰的构造方法对象::getConstructors::"+Arrays.toString(cla1.getConstructors()));
System.out.println("获取所有的构造方法对象::getDeclaredConstructors::"+Arrays.toString(cla1.getDeclaredConstructors()));
System.out.println("获取public修饰的无参数的构造方法::getConstructor::"+cla1.getConstructor(null));
System.out.println("获取public修饰的参数类型为double的构造方法::getConstructor::"+cla1.getConstructor(double.class));
System.out.println("获取任意修饰的参数类型为double的构造方法::getDeclaredConstructor::"+cla1.getDeclaredConstructor(int.class));

System.out.println("获取public修饰的某个成员变量:getField"+cla1.getField("a"));
System.out.println("获取任意修饰的某个成员变量:getDeclaredField"+cla1.getDeclaredField("c"));
System.out.println("获取public修饰的所有成员变量:getField"+Arrays.toString(cla1.getFields()));
System.out.println("获取任意修饰的所有成员变量:getDeclaredField"+Arrays.toString(cla1.getDeclaredFields()));

System.out.println("获取public修饰的某个普通方法:getMethod"+cla1.getMethod("haha", int.class,float.class));
System.out.println("获取任意修饰的某个普通方法:getDeclaredMethod"+cla1.getDeclaredMethod("hh"));
System.out.println("获取public修饰的所有普通方法:getMethods"+Arrays.toString(cla1.getMethods()));
System.out.println("获取任意修饰的所有普通方法:getDeclaredMethods"+Arrays.toString(cla1.getDeclaredMethods()));

5 Constructor类

 /*
		  * 构造器:Constructor
		  * 1: 获取当前构造方法的数据
		  *    String getName()
		  *    int getModifiers()  
		  *    Class<?>[] getParameterTypes()    
		  * 2: 创建对象
		  *     T newInstance(Object... initargs)   
		  * 3: 取消范围修饰符的检查
		  *     void setAccessible(boolean flag)
* */
	     Class cla1=Class.forName("com.zhiyou100.demo012_reflect.Student");
	     Constructor con1=cla1.getDeclaredConstructor(int.class,String.class,float.class,String.class);
	     System.out.println(con1);
	     System.out.println("getName:获取方法名:"+con1.getName());
	     System.out.println("getModifiers:获取修饰符:"+con1.getModifiers());
	     System.out.println("getParameterTypes:获取参数列表类型:"+Arrays.toString(con1.getParameterTypes()));
	     Student s1=(Student)con1.newInstance(1,"eheh",1.1f,"男");
	     System.out.println("s1="+s1);
	     
	     //获取私有的构造方法:private  Student(int sid) 
	     con1=cla1.getDeclaredConstructor(int.class);
	     System.out.println(con1);
	     con1.setAccessible(true);//取消范围修饰符检查
	     s1=(Student)con1.newInstance(1);//IllegalAccessException
	     System.out.println("s1="+s1);

6 Field类

/*字段:Filed
		 *1 获取字段的信息
		 *    String getName()  :获取属性名
		 *    Class<?> getType()  :获取属性的类型
		 *    int getModifiers()  :获取属性的修饰符
		 *2 设置和获取属性的值
		 *    Object get(Object obj) :获取参数对象的当前属性的值 
		 *    void set(Object obj, Object value) :设置参数对象obj的当前属性的值为value      
		 * 3 取消范围修饰符的检查
		 *     void setAccessible(boolean flag)
 * */
		Class cla1=Class.forName("com.zhiyou100.demo012_reflect.Student");
		//private String sex;
		Field f1=cla1.getDeclaredField("sex");
		Student s1=new Student(101, "韩梅梅", 11f, "女");
		f1.setAccessible(true);//暴力访问
		//设置s1对象的sex属性的值为 妖
		f1.set(s1, "妖");
		System.out.println("获取s1对象的sex属性的值:"+f1.get(s1));//IllegalAccessException:
		System.out.println(s1);
		
		System.out.println("获取属性名:"+f1.getName());
		System.out.println("获取属性类型:"+f1.getType());
		System.out.println("获取属性修饰符:"+f1.getModifiers());

7 Method类

/*普通方法:Method
		 *1 获取方法的信息
		 *  String getName()  :获取方法名
		 *  int getModifiers()  :获取方法修饰符
		 *  Class<?> getReturnType()  :获取方法的返回值类型
		 *  Class<?>[] getParameterTypes()  :获取方法的参数类型
		 *  Class<?>[] getExceptionTypes() :获取抛出的异常
		 *2 调用方法
		 *  Object invoke(Object obj, Object... args)     
		 *3 暴力访问
		 *  void setAccessible(boolean flag)  
		 *  
		 * 
 * */
		Class cla1=Class.forName("com.zhiyou100.demo012_reflect.Student");
		//private double haha(int a,float b)
		Method m1=cla1.getDeclaredMethod("haha", int.class,float.class);
		System.out.println("m1==="+m1);
		System.out.println("getName:获取方法名::"+m1.getName());
		System.out.println("getName:获取方法修饰符::"+m1.getModifiers());
		System.out.println("getName:获取方法返回值类型::"+m1.getReturnType());
		System.out.println("getName:获取方法参数列表::"+Arrays.toString(m1.getParameterTypes()));
		System.out.println("getName:获取方法抛出的异常类型::"+Arrays.toString(m1.getExceptionTypes()));
		
		Student s1=new Student(101, "韩梅梅", 11f, "女");
        //调用方法
		m1.setAccessible(true);//暴力访问
		Object result=m1.invoke(s1, 11,22.1f);//IllegalAccessException
		System.out.println("方法返回值值:"+result);

总结:

反射其实就是4个类+(4+1+2+1)个方法

8 反射练习1:

需求

写一个通用的dao实现 所有实体类对数据库的crud
:::dao就是就是java对象-数据库行  数据库行-java对象 的映射关系

大纲

//要求:类名 和 表名一直 只是首字母小写
//     Student类--student表
//     属性名和列名一致::
//     woDeMingZi属性---wo_de_ming_zi
//     所有属性都使用包装类类型
//     主键名都为id
public interface Demo05Mapper<E,ID_TYPE>{//E对象的类型 ID_TYPE主键的类型
	public int addOne(E e);//把对象的信息写到数据库中
	public int aupdateOneById(E e);//根据id修改数据库对应的行
	public int deleteOneById(ID_TYPE id,Class cla);//根据id删除数据库中对应的行
	public E getOneById(ID_TYPE id,Class cla);//根据id查询数据库中对应的行 读成java对象
	public List<E> getAll(Class cla);//获取所有行 读成java对象
}

数据库准备

CREATE DATABASE db_4 CHARSET='utf8';
USE db_4;
CREATE TABLE teacher(
   id INT PRIMARY KEY AUTO_INCREMENT,
   tming_zi VARCHAR(11),
   txing_bie CHAR(1),
   tfen_shu FLOAT(4,1),
   tdang_yuan_ma BOOL
);
INSERT INTO teacher VALUES(NULL,
	SUBSTRING(UUID(),1,10),
	IF(RAND()>0.5,'男','女'),
	TRUNCATE(RAND()*100,1),
	RAND()>0.5
);

实现类

package com.zhiyou100.demo012_reflect;

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
//注意:mysql数据库中 表明和列明是不区分大小写的
//要求:类名 和 表名一致::
//     属性名和列名一致::
//     woDeMingZi属性---wo_de_ming_zi列
//     XueSheng类------xue_sheng表
//     所有属性都使用包装类类型
//     主键名都为id
public class Demo05MapperImp<E,ID_TYPE> implements Demo05Mapper<E, ID_TYPE>{//E对象的类型 ID_TYPE主键的类型
  
	public int addOne(E e){
		//获取表明
		Class cla=e.getClass();
		String claName=cla.getSimpleName();
		//获取表明
		String tableName=getColumnNameByFieldName(claName);
		//获取所有属性
		Field[] fieldArr=cla.getDeclaredFields();
		//定义字符串记录sql模板
		StringBuffer stb=new StringBuffer("");
		stb.append("insert into ");
		stb.append(tableName+"(");
		for (Field field : fieldArr) {
			//获取字段名
			String fieldName=field.getName();
			//由字段名获取列明
			String columnName=getColumnNameByFieldName(fieldName);
			stb.append(columnName+",");
		}
		//最后一列的,更改为)
		stb.setCharAt(stb.length()-1, ')');
		stb.append(" values( ");
		for (int i = 0; i < fieldArr.length; i++) {
			stb.append("?,");
		}
		//最后一列的,更改为)
		stb.setCharAt(stb.length()-1, ')');
		System.out.println("slq:::"+stb.toString());
		Connection con=JdbcUtil.getCon();//获取连接
		PreparedStatement pre=null;
		int hang=0;
		try {
			pre=con.prepareStatement(stb.toString());
			//给占位符赋值
			for (int i = 0; i < fieldArr.length; i++) {
				//获取字段的值
				Field field=fieldArr[i];
				//暴力访问
				field.setAccessible(true);
				pre.setObject(i+1, field.get(e));
			}
			hang=pre.executeUpdate();
			
		} catch (Exception e2) {
			throw new RuntimeException(e2);
		}
		JdbcUtil.close(con, pre, null);
		return hang;
	}
	public int aupdateOneById(E e){
	//获取表明
			Class cla=e.getClass();
			String claName=cla.getSimpleName();
			//获取表明
			String tableName=getColumnNameByFieldName(claName);
			//获取所有属性
			Field[] fieldArr=cla.getDeclaredFields();
			//定义字符串记录sql模板:update 表名 set xxx=?,xxx=? where id=?
			StringBuffer stb=new StringBuffer("");
			stb.append("update  ");
			stb.append(tableName+" set ");
			for (Field field : fieldArr) {
				//获取字段名
				String fieldName=field.getName();
				if(fieldName.equals("id")){
					continue;
				}
				//由字段名获取列明
				String columnName=getColumnNameByFieldName(fieldName);
				stb.append(columnName+" = ? ,");
			}
			//最后一个,删除
			stb.deleteCharAt(stb.length()-1);
			stb.append(" where id=?");
			System.out.println("slq:::"+stb.toString());
			Connection con=JdbcUtil.getCon();//获取连接
			PreparedStatement pre=null;
			int hang=0;
			try {
				pre=con.prepareStatement(stb.toString());
				//给占位符赋值
				Object idValue=null;
				for (int i = 0,index=0; i < fieldArr.length; i++) {
					//获取字段的值
					Field field=fieldArr[i];
					//暴力访问
					field.setAccessible(true);
					if(field.getName().equals("id")){
						idValue=field.get(e);
						continue;
					}
					pre.setObject(index+1, field.get(e));
					index++;
				}
				//给最后一个占位符赋值
				pre.setObject(fieldArr.length, idValue);
				hang=pre.executeUpdate();
				
			} catch (Exception e2) {
				throw new RuntimeException(e2);
			}
			JdbcUtil.close(con, pre, null);
			return hang;
	}
	public int deleteOneById(ID_TYPE id,Class cla){
		String claName=cla.getSimpleName();
		//获取表明
		String tableName=getColumnNameByFieldName(claName);
		
		//定义字符串记录sql模板:delete from 表明 where id=?
		StringBuffer stb=new StringBuffer("delete from ");
		stb.append(tableName+" where id=?");
		System.out.println("slq:::"+stb.toString());
		Connection con=JdbcUtil.getCon();//获取连接
		PreparedStatement pre=null;
		int hang=0;
		try {
			pre=con.prepareStatement(stb.toString());
			//给最后一个占位符赋值
			pre.setObject(1, id);
			hang=pre.executeUpdate();
			
		} catch (Exception e2) {
			throw new RuntimeException(e2);
		}
		JdbcUtil.close(con, pre, null);
		return hang;
	}
	public E getOneById(ID_TYPE id,Class cla){
		//获取类名
		String claName=cla.getSimpleName();
		//获取表明
		String tableName=getColumnNameByFieldName(claName);
		//定义字符串记录sql模板:select * from 表名 where id=?
		StringBuffer stb=new StringBuffer("");
		stb.append("select * from ");
		stb.append(tableName+" where id=?");
		System.out.println("slq:::"+stb.toString());
		Connection con=JdbcUtil.getCon();//获取连接
		PreparedStatement pre=null;
		ResultSet set=null;
		//准备一个对象
		E obj=null;
		try {
			pre=con.prepareStatement(stb.toString());
			//给最占位符赋值
			pre.setObject(1, id);
			set=pre.executeQuery();
			//解析结果集
			if(set.next()){
				//创建对象
				obj=(E)cla.newInstance();
				//给对象的属性赋值:属性的值从结果集中解析 获取
				//获取所有属性
				Field[] fieldArr=cla.getDeclaredFields();
				for (Field field : fieldArr) {
					//暴力访问
					field.setAccessible(true);
					//获取其列名
					String fieldName=field.getName();
					String columnName=getColumnNameByFieldName(fieldName);
					field.set(obj, set.getObject(columnName));
				}
			}
			
		} catch (Exception e2) {
			throw new RuntimeException(e2);
		}
		JdbcUtil.close(con, pre, set);
		return obj;
	}
	public List<E> getAll(Class cla){
		//获取类名
		String claName=cla.getSimpleName();
		//获取表明
		String tableName=getColumnNameByFieldName(claName);
		//定义字符串记录sql模板:select * from 表名
		StringBuffer stb=new StringBuffer("");
		stb.append("select * from ");
		stb.append(tableName);
		System.out.println("slq:::"+stb.toString());
		Connection con=JdbcUtil.getCon();//获取连接
		PreparedStatement pre=null;
		ResultSet set=null;
		//准备一集合
		List<E> list=new ArrayList<E>();
		try {
			pre=con.prepareStatement(stb.toString());
			//给最占位符赋值
			set=pre.executeQuery();
			//解析结果集
			while(set.next()){
				//创建对象
				E obj=(E)cla.newInstance();
				//给对象的属性赋值:属性的值从结果集中解析 获取
				//获取所有属性
				Field[] fieldArr=cla.getDeclaredFields();
				for (Field field : fieldArr) {
					//暴力访问
					field.setAccessible(true);
					//获取其列名
					String fieldName=field.getName();
					String columnName=getColumnNameByFieldName(fieldName);
					field.set(obj, set.getObject(columnName));
				}
				list.add(obj);
			}
			
		} catch (Exception e2) {
			throw new RuntimeException(e2);
		}
		JdbcUtil.close(con, pre, set);
		return list;
	}
	//准备一个方法:woDeMingZi属性---wo_de_ming_zi
	private String getColumnNameByFieldName(String fieldName){
		String columnName="";
		for (int i = 0; i < fieldName.length(); i++) {
			char c=fieldName.charAt(i);
			if(i!=0&&Character.isUpperCase(c)){
				columnName+="_";
			}
			columnName+=c;
		}
		columnName=columnName.toLowerCase();
		return columnName;
	}
	public static void main(String[] args) {
		//System.out.println(getColumnNameByFieldName("woDeMingZi"));
		Demo05MapperImp<Teacher,Integer> demo05=new Demo05MapperImp<Teacher, Integer>();
		//System.out.println("添加:::"+demo05.addOne(new Teacher(2988, "张三丰", "男", 100f, false)));
		//System.out.println("修改:::"+demo05.aupdateOneById(new Teacher(1, "张三丰", "妖", 99f, false)));
		//System.out.println("删除:::"+demo05.deleteOneById(2, Teacher.class));
		System.out.println("获取一个:::"+demo05.getOneById(1,Teacher.class));
		System.out.println("获取所有:::"+demo05.getAll(Teacher.class));
	}
	
}

9 反射练习2:

通过反射写一个工具类 可以针对于所有类型的对象 保存为对应的xml
要求:主键名必须是id id为标签的唯一属性 其他属性都是子标签
     文件名就是类名
     标签名就是类名
     属性名就是子标签名
     跟标签统一为 root
     位置都当前包
package com.zhiyou100.demo012_reflect;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.annotation.Generated;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;

import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;

public class Demo06<E,ID_TYPE>{
    private static String path="src/com/zhiyou100/demo012_reflect/";
	public static void main(String[] args) throws Exception{
		Demo06<Teacher,Integer> d6=new Demo06<Teacher, Integer>();
		d6.addOne(new Teacher(111, "张1三1", "男", 211f, true));
		d6.addOne(new Teacher(121, "张2三1", "妖", 212f, true));
		d6.addOne(new Teacher(131, "张3三1", "女", 213f, false));
		
		//d6.updateOneById(new Teacher(13, "张33", "圣", 333f, false));
		
		//d6.deleteOneById(12, Teacher.class);
		System.out.println("获取一个::"+d6.getOneById(11, Teacher.class));
		System.out.println("获取所有::"+d6.getAll(Teacher.class));
	}
	public int addOne(E e)throws Exception{
		//获取类名
		Class cla=e.getClass();
		String className=cla.getSimpleName();
		//1 读取xml文件为document对象
		Document doc=readXml2Doc(className);
		//2 获取跟标签root
		Element root=(Element)doc.getElementsByTagName("root").item(0);
		//3 在跟标签下添加一个 类名同名的子标签
		Element classEle=doc.createElement(className);
		//获取所有字段
		Field[] fieldArr=cla.getDeclaredFields();
		for (Field field : fieldArr) {
			//获取字段名
			String fieldName=field.getName();
			//获取字段值
			field.setAccessible(true);
			Object fieldValue = field.get(e);
			if(fieldName.equals("id")){
				//设置为标签的属性
				classEle.setAttribute("id", fieldValue+"");
				continue;
			}
			//设置为子标签
			Element fieldEle=doc.createElement(fieldName);
			fieldEle.setTextContent(fieldValue+"");//设置子标签的文本内容
			//添加到父标签下
			classEle.appendChild(fieldEle);
		}
		//添加到父标签下
		root.appendChild(classEle);
		//把内存中documnet对象的信息刷新到xml中
		writeDoc2Xml(doc, className);
		return 1;
	}
	public int updateOneById(E e)throws Exception{
		//获取类名
		Class cla=e.getClass();
		String className=cla.getSimpleName();
		//获取参数对象的id属性值
		Field idField=cla.getDeclaredField("id");
		idField.setAccessible(true);
		Object idValue=idField.get(e);
		//1 读取xml文件为document对象
		Document doc=readXml2Doc(className);
		//2 获取跟标签root
		Element root=(Element)doc.getElementsByTagName("root").item(0);
		//3 获取跟标签下的所有类标签
		NodeList list=root.getElementsByTagName(className);
		for (int i = 0; i < list.getLength(); i++) {
			Element classEle=(Element)list.item(i);
			//获取标签的id属性的值
			String idAttrValue=classEle.getAttribute("id");
			if(idAttrValue.equals(idValue+"")){
				//更改当前标签的子标签的文本内容 和 参数对象的属性值一致
				Field[] fieldArr=cla.getDeclaredFields();
				for (Field field : fieldArr) {
					//获取属性名
					String fieldName=field.getName();
					if(fieldName.equals("id")){
						continue;
					}
					//获取属性值
					field.setAccessible(true);
					Object fieldValue=field.get(e);
					//获取对应的子标签
					Element ziEle=(Element)classEle.getElementsByTagName(fieldName).item(0);
					ziEle.setTextContent(fieldValue+"");
				}
				break;
			}
		}
		//把内存中documnet对象的信息刷新到xml中
		writeDoc2Xml(doc, className);
		return 1;
	}
	public int deleteOneById(ID_TYPE id,Class cla){
		   //获取类名
			String className=cla.getSimpleName();
			//1 读取xml文件为document对象
			Document doc=readXml2Doc(className);
			//2 获取跟标签root
			Element root=(Element)doc.getElementsByTagName("root").item(0);
			//3 获取跟标签下的所有类标签
			NodeList list=root.getElementsByTagName(className);
			for (int i = 0; i < list.getLength(); i++) {
				Element classEle=(Element)list.item(i);
				//获取标签的id属性的值
				String idAttrValue=classEle.getAttribute("id");
				if(idAttrValue.equals(id+"")){
					//删除当前子标签
					root.removeChild(classEle);
					break;
				}
			}
			//把内存中documnet对象的信息刷新到xml中
			writeDoc2Xml(doc, className);
			return 1;
	}
	public E getOneById(ID_TYPE id,Class cla)throws Exception{
		E e=null;
	   //获取类名
		String className=cla.getSimpleName();
		//1 读取xml文件为document对象
		Document doc=readXml2Doc(className);
		//2 获取跟标签root
		Element root=(Element)doc.getElementsByTagName("root").item(0);
		//3 获取跟标签下的所有类标签
		NodeList list=root.getElementsByTagName(className);
		for (int i = 0; i < list.getLength(); i++) {
			Element classEle=(Element)list.item(i);
			//获取标签的id属性的值
			String idAttrValue=classEle.getAttribute("id");
			if(idAttrValue.equals(id+"")){
				//把当前标签的信息 读成一个对象
				e=(E)cla.newInstance();
				//给对象的属性赋值
				Field[] fieldArr=cla.getDeclaredFields();
				for (Field field : fieldArr) {
					field.setAccessible(true);//暴力访问
					String fieldName=field.getName();//获取属性名
					//给id赋值
					if(fieldName.equals("id")){
						field.set(e, id);
						continue;
					}
					//给其他属性赋值 子标签的文本内容
					Element fieldEle=(Element)classEle.getElementsByTagName(fieldName).item(0);
					String fieldvalue=fieldEle.getTextContent();
					//把标签的值 赋值给e的当前属性
					field.set(e, changeType(fieldvalue, field.getType()));
				}
				break;
			}
		}
		return e;
	}
	public List<E> getAll(Class cla)throws Exception{
		List<E> listObj=new ArrayList<E>();
	   //获取类名
		String className=cla.getSimpleName();
		//1 读取xml文件为document对象
		Document doc=readXml2Doc(className);
		//2 获取跟标签root
		Element root=(Element)doc.getElementsByTagName("root").item(0);
		//3 获取跟标签下的所有类标签
		NodeList list=root.getElementsByTagName(className);
		for (int i = 0; i < list.getLength(); i++) {
			Element classEle=(Element)list.item(i);
			//获取标签的id属性的值
			String idAttrValue=classEle.getAttribute("id");
			//把当前标签的信息 读成一个对象
			E e=(E)cla.newInstance();
			//给对象的属性赋值
			Field[] fieldArr=cla.getDeclaredFields();
			for (Field field : fieldArr) {
				field.setAccessible(true);//暴力访问
				String fieldName=field.getName();//获取属性名
				//给id赋值
				if(fieldName.equals("id")){
					field.set(e, changeType(idAttrValue, field.getType()));
					continue;
				}
				//给其他属性赋值 子标签的文本内容
				Element fieldEle=(Element)classEle.getElementsByTagName(fieldName).item(0);
				String fieldvalue=fieldEle.getTextContent();
				//把标签的值 赋值给e的当前属性
				field.set(e, changeType(fieldvalue, field.getType()));
			}
			listObj.add(e);
		}
		return listObj;
	}
	//写一个方法:把参数字符串的值 转化为指定的类型
	private static Object changeType(String value,Class type)throws Exception{
		if(type==byte.class || type==Byte.class){
			return Byte.parseByte(value);
		}
		if(type==short.class || type==Short.class){
			return Short.parseShort(value);
		}
		if(type==int.class || type==Integer.class){
			return Integer.parseInt(value);
		}
		if(type==char.class || type==Character.class){
			return value.indexOf(0);
		}
		if(type==long.class || type==Long.class){
			return Long.parseLong(value);
		}
		if(type==float.class || type==Float.class){
			return Float.parseFloat(value);
		}
		if(type==double.class || type==Double.class){
			return Double.parseDouble(value);
		}
		if(type==boolean.class || type==Boolean.class){
			return Boolean.parseBoolean(value);
		}
		if(type==Date.class){
			return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(value);
		}
		return value;
	}
	//1 读取xml文件为document对象
	public static Document  readXml2Doc(String className){
		File file=new File(path+className+".xml");
		try {
			if(!file.exists()) {
				//创建空的文件
				BufferedWriter bout=new BufferedWriter(new FileWriter(file));
				bout.write("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
				bout.newLine();
				bout.flush();
				bout.write("<root> </root>");
				bout.flush();
				bout.close();
			}
			return DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(file);
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	//2 刷新doc道xml中
	public static void writeDoc2Xml(Document doc,String className) {
		try {
			Transformer tf=TransformerFactory.newInstance().newTransformer();
			tf.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
			tf.setOutputProperty(OutputKeys.INDENT, "yes");
			File file=new File(path+className+".xml");
			tf.transform(new DOMSource(doc), new StreamResult(file));
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值