反射实现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;
}
}