package com.itheima.domain; //一般:实体类的字段名和数据库表的字段名保持一致 //约定优于编码 public class Account { private int id; private String name; private float money; 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 float getMoney() { return money; } public void setMoney(float money) { this.money = money; } @Override public String toString() { return "Account [id=" + id + ", name=" + name + ", money=" + money + "]"; } }
package com.itheima.util; import java.io.IOException; import java.io.InputStream; import java.sql.Connection; import java.sql.SQLException; import java.util.Properties; import javax.sql.DataSource; import org.apache.commons.dbcp.BasicDataSourceFactory; public class DBCPUtil { private static DataSource dataSource; static{ try { InputStream in = DBCPUtil.class.getClassLoader().getResourceAsStream("dbcpconfig.properties"); Properties props = new Properties(); props.load(in); dataSource = BasicDataSourceFactory.createDataSource(props); } catch (Exception e) { throw new ExceptionInInitializerError(e); } } public static DataSource getDataSource(){ return dataSource; } public static Connection getConnection(){ try { return dataSource.getConnection(); } catch (SQLException e) { throw new RuntimeException(e); } } }
package com.itheima.dbassist; import java.sql.ResultSet; public interface ResultSetHandler { /** * 把结果中的数据封装到指定的对象中 * @param rs * @return 封装了数据的对象 */ Object handle(ResultSet rs); }
package com.itheima.dbassist; import java.lang.reflect.Field; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.List; /** * 封装到JavaBean中 * 满足约定:数据库字段名和JavaBean字段名保持一致 * @author wzhting * */ public class BeanListHanlder implements ResultSetHandler { private Class clazz;//目标类型 public BeanListHanlder(Class clazz){ this.clazz = clazz; } public Object handle(ResultSet rs) { try { List list = new ArrayList(); while(rs.next()){ //有记录 Object bean = clazz.newInstance();//目标对象 //有多少列,列名和值又是什么? ResultSetMetaData rsmd = rs.getMetaData(); int count = rsmd.getColumnCount();//列数 for(int i=0;i<count;i++){ String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名 Object fieldValue = rs.getObject(fieldName);//字段值 //通过字段反射 Field f = clazz.getDeclaredField(fieldName); f.setAccessible(true); f.set(bean, fieldValue); } list.add(bean); } return list; } catch (Exception e) { throw new RuntimeException(e); } } }
package com.itheima.dbassist; import java.lang.reflect.Field; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; /** * 适合只有一条查询结果的情况 * 封装到JavaBean中 * 满足约定:数据库字段名和JavaBean字段名保持一致 * @author wzhting * */ public class BeanHanlder implements ResultSetHandler { private Class clazz;//目标类型 public BeanHanlder(Class clazz){ this.clazz = clazz; } public Object handle(ResultSet rs) { try { if(rs.next()){ //有记录 Object bean = clazz.newInstance();//目标对象 //有多少列,列名和值又是什么? ResultSetMetaData rsmd = rs.getMetaData(); int count = rsmd.getColumnCount();//列数 for(int i=0;i<count;i++){ String fieldName = rsmd.getColumnName(i+1);//得到数据库字段名,也就得到了JavaBan的字段名 Object fieldValue = rs.getObject(fieldName);//字段值 //通过字段反射 Field f = clazz.getDeclaredField(fieldName); f.setAccessible(true); f.set(bean, fieldValue); } return bean; } return null; } catch (Exception e) { throw new RuntimeException(e); } } }
package com.itheima.dbassist; import java.sql.Connection; import java.sql.ParameterMetaData; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; /** * 框架的核心类 * @author wzhting * */ public class DBAssist { private DataSource dataSource; public DBAssist(DataSource dataSource){ this.dataSource = dataSource; } //写:添加、删除、修改 //params参数要和sql中的占位符对应 public void update(String sql,Object...params) { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try{ conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); //设置参数 //得到sql中的参数 ParameterMetaData pmd = stmt.getParameterMetaData(); int count = pmd.getParameterCount(); if(count>0){ if(params==null){ throw new RuntimeException("必须传入参数的值"); } if(count!=params.length){ throw new RuntimeException("参数数量不匹配"); } for(int i=0;i<count;i++){ stmt.setObject(i+1, params[i]); } } stmt.executeUpdate(); }catch(Exception e){ throw new RuntimeException(e); }finally{ release(rs, stmt, conn); } } //读:查询 public Object query(String sql,ResultSetHandler rsh,Object...params) { Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try{ conn = dataSource.getConnection(); stmt = conn.prepareStatement(sql); //设置参数 //得到sql中的参数 ParameterMetaData pmd = stmt.getParameterMetaData(); int count = pmd.getParameterCount(); if(count>0){ if(params==null){ throw new RuntimeException("必须传入参数的值"); } if(count!=params.length){ throw new RuntimeException("参数数量不匹配"); } for(int i=0;i<count;i++){ stmt.setObject(i+1, params[i]); } } rs = stmt.executeQuery(); //有结果集,要封装到对象中。策略设计模式 return rsh.handle(rs); }catch(Exception e){ throw new RuntimeException(e); }finally{ release(rs, stmt, conn); } } private void release(ResultSet rs,Statement stmt,Connection conn){ if(rs!=null){ try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } rs = null; } if(stmt!=null){ try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } stmt = null; } if(conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } conn = null; } } }
package com.itheima.test; import java.util.List; import org.junit.Test; import com.itheima.dbassist.BeanHanlder; import com.itheima.dbassist.BeanListHanlder; import com.itheima.dbassist.DBAssist; import com.itheima.domain.Account; import com.itheima.util.DBCPUtil; public class DBAssistTest { private DBAssist da = new DBAssist(DBCPUtil.getDataSource()); @Test public void testAdd(){ da.update("insert into account values (?,?,?)", 7,"ggg",1000); } @Test public void testUpdate(){ da.update("update account set money=? where id=?", 10000,7); } @Test public void testDel(){ da.update("delete from account where id=?",7); } @Test public void testQueryOne(){ Object obj = da.query("select * from account where id=?",new BeanHanlder(Account.class),2); System.out.println(obj); } @Test public void testQueryAll(){ List list = (List)da.query("select * from account",new BeanListHanlder(Account.class)); for(Object o:list) System.out.println(o); } }