dao 層結構的設計方案sql
包和類的分配結構數據庫
1.新建一個項目
2.導入相關的開發包 (好比驅動包等)
3.定義出包的結構
4.將鏈接數據庫的鏈接工具放到 util 包中
5.建立 Emp(簡單 JAVA類, VO類, 實體類,JavaBean) 對象 (該對象放到 vo 包中)
6.開發 dao 層的接口 IEmpDAO (操做標準, 放入dao 包中)
dao 層須要本身的接口爲了解耦合 (一樣的 service 也有本身的接口).
7. 開發出父工具類(此類父工具類中的方法都是泛型方法,由於要讓不一樣的子類使用工具類中的方法)app
1 public class BaseDAOUtil { 2 private PreparedStatement pst; 3 private ResultSet rst; 4 5 public <T> int save(Connection conn,String sql,Class<T> clz,T vo) throws Exception { 6 pst = conn.prepareStatement(sql); 7 //爲 sql 設置佔位符 (insert into 表(字段1,字段2,字段3,) VALUES(?,?,?)) 8 String[] columns = sql.split("\\(")[1].split("\\)")[0].split(","); 9 for (int i = 0; i < columns.length; i++) { 10 Field f = vo.getClass().getDeclaredField(columns[i]); 11 //打開訪問權限 12 f.setAccessible(true); 13 //取得字段對應的屬性值 14 Object fvalue = f.get(vo); 15 pst.setObject(i+1, fvalue); 16 } 17 return pst.executeUpdate(); 18 } 19 public <T> int edit(Connection conn,String sql,T vo) throws Exception { 20 pst = conn.prepareStatement(sql); 21 //UPDATE emp SET sal=?,job=?,comm=? WHERE empno=? AND ; 22 String[] strs = sql.split("SET")[1].split("WHERE")[0].split(","); 23 int i = 0; 24 for (i = 0; i < strs.length; i++) { 25 //獲取要修改的字段名稱 26 String column = strs[i].split("=")[0]; 27 //經過反射獲取 column 對應在 vo 中的屬性對象 28 Field f = vo.getClass().getDeclaredField(column.trim()); 29 f.setAccessible(true); 30 //取得該字段在vo 對象中的值 31 Object fvalue = f.get(vo); 32 //爲佔位符設置具體的內容 33 pst.setObject(i+1, fvalue); 34 } 35 String conditions = sql.split("WHERE")[1].split("=")[0]; 36 Field f = vo.getClass().getDeclaredField(conditions.trim()); 37 f.setAccessible(true); 38 //取得該字段在vo 對象中的值 39 Object fvalue = f.get(vo); 40 pst.setObject(i+1, fvalue); 41 return pst.executeUpdate(); 42 } 43 44 45 public int removeBuId(Connection conn,String sql,Object id) throws Exception { 46 pst = conn.prepareStatement(sql); 47 pst.setObject(1, id); 48 return pst.executeUpdate(); 49 } 50 51 52 public int removeBatch(Connection conn,StringBuffer sql,List<Object> ids) throws Exception { 53 Iterator<Object> iter = ids.iterator(); 54 55 while (iter.hasNext()) { 56 sql.append(iter.next() + ",") ; 57 } 58 sql.delete(sql.length()-1, sql.length()); 59 sql.append(")"); 60 61 pst = conn.prepareStatement(sql.toString()); 62 63 return pst.executeUpdate(); 64 } 65 66 /* 67 * 根據編號查詢數據 68 */ 69 public <T> T selectOne(Connection conn,String sql,Class<T> clz,Object id) throws Exception { 70 pst = conn.prepareStatement(sql); 71 pst.setObject(1, id); 72 //執行 sql 語句 73 rst = pst.executeQuery(); 74 75 T t = null; 76 if (rst.next()) { 77 t=clz.newInstance(); 78 //取得全部屬性 79 Field[] fs = clz.getDeclaredFields(); 80 for (Field f : fs) { 81 //打開訪問權限 82 f.setAccessible(true); 83 //取得屬性名 84 String fname = f.getName(); 85 //使用該屬性名稱從結果集中取得數據 86 Object fvalue = rst.getObject(fname); 87 //將取得的值保存給 t 對象的屬性 88 f.set(t, fvalue); 89 } 90 return t; 91 } 92 return null; 93 } 94 95 96 public <T> List<T> selectList(Connection conn,String sql,Class<T> clz,Object...params) throws Exception { 97 List<T> list = new ArrayList<T>(); 98 pst = conn.prepareStatement(sql); 99 100 for (int i = 0; i < params.length; i++) { 101 pst.setObject(i+1, params[i]); 102 } 103 //執行 sql 語句 104 rst = pst.executeQuery(); 105 T t = null; 106 while (rst.next()) { 107 t = clz.newInstance(); 108 //取得全部屬性 109 Field[] fs = clz.getDeclaredFields(); 110 for (Field f : fs) { 111 //打開訪問權限 112 f.setAccessible(true); 113 //取得屬性名 114 String fname = f.getName(); 115 //使用該屬性名稱從結果集中取得數據 116 Object fvalue = rst.getObject(fname); 117 //將取得的值保存給 t 對象的屬性 118 f.set(t, fvalue); 119 } 120 list.add(t); 121 } 122 return list; 123 } 124 125 public int selectCount(Connection conn,String sql,Object...params) throws Exception { 126 pst = conn.prepareStatement(sql); 127 for (int i = 0; i < params.length; i++) { 128 pst.setObject(i+1, params[i]); 129 } 130 //執行 sql 語句 131 rst = pst.executeQuery(); 132 rst.next(); 133 return rst.getInt(1); 134 } 135 }
8.定義父接口ide
1 public interface IBaseDAO<T> { 2 /** 3 * 增長數據 4 * @param vo 保存了藥插入數據的對象 5 * @return 增長的行數 6 * @throws Exception 7 */ 8 public int insert(T vo) throws Exception; 9 /** 10 * 修改數據 11 * @param vo 保存了要修改的數據的對象 12 * @return 修改的行數 13 * @throws Exception 14 */ 15 public int update(T vo) throws Exception; 16 /** 17 * 根據編號刪除數據 18 * @param empno 要刪除的數據的編號 19 * @return 刪除的行數 20 * @throws Exception 21 */ 22 public int deleteBuId(Object id) throws Exception; 23 /** 24 * 實現批量刪除數據 25 * @param empnos 保存了要刪除的數據的編號的集合 26 * @return 刪除的行數 27 * @throws Exception 28 */ 29 public int deleteBatch(List<Object> ids) throws Exception; 30 /** 31 * 根據編號查詢數據 32 * @param id 要查詢的數據編號 33 * @return 若有數據對象返回數據對象 不然返回 null 34 * @throws Exception 35 */ 36 public T selectById(Object id) throws Exception; 37 /** 38 * 根據姓名模糊分頁查詢 39 * @param kw 模糊查詢的關鍵字 40 * @param cp 當前頁 41 * @param ls 每頁顯示的數據量 42 * @return 返回保存了 Emp 對象的集合 43 * @throws Exception 44 */ 45 public List<T> selectSplitAll(String kw,Integer cp,Integer ls) throws Exception; 46 /** 47 * 統計數據量 48 * @param kw 模糊查詢的關鍵字 49 * @return 返回查詢到的數據量 50 * @throws Exception 51 */ 52 public int selectCount(String kw) throws Exception; 53 }
9.讓子接口實現父接口的時候給出具體泛型工具
public interface IDeptDAO extends IBaseDAO<Dept>{ //定義子接口特有的方法 } public interface IEmpDAO extends IBaseDAO<Emp>{ //定義子接口特有的方法 }
10讓子類繼承父工具類的同時實現本身的子接口測試
1 public class EmpDAOImpl extends BaseDAOUtil implements IEmpDAO { 2 private Connection conn; 3 public EmpDAOImpl() { 4 super(); 5 } 6 public EmpDAOImpl(Connection conn) { 7 super(); 8 this.conn = conn; 9 } 10 11 @Override 12 public int insert(Emp vo) throws Exception { 13 String sql = "INSERT INTO emp(empno,ename,job,sal,hiredate,mgr,comm,deptno)" + " VALUES(?,?,?,?,?,?,?,?)"; 14 return super.save(conn, sql, Emp.class, vo); 15 } 16 17 @Override 18 public int update(Emp vo) throws Exception { 19 String sql = "UPDATE emp SET ename=?,job=?,sal=?,hiredate=?,mgr=?,comm=?,deptno=? WHERE empno=?"; 20 return super.edit(conn, sql, vo); 21 } 22 23 @Override 24 public int deleteBuId(Object id) throws Exception { 25 String sql = "DELETE FROM emp WHERE empno=?"; 26 return super.removeBuId(conn, sql, id); 27 } 28 29 @Override 30 public int deleteBatch(List<Object> ids) throws Exception { 31 StringBuffer sql = new StringBuffer("DELETE FROM emp WHERE empno IN("); 32 return super.removeBatch(conn, sql, ids); 33 } 34 35 @Override 36 public Emp selectById(Object id) throws Exception { 37 String sql = "SELECT empno,ename,job,sal,hiredate,mgr,comm,deptno" + " FROM emp" + " WHERE empno=?"; 38 return super.selectOne(conn, sql, Emp.class, id); 39 } 40 41 @Override 42 public List<Emp> selectSplitAll(String kw, Integer cp, Integer ls) throws Exception { 43 String sql = "SELECT empno,ename,job,sal,hiredate,mgr,comm,deptno" + " FROM emp" 44 + " WHERE ename LIKE ? LIMIT ?,?"; 45 return super.selectList(conn, sql, Emp.class, kw,(cp-1)*ls,ls); 46 } 47 48 @Override 49 public int selectCount(String kw) throws Exception { 50 String sql = "SELECT COUNT(*)" + " FROM emp" + " WHERE ename LIKE ?"; 51 return super.selectCount(conn, sql, kw); 52 } 53 }
測試:this
public class Test { public static void main(String[] args) throws Exception { Connection conn = DBUitl.getConnection(); IEmpDAO dao1 = new EmpDAOImpl(conn); // IDeptDAO dao2 = new DeptDAOImpl(conn); // System.out.println(dao1.insert(new Emp(1115,"zhang33","音樂",9000.00,new Date(),7788,2000.00,10))); // System.out.println(dao1.deleteBuId(1115)); // List<Object> list = new ArrayList<Object>(); // list.add(1009); // list.add(1115); // System.out.println(dao1.deleteBatch(list)); // System.out.println(dao1.selectById(7788)); // System.out.println(dao1.selectCount("A%")); // List<Emp> list = dao1.selectSplitAll("%A%", 2, 5); // for (Emp emp : list) { // System.out.println(emp); // } // System.out.println(dao2.selectById(20)); // System.out.println(dao2.selectCount("A%")); } }