使用反射机制写一个通用Dao类对数据库进行增删改查操作

通用DAO类:

package com.xintouyun.dao;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import com.xintouyun.util.JdbcUtil;

public class BaseDao <E> {
	private Class<?> cls;
	public BaseDao() {
		Type sType=getClass().getGenericSuperclass();
		Type[] generics=((ParameterizedType) sType).getActualTypeArguments();
		cls=(Class<?>) (generics[0]);
	}
	//通用的数据库增删改操作,可以总结成update方法来实现
	public int update(String sql,Object...parameters) {
		Connection conn=null;
		PreparedStatement st=null;
		ResultSet rs=null;
		int affectedRow=0;
		conn=JdbcUtil.getConnection();
		try {
			st=conn.prepareStatement(sql);
			setParameters(st,parameters);
			affectedRow=st.executeUpdate();
		} catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcUtil.closeAll(rs, st, conn);
		}	
		return affectedRow;
	}
	//数据库单条查询
	public E get(String sql,Object...parameters) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		Connection conn=null;
		PreparedStatement st=null;
		ResultSet rs=null;
		E obj=null;
		try {
			conn=JdbcUtil.getConnection();
			st=conn.prepareStatement(sql);
			setParameters(st,parameters);
			rs=st.executeQuery();
			while(rs.next()) {
				obj=oneRowToObject(rs);
			}
		}catch (SQLException e) {
			e.printStackTrace();
		}finally {
			JdbcUtil.closeAll(rs, st, conn);
		}	
		return obj;
	}
	//数据库多条查询
	public List<E> list(String sql,Object...parameters) {
		Connection conn = null;
		PreparedStatement st = null;
		ResultSet rs = null;
		List<E> list = new ArrayList<>();
		
		try {
			conn = JdbcUtil.getConnection();
			st = conn.prepareStatement(sql);
			setParameters(st, parameters);
			rs = st.executeQuery();
			while(rs.next()) {
				E obj = oneRowToObject(rs);
				list.add(obj);
			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			JdbcUtil.closeAll(rs, st, conn);
		}
	
		return list;
	}
	private E oneRowToObject(ResultSet rs) throws InstantiationException, IllegalAccessException, SQLException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		E obj;
		obj=(E) cls.newInstance();
		//获取结果集元数据(获取此 ResultSet 对象的列的编号、类型和属性。)
		ResultSetMetaData rd=rs.getMetaData();
		for (int i = 0; i < rd.getColumnCount(); i++) {
			//获取列名
			String columnName=rd.getColumnLabel(i+1);
			//组合方法名
			String methodName="set"+columnName.substring(0, 1).toUpperCase()+columnName.substring(1);
			//获取列类型
			int columnType=rd.getColumnType(i+1);
			Method method=null;
			switch(columnType) {
			case java.sql.Types.VARCHAR:
			case java.sql.Types.CHAR:
				method=cls.getMethod(methodName, String.class);
				if(method!=null) {
					method.invoke(obj, rs.getString(columnName));	
				}
				break;
			
			case java.sql.Types.INTEGER:
			case java.sql.Types.SMALLINT:
				method=cls.getMethod(methodName, int.class);
				if(method!=null) {
					method.invoke(obj, rs.getInt(columnName));	
				}
				break;
			case java.sql.Types.BIGINT:
				method=cls.getMethod(methodName, long.class);
				if(method!=null) {
					method.invoke(obj, rs.getLong(columnName));	
				}
				break;
			case java.sql.Types.DATE:
			case java.sql.Types.TIMESTAMP:
				method=cls.getMethod(methodName, Date.class);
				if(method!=null) {
					method.invoke(obj, rs.getTimestamp(columnName));	
				}
				break;
			case java.sql.Types.DECIMAL:
				method=cls.getMethod(methodName, BigDecimal.class);
				if(method!=null) {
					method.invoke(obj, rs.getBigDecimal(columnName));	
				}
				break;
			case java.sql.Types.DOUBLE:
			case java.sql.Types.NUMERIC:
				method=cls.getMethod(methodName, double.class);
				if(method!=null) {
					method.invoke(obj, rs.getDouble(columnName));	
				}
				break;
			case java.sql.Types.BIT:
				method=cls.getMethod(methodName, boolean.class);
				if(method!=null) {
					method.invoke(obj, rs.getBoolean(columnName));	
				}
				break;
			default:
				break;
			}	
		}
		return obj;
	}
	
	private void setParameters(PreparedStatement st, Object[] parameters) {
		if(parameters!=null&&parameters.length>0) {
			for(int i=0;i<parameters.length;i++) {
				try {
					st.setObject(i+1,parameters[i] );
				} catch (SQLException e) {
					e.printStackTrace();
				}
			}	
		}
	}
}

 JdbcUtil类:这里连接的是本地的mysql数据库的bbs数据库

