JDBC连接数据库反射实现O/R映射(2)

测试preparedStatement   
 public void testPreparedStatement(){
    	Connection connection=null;
    	PreparedStatement preparedStatement=null;
    	try{
    		connection =JDBCTools.getConnection();
    		String sql="insert into customers(name,email,birth) "+
    		"values(?,?,?)";
    		preparedStatement=connection.prepareStatement(sql);
    		preparedStatement.setString(1, "ATGUIGU");
    		preparedStatement.setString(2, "simleint@163.com");
    		preparedStatement.setDate(3, new Date(new java.util.Date().getTime()));
    		preparedStatement.executeUpdate();
    	}catch(Exception e){
    		e.printStackTrace();
    	}finally{
    		JDBCTools.release(null, preparedStatement, connection);
    	}
    }
测试结果集元数据: 利用SQL进行查询,得到结果集。
利用反射创建实体对象,获取结果集的列的别名。
在获取结果集的每一列的值,结合3得到一个Map,键的别名,值:列的值。</span>
再利用反射为2的对应的属性赋值:属性为Map的键,值为Map的值。</span>
  public void testResultSetMetaData(){
		Customer customer=null;
		Connection conn=null;
		PreparedStatement preparedStatement=null;
		ResultSet rs=null;
		try{
			String sql="select ID id,NAME name,EMAIL email,BIRTH birth from customers";
			conn=JDBCTools.getConnection();
			preparedStatement=conn.prepareStatement(sql);
//1得到rs
			rs=preparedStatement.executeQuery();
			
			Map<String,Object>values=
					new HashMap<String,Object>();
			//2得到结果集ResultSetMetaData对象。
			ResultSetMetaData rsmd=rs.getMetaData();
			while(rs.next()){
			for(int i=0;i<rsmd.getColumnCount();i++){
				String columnLabel=rsmd.getColumnLabel(i+1);
				Object columnValue=rs.getObject(columnLabel);
				
				values.put(columnLabel,columnValue);
			}
		}
			System.out.println(values);
			Class clazz=Customer.class;
			Object object=clazz.newInstance();
			for(Map.Entry<String, Object>entry:values.entrySet()){
				String fieldName=entry.getKey();
				Object fieldValue=entry.getValue();
				System.out.println(fieldName+" :"+fieldValue);
				ReflectionUtils.setFieldValue(object,fieldName,fieldValue);
			}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCTools.release(rs,preparedStatement,conn);
		}
	
  }

抽取出泛型方法:

    public void testGet(){
    	String sql="select ID id,NAME name,EMAIL email,BIRTH birth "+"From customers";
    	Customer customer=get(Customer.class,sql);
    	System.out.println(customer);
    	
    }
    public <T> T get(Class<T> clazz,String sql,Object...args){
         T entity=null;
		Connection conn=null;
		PreparedStatement preparedStatement=null;
		ResultSet rs=null;
		try{
			conn=JDBCTools.getConnection();
			preparedStatement=conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++)
			{
				preparedStatement.setObject(i+1, args[i]);
			}
             //1得到rs
			rs=preparedStatement.executeQuery();
			//2得到结果集ResultSetMetaData对象。
			ResultSetMetaData rsmd=rs.getMetaData();
			//3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
			Map<String,Object>values=
					new HashMap<String,Object>();
            //处理结果集。
			while(rs.next()){
			for(int i=0;i<rsmd.getColumnCount();i++){
				String columnLabel=rsmd.getColumnLabel(i+1);
				Object columnValue=rs.getObject(columnLabel);
				
				values.put(columnLabel,columnValue);
			}
		}
		//5若Map不为空利用反射创建clazz对应的对象。
			if(values.size()>0){
			entity=clazz.newInstance();
			for(Map.Entry<String, Object>entry:values.entrySet()){
				String fieldName=entry.getKey();
				Object fieldValue=entry.getValue();
				ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
			}
		}
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCTools.release(rs,preparedStatement,conn);
		}
	return entity;
  }
其中JDBCTools.java为:

/*
 * 操作JDBC的工具类,其中封装了一些工具方法
 * 通过读取配置文件从数据库服务器获取一个连接*/
