反射实现JDBC连接

反射实现JDBC连接

​ 在查询后获取到ResultSet结果集,通过反射的形式将结果集中的数据存入对应的对象中.

​ 1.获取到ResultSetMateData查询表的结构

​ 2.从表结构中,获取到 表名与字段名及字段的个数

​ 3.通过表名找到类名,并加载这个类

​ 4.循环每一个字段,找到属性名对应字段名

​ 5.对对应的属性赋值

注意: 属性的类型使用包装类型,因为数据库中可能存在null

​ 1.设计实体类,避免空指针异常,实体类采用包装类型

public class Goods {
	private Integer gid;
	private String name;
	private Integer tid;
	private Goodstype gt; //外键关联对象
	private Double price;
	private Date outdate;
	private String sup;
	private Integer num;
	public Integer getGid() {
		return gid;
	}
	public void setGid(Integer gid) {
		this.gid = gid;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getTid() {
		return tid;
	}
	public void setTid(Integer tid) {
		this.tid = tid;
	}
	public Goodstype getGt() {
		return gt;
	}
	public void setGt(Goodstype gt) {
		this.gt = gt;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	public Date getOutdate() {
		return outdate;
	}
	public void setOutdate(Date outdate) {
		this.outdate = outdate;
	}
	public String getSup() {
		return sup;
	}
	public void setSup(String sup) {
		this.sup = sup;
	}
	public Integer getNum() {
		return num;
	}
	public void setNum(Integer num) {
		this.num = num;
	}
	@Override
	public String toString() {
		if(gt!=null)
			return "Goods [gid=" + gid + ", name=" + name + ", goodstype=" + gt.getTname() + ", price=" + price + ", outdate=" + outdate
				+ ", sup=" + sup + ", num=" + num + "]";
		else
			return "Goods [gid=" + gid + ", name=" + name + ", goodstype=null, price=" + price + ", outdate=" + outdate
					+ ", sup=" + sup + ", num=" + num + "]";
	}
}

DB工具类设计,采用反射实现获取对象

public abstract class DBUtil<T> {

	private Connection conn = null;
	private PreparedStatement pst = null;
	private ResultSet rs = null;
	private Properties pro = new Properties();
	
	//统一连接方法
	public Connection getConn(){
		try {
			pro.load(this.getClass().getClassLoader().getResourceAsStream("db.properties"));
			Class.forName(pro.getProperty("driver"));
			conn = DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("uname"), pro.getProperty("password"));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return conn;
	}
	//统一更新
	public boolean update(String sql,Object...obj){
		try {
			pst = getConn().prepareStatement(sql);
			//为占位符赋值
			for (int i = 0; i < obj.length; i++) {
				pst.setObject(i+1, obj[i]);
			}
			//执行sql
			int row = pst.executeUpdate();
			if(row>0)
				return true;
		} catch (Exception e) {
			e.printStackTrace();
		}finally {
			getClose(rs, pst, conn);
		}
		return false;
	}
	//统一查询方法
	public List<T> query(String sql,Object...obj){
		List<T> list = new ArrayList<>();
		try {
			pst = getConn().prepareStatement(sql);
			//为占位符赋值
			for (int i = 0; i < obj.length; i++) {
				pst.setObject(i+1, obj[i]);
			}
			//执行sql
			rs = pst.executeQuery();
			//获取到结果集的数据源结构
			ResultSetMetaData rsmd = rs.getMetaData();
			//获取到表名,得到类
			String tableName = rsmd.getTableName(1);
			Class<?> clazz = Class.forName("com.gec.bean."+tableName.substring(0, 1).toUpperCase()+tableName.substring(1));
			//获取到字段的个数
			int cnum = rsmd.getColumnCount();
			while(rs.next()){
				//创建对象
				@SuppressWarnings("unchecked")
				T t = (T) clazz.newInstance();
				//循环字段
				for (int i = 0; i < cnum; i++) {
					//循环字段,并获取到字段名称
					String cname = rsmd.getColumnName(i+1);
					//通过字段名获取到属性
					Field f = clazz.getDeclaredField(cname);
					//打开权限
					f.setAccessible(true);
					//为每个属性赋值
					f.set(t, rs.getObject(i+1));
				}
				//再将对象放入集合
				list.add(t);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return list;
	}
	
	
	public void getClose(ResultSet rs, PreparedStatement pst,Connection conn){
		try {
			if(rs!=null)
				rs.close();
			if(pst!=null)
				pst.close();
			if(conn!=null)
				conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
}

Dao实现,不需要再重写getEntity方法

public class GoodsDaoImpl extends DBUtil<Goods> implements GoodsDao {

	@Override
	public List<Goods> findAll() {
		return query("select * from goods");
	}

	@Override
	public Goods findById(int gid) {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean save(Goods goods) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean update(Goods goods) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public boolean delete(int gid) {
		// TODO Auto-generated method stub
		return false;
	}

}

Service实现,外键对象关联延迟到Service实现类进行

public class GoodsServiceImpl implements GoodsService {
	//将外键对象查询延迟到业务层进行查询
	GoodsTypeDao gtd = new GoodsTypeDaoImpl();
	GoodsDao gd = new GoodsDaoImpl();
	@Override
	public List<Goods> findAll() {
		List<Goods> list = gd.findAll();
		for (Goods goods : list) {
			goods.setGt(gtd.findById(goods.getTid()));
		}
		return list;
	}
}
posted @ 2023-03-17 10:18  devynlime  阅读(58)  评论(0编辑  收藏  举报