package com.xintouyun.util;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbcUtil {
	private static final String DRIVER_CLASS="com.mysql.jdbc.Driver";
	private static final String URL="jdbc:mysql:///bbs";
	private static final String USER="root";
	private static final String PASSWORD="123456";
	static {
		try {
			Class.forName(DRIVER_CLASS);
		}catch(ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
	public static Connection getConnection() {
		
		try {
			return DriverManager.getConnection(URL, USER, PASSWORD);
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
		
	}
	public static void closeAll(ResultSet rs,Statement st,Connection conn) {
		try {
			if(rs!=null) {
				rs.close();
			}
			if(st!=null) {
				st.close();
			}
			if(conn!=null) {
				conn.close();
			}
		}catch(SQLException e) {
			e.printStackTrace();
		}
	}
}

 需要使用的时候创建具体的类对应的Dao继承BaseDao,声明一下泛型就可以使用了

比如说,先创建一个user类:

package com.xintouyun.jdbcutil.entity;

public class User {
	private int uid;
	private String uname;
	private String upass;
	private int state;
	private int flag;
	private UserState userState;
	
	public UserState getUserState() {
		return userState;
	}
	public void setUserState(UserState userState) {
		this.userState = userState;
	}
	public int getUid() {
		return uid;
	}
	public void setUid(int uid) {
		this.uid = uid;
	}
	public String getUname() {
		return uname;
	}
	public void setUname(String uname) {
		this.uname = uname;
	}
	public String getUpass() {
		return upass;
	}
	public void setUpass(String upass) {
		this.upass = upass;
	}
	public int getState() {
		return state;
	}
	public void setState(int state) {
		this.state = state;
	}
	public int getFlag() {
		return flag;
	}
	public void setFlag(int flag) {
		this.flag = flag;
	}
}

创建他的UserDao:

package com.xintouyun.dao;

import com.xintouyun.jdbcutil.entity.User;

public class UserDao extends BaseDao <User>{
	
}

创建测试类:

package com.xintouyun.jdbcutil.test;

import java.lang.reflect.InvocationTargetException;
import java.util.List;

import com.xintouyun.dao.UserDao;
import com.xintouyun.jdbcutil.entity.User;

public class test {
	public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
		UserDao userdao = new UserDao();
		/*//删除语句
		//int i=userdao.update("delete from board where bid=?",8);
		//添加语句
		
		//修改语句
		int i=userdao.update("update user set uname='"+"zhaoliu"+"' where uid=6" );
		System.out.println(i);*/
		/*//单行查询
		User user= userdao.get("select * from user where uid=?",1);
		System.out.println(user.getUid()+" "+user.getUname()+" "+user.getState()+" "+user.getFlag());
		*/
		List<User> list=userdao.list("select * from user");
		System.out.println("uid\t"+"uname\t"+"state\t"+"flag");
		for (User user : list) {
			System.out.println(user.getUid()+"\t"+user.getUname()+"\t"+user.getState()+"\t"+user.getFlag());
		}
	}
}

测试结果:

 数据库中内容为:

查询成功!!!

猜你喜欢

转载自blog.csdn.net/qq_40180411/article/details/81556835