public class JDBCTools {
	public static Connection getConnection() throws IOException, ClassNotFoundException, SQLException{
		//1.准备连接数据库的4个字符串。
		  //1)z创建jdbc.properties对象。
		Properties properties=new Properties();
		  //2)加载对应的输入流。
		InputStream in=JDBCTools.class.getClassLoader().getResourceAsStream("jdbc.properties");
		//3)加载2)对应的输入流 
		  properties.load(in);
		//4)具体决定user,password等4个字符串。
		  String user=properties.getProperty("user");
		  String password=properties.getProperty("password");
		  String driver=properties.getProperty("driverClass");
		  String jdbcUrl=properties.getProperty("jdbcUrl");
		//2.加载数据库驱动(对应的Driver实现类中有注册驱动的静态代码块)
		  Class.forName(driver);
		//3.通过DriverManager的getConnection()方法获取数据库连接。
		  return DriverManager.getConnection(jdbcUrl,user,password);
	}
	/*
	 *关闭Statement,Connection */
	public static void  release(ResultSet rs,Statement statement,Connection conn){
		if(rs!=null){
			try {
				rs.close();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	    if(statement!=null){
	    	  try{
	    		  statement.close();
	    	  }catch(Exception e2){
	    	  e2.printStackTrace();
	        }
	      }
	      if(conn!=null){
	    	  try{
	    		  conn.close();
	    	  }catch(Exception e2){
	    	  e2.printStackTrace();
	      }
	    }
	}

	public static void update(String sql) throws SQLException{		
		Connection conn=null;
		Statement statement=null;
		try{
		conn=JDBCTools.getConnection();
		statement=conn.createStatement();
		statement.executeUpdate(sql);
		}catch(Exception e){
			e.printStackTrace();
		}finally{
	    JDBCTools.release(null,statement, conn);
	}
   }
	public static void update(String sql,Object...args) throws IOException, ClassNotFoundException{
		Connection conn=null;
		  PreparedStatement pstmt=null;
		  try{
			  conn=JDBCTools.getConnection();
			   pstmt=conn.prepareStatement(sql);
			  for(int i=0;i<args.length;i++){
				  pstmt.setObject(i+1,args[i]);
			  }
			  pstmt.executeUpdate();
		  }catch(SQLException e){
			  System.out.println("使用预编译语句更新数据操作发生异常");
		  }
	}
	/*
	 * 1ResultSetMetaData是描述ResultSet的元数据的对象,即从中可以获取到结果集中有多少列,列名是多少。。。
	 * 2得到ResultSetNataData对象:调用ResultSet的getMetaData()方法
	 * ResultSetMetaData有哪些方法。
	 * int getColumnCount():SQL语句中包含哪些列。
	 * String getColumnLable(int column)获取指定的列的别名,其中索引从1开始。*/
 

	
	   public <T> T get(Class<T> clazz,String sql,Object...args){
			/*
			 * 1先利用SQL进行查询得到结果集
			 * 2利用反射创建实体类的对象
			 * 3获取结果集的列的别名:idcard。。。
			 * 4获取结果集的每一列的值,结合3得到一个Map。键:列的别名,值:列的值
			 * 5再利用反射为2的对应的属性赋值。*/
	         T entity=null;
			Connection conn=null;
			PreparedStatement preparedStatement=null;
			ResultSet rs=null;
			try{
				conn=JDBCTools.getConnection();
				preparedStatement=conn.prepareStatement(sql);
				for(int i=0;i<args.length;i++)
				{
					preparedStatement.setObject(i+1, args[i]);
				}
	             //1得到rs
				rs=preparedStatement.executeQuery();
				//2得到结果集ResultSetMetaData对象。
				ResultSetMetaData rsmd=rs.getMetaData();
				//3创建一个Map<String,Object>对象,键:SQL查询的别名。值:列的值
				Map<String,Object>values=
						new HashMap<String,Object>();
	            //处理结果集。
				while(rs.next()){
				for(int i=0;i<rsmd.getColumnCount();i++){
					String columnLabel=rsmd.getColumnLabel(i+1);
					Object columnValue=rs.getObject(columnLabel);
					
					values.put(columnLabel,columnValue);
				}
			}
			//5若Map不为空利用反射创建clazz对应的对象。
				if(values.size()>0){
				entity=clazz.newInstance();
				for(Map.Entry<String, Object>entry:values.entrySet()){
					String fieldName=entry.getKey();
					Object fieldValue=entry.getValue();
					ReflectionUtils.setFieldValue(entity,fieldName,fieldValue);
				}
			}
			}catch(Exception e){
				e.printStackTrace();
			}finally{
				JDBCTools.release(rs,preparedStatement,conn);
			}
		return entity;
	  }	
	
	
	public Customer getCustomer(String sql,Object...args){
		Customer customer=null;
		Connection conn=null;
		PreparedStatement preparedStatement=null;
		ResultSet rs=null;
		try{
			conn=JDBCTools.getConnection();
			preparedStatement=conn.prepareStatement(sql);
			for(int i=0;i<args.length;i++)
			{
				preparedStatement.setObject(i+1, args[i]);
			}
			rs=preparedStatement.executeQuery();
			
			if(rs.next()){
				customer=new Customer();
				customer.setId(rs.getInt(1));
				customer.setName(rs.getString(2));
				customer.setEmail(rs.getString(3));
				customer.setBirth(rs.getDate(4));
			}
			
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			JDBCTools.release(rs,preparedStatement,conn);
		}
		return customer;
	} 
	
	
}
ReflectionUtils.java为:

package com.atguigu.jdbc;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

/**
 * 反射的 Utils 函数集合
 * 提供访问私有变量, 获取泛型类型 Class, 提取集合中元素属性等 Utils 函数
 * @author Administrator
 *
 */
public class ReflectionUtils {

	
	/**
	 * 通过反射, 获得定义 Class 时声明的父类的泛型参数的类型
	 * 如: public EmployeeDao extends BaseDao<Employee, String>
	 * @param clazz
	 * @param index
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class getSuperClassGenricType(Class clazz, int index){
		Type genType = clazz.getGenericSuperclass();
		
		if(!(genType instanceof ParameterizedType)){
			return Object.class;
		}
		
		Type [] params = ((ParameterizedType)genType).getActualTypeArguments();
		
		if(index >= params.length || index < 0){
			return Object.class;
		}
		
		if(!(params[index] instanceof Class)){
			return Object.class;
		}
		
		return (Class) params[index];
	}
	
	/**
	 * 通过反射, 获得 Class 定义中声明的父类的泛型参数类型
	 * 如: public EmployeeDao extends BaseDao<Employee, String>
	 * @param <T>
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static<T> Class<T> getSuperGenericType(Class clazz){
		return getSuperClassGenricType(clazz, 0);
	}
	
	/**
	 * 循环向上转型, 获取对象的 DeclaredMethod
	 * @param object
	 * @param methodName
	 * @param parameterTypes
	 * @return
	 */
	public static Method getDeclaredMethod(Object object, String methodName, Class<?>[] parameterTypes){
		
		for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
			try {
				//superClass.getMethod(methodName, parameterTypes);
				return superClass.getDeclaredMethod(methodName, parameterTypes);
			} catch (NoSuchMethodException e) {
				//Method 不在当前类定义, 继续向上转型
			}
			//..
		}
		
		return null;
	}
	
	/**
	 * 使 filed 变为可访问
	 * @param field
	 */
	public static void makeAccessible(Field field){
		if(!Modifier.isPublic(field.getModifiers())){
			field.setAccessible(true);
		}
	}
	
	/**
	 * 循环向上转型, 获取对象的 DeclaredField
	 * @param object
	 * @param filedName
	 * @return
	 */
	public static Field getDeclaredField(Object object, String filedName){
		
		for(Class<?> superClass = object.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()){
			try {
				return superClass.getDeclaredField(filedName);
			} catch (NoSuchFieldException e) {
				//Field 不在当前类定义, 继续向上转型
			}
		}
		return null;
	}
	
	/**
	 * 直接调用对象方法, 而忽略修饰符(private, protected)
	 * @param object
	 * @param methodName
	 * @param parameterTypes
	 * @param parameters
	 * @return
	 * @throws InvocationTargetException 
	 * @throws IllegalArgumentException 
	 */
	public static Object invokeMethod(Object object, String methodName, Class<?> [] parameterTypes,
			Object [] parameters) throws InvocationTargetException{
		
		Method method = getDeclaredMethod(object, methodName, parameterTypes);
		
		if(method == null){
			throw new IllegalArgumentException("Could not find method [" + methodName + "] on target [" + object + "]");
		}
		
		method.setAccessible(true);
		
		try {
			return method.invoke(object, parameters);
		} catch(IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		} 
		
		return null;
	}
	
	/**
	 * 直接设置对象属性值, 忽略 private/protected 修饰符, 也不经过 setter
	 * @param object
	 * @param fieldName
	 * @param value
	 */
	public static void setFieldValue(Object object, String fieldName, Object value){
		Field field = getDeclaredField(object, fieldName);
		
		if (field == null)
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
		
		makeAccessible(field);
		
		try {
			field.set(object, value);
		} catch (IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		}
	}
	
	/**
	 * 直接读取对象的属性值, 忽略 private/protected 修饰符, 也不经过 getter
	 * @param object
	 * @param fieldName
	 * @return
	 */
	public static Object getFieldValue(Object object, String fieldName){
		Field field = getDeclaredField(object, fieldName);
		
		if (field == null)
			throw new IllegalArgumentException("Could not find field [" + fieldName + "] on target [" + object + "]");
		
		makeAccessible(field);
		
		Object result = null;
		
		try {
			result = field.get(object);
		} catch (IllegalAccessException e) {
			System.out.println("不可能抛出的异常");
		}
		
		return result;
	}
}
Customer类为:

package com.atguigu.jdbc;

import java.sql.Date;

public class Customer {
	 private int id;
	 private String name;
     private String email;
     private Date birth;
     
     public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	public Customer(){}

	 public Customer(int id, String name, String email, Date birth) {
		super();
		this.id = id;
		this.name = name;
		this.email = email;
		this.birth = birth;
	}


	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", email=" + email
				+ ", birth=" + birth + "]";
	}
	
}






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值