Java DAO模式 關係配置
阿新 • • 發佈:2019-01-31
本部落格根據《李興華--java8程式設計開發入門》視訊整理而來。
處理關係(瞭解)
現在已經實現了僱員和部門的基礎操作,但是在僱員裡面存在有mgr(所在部門負責人)和deptno(所在部門編號)兩個關聯欄位。
1. 修改VO類的定義:
(1)修改Emp.java類
private Emp mgr ;//部門負責人(仍是僱員) private Dept dept ;//所在部門資訊 public void setMgr(Emp mgr) { this.mgr = mgr; } public void setDept(Dept dept) { this.dept = dept; } public Emp getMgr() { return mgr; }public Dept getDept() { return dept; }
表示僱員和領導關係以及僱員和部門關係。
(2)修改部門定義(Dept.java)
private List<Emp> emps; //部門中的員工們
public void setEmps(List<Emp> emps) {
this.emps = emps;
}
public List<Emp> getEmps() {
return emps;
}
2. 修改EmpDAOImpl子類:
(1)增加資料時需要考慮到僱員的領導以及部門編號
@Override public boolean doCreate(Emp vo) throws Exception { String sql = "insert into emp(empno,ename,job,hiredate,sal,comm,mgr,deptno) values (?,?,?,?,?,?,?,?)"; this.pstmt = this.conn.prepareStatement(sql); // PreparedStatement 作為執行sql語句的物件,其中後面括號中的(sql)是要執行的sql語句; this.pstmt.setInt(1, vo.getEmpno()); this.pstmt.setString(2, vo.getEname()); this.pstmt.setString(3, vo.getJob()); this.pstmt.setDate(4, new java.sql.Date(vo.getHiredate().getTime())); this.pstmt.setDouble(5, vo.getSal()); this.pstmt.setDouble(6, vo.getComm()); if(vo.getMgr() == null) { //沒有設定領導資料 this.pstmt.setNull(7, Types.NULL); }else { this.pstmt.setInt(7, vo.getMgr().getEmpno()); //部門經理編號 } if(vo.getDept() == null) { //沒有設定部門資料 this.pstmt.setNull(8, Types.NULL); }else { //所在部門編號 this.pstmt.setInt(8, vo.getDept().getDeptno()); } return this.pstmt.executeUpdate() > 0; }
(2)修改資料時也需要發生變化
@Override public boolean doUpdate(Emp vo) throws Exception { String sql = "update emp set ename=?,job=?,hiredate=?,sal=?,comm=?,mgr=?,deptno=? where empno=?"; this.pstmt = this.conn.prepareStatement(sql); this.pstmt.setString(1, vo.getEname()); this.pstmt.setString(2, vo.getJob()); this.pstmt.setDate(3, new java.sql.Date(vo.getHiredate().getTime())); this.pstmt.setDouble(4, vo.getSal()); this.pstmt.setDouble(5, vo.getComm()); if(vo.getMgr() == null) { //沒有設定領導資料 this.pstmt.setNull(6, Types.NULL); }else { this.pstmt.setInt(6, vo.getMgr().getEmpno()); //部門經理編號 } if(vo.getDept() == null) { //沒有設定部門資料 this.pstmt.setNull(7, Types.NULL); }else { //所在部門編號 this.pstmt.setInt(7, vo.getDept().getDeptno()); } this.pstmt.setInt(8, vo.getEmpno()); return this.pstmt.executeUpdate() > 0; }
(3)在查詢單個僱員資訊的時候也需要進行全部內容的查詢。
也就是說現在的查詢裡面需要定義新的功能,目的是為了與之前的單表查詢分開。(單表->多表)
在IDAO裡面所寫的大部分方法都是支援單表操作的。而多表操作是Emp才具有的功能,於是需要在IEmpDAO中進行功能擴充。
擴充IEmpDAO方法
package com.fs.dao;
import java.util.List;
import com.fs.vo.Emp;
/**
* 實現emp表的資料層的操作標準
* @author 婉阿婉
*/
public interface IEmpDAO extends IDAO<Integer, Emp> {
/**
* 查詢僱員的詳細資訊,包括僱員對應的領導資訊以及所在的部門資訊
* @param id 要查詢的僱員編號
* @return 所有的資料以VO物件返回,如果沒有則返回空
* @throws Exception SQL執行異常
*/
public Emp findByIdDetails(Integer id) throws Exception;
/**
* 查詢僱員的完整資訊(部門經理人(僱員)所領導的僱員的資訊)
* @return 所有的資料物件以List集合返回,如果沒有資料則集合長度為0(size() == 0)
* @throws Exception SQL執行異常
*/
public List<Emp> findAllDetails() throws Exception;
/**
* 分頁查詢僱員的完整資訊
* @param currentPage 當前所在的頁
* @param lineSize 每頁顯示的資料行數
* @param column 要進行模糊查詢的資料列
* @param keyword 模糊查詢的關鍵字
* @return 如果表中有資料,則所有的資料會封裝為VO物件而後利用List集合返回,<br>
* 如果沒有資料,那麼集合的長度為0(size() == 0,不是null)
* @throws Exception SQL執行異常
*/
public List<Emp> findAllSplitDetails(Integer currentPage, Integer lineSize, String column, String keyword)
throws Exception;
}
一一實現這些方法(單方面的,暫不實現部門找到僱員,因為老師說現在理解不了...)
EmpDAOImpl.java
@Override
public Emp findByIdDetails(Integer id) throws Exception {
Emp vo = null;
String sql = " SELECT e.empno,e.ename,e.job,e.hiredate,e.sal,e.comm," + " m.empno 經理編號,m.ename 經理姓名,"
+ " d.deptno 負責部門編號,d.dname 負責部門名稱,d.loc 負責部門地址 " + " FROM (emp e LEFT JOIN emp m ON e.mgr=m.empno) "
+ " LEFT JOIN dept d ON e.dept=d.deptno " + " WHERE e.empno=? ";
this.pstmt = this.conn.prepareStatement(sql);
ResultSet rs = this.pstmt.executeQuery();
if (rs.next()) {
vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
// 經理僱員資料
Emp mgr = new Emp();
mgr.setEmpno(rs.getInt(7));
mgr.setEname(rs.getString(8));
vo.setMgr(mgr);
// 部門資料
Dept dept = new Dept();
dept.setDeptno(rs.getInt(9));
dept.setDname(rs.getString(10));
dept.setLoc(rs.getString(11));
// 幫僱員找到部門
vo.setDept(dept);
}
return vo;
}
@Override
public List<Emp> findAllDetails() throws Exception {
List<Emp> all = new ArrayList<Emp>();
String sql = " SELECT e.empno,e.ename,e.job,e.hiredate,e.sal,e.comm," + " m.empno 經理編號,m.ename 經理姓名,"
+ " d.deptno 負責部門編號,d.dname 負責部門名稱,d.loc 負責部門地址 " + " FROM (emp e LEFT JOIN emp m ON e.mgr=m.empno) "
+ " LEFT JOIN dept d ON e.dept=d.deptno ";
this.pstmt = this.conn.prepareStatement(sql);
ResultSet rs = this.pstmt.executeQuery();
while (rs.next()) {
// 普通僱員資料
Emp vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
// 經理僱員資料
Emp mgr = new Emp();
mgr.setEmpno(rs.getInt(7));
mgr.setEname(rs.getString(8));
vo.setMgr(mgr);
// 部門資料
Dept dept = new Dept();
dept.setDeptno(rs.getInt(9));
dept.setDname(rs.getString(10));
dept.setLoc(rs.getString(11));
// 幫僱員找到部門
vo.setDept(dept);
// 將僱員加入List集合
all.add(vo);
}
return all;
}
@Override
public List<Emp> findAllSplitDetails(Integer currentPage, Integer lineSize, String column, String keyWord)
throws Exception {
List<Emp> all = new ArrayList<Emp>();
String sql = " select e.empno,e.ename,e.job,e.hiredate,e.sal,e.comm, " + " m.empno 經理編號,m.ename 經理姓名, "
+ " d.deptno 負責部門編號,d.dname 負責部門名稱,d.loc 負責部門地址 " + " FROM (emp e LEFT JOIN emp m ON e.mgr=m.empno) "
+ " LEFT JOIN dept d ON e.dept=d.deptno " + " where e." + column + " like ? limit ?,? ";
this.pstmt = this.conn.prepareStatement(sql);
this.pstmt.setString(1, "%" + keyWord + "%");
this.pstmt.setInt(2, (currentPage - 1) * lineSize);
this.pstmt.setInt(3, lineSize);
ResultSet rs = this.pstmt.executeQuery();
while (rs.next()) {
Emp vo = new Emp();
vo.setEmpno(rs.getInt(1));
vo.setEname(rs.getString(2));
vo.setJob(rs.getString(3));
vo.setHiredate(rs.getDate(4));
vo.setSal(rs.getDouble(5));
vo.setComm(rs.getDouble(6));
// 經理僱員資料
Emp mgr = new Emp();
mgr.setEmpno(rs.getInt(7));
mgr.setEname(rs.getString(8));
vo.setMgr(mgr);
// 部門資料
Dept dept = new Dept();
dept.setDeptno(rs.getInt(9));
dept.setDname(rs.getString(10));
dept.setLoc(rs.getString(11));
// 幫僱員找到部門
vo.setDept(dept);
// 將僱員加入List集合
all.add(vo);
}
return all;
}
在服務層中實現這些方法
(1)IEmpService.java
package com.fs.service;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.fs.vo.Emp;
/**
* 定義Emp表 業務層的執行標準,此類一定要負責資料庫的開啟和關閉操作
* 此類可以通過DAOFactory類取得IEmpDAO的介面物件
* @author 婉阿婉
*/
public interface IEmpService {
public Emp getDetails(int ids) throws Exception;
public List<Emp> listDetails() throws Exception;
public Map<String,Object> listDetails(int currentPage,int lineSize,String column,String keyWord) throws Exception;
/**
* 實現僱員資料的增加操作,本次操作要呼叫IEmpDAO介面的如下方法<br>
* <li>需要呼叫IEmpDAO.findById()方法,判斷要增加資料的id是否已經存在
* <li>如果要增加資料的id不存在則呼叫IEmpDAO.doCreate()方法,返回操作的結果
* @param vo 包含了要增加資料的VO物件
* @return 如果增加資料的ID重複即儲存失敗返回false,否則返回true
* @throws Exception SQL執行異常
*/
public boolean insert(Emp vo) throws Exception;
/**
* 實現僱員資料的修改操作,本次要呼叫IEmpDAO.doUpdate()方法,本次修改屬於全部內容修改
* @param vo 包含了要修改的VO物件
* @return 修改成功返回true,否則返回false
* @throws Exception SQL執行異常
*/
public boolean update(Emp vo) throws Exception;
/**
* 執行僱員資料的刪除操作,可以刪除多個僱員資訊,呼叫IEmpDAO.doRemoveBatch()方法
* @param ids 包含了所有要刪除資料的集合,其中沒有重複資料
* @return 刪除成功(要刪除條數==刪除條數)返回true,否則返回false
* @throws Exception SQL執行異常
*/
public boolean delete(Set<Integer> ids) throws Exception;
/**
* 根據僱員編號查詢僱員的完整資訊,呼叫IEmpDAO.findById()方法
* @param ids 要查詢的僱員編號
* @return 找到了相應的僱員資訊則以VO物件返回,否則返回null
* @throws Exception SQL執行異常
*/
public Emp get(int ids) throws Exception;
/**
* 查詢全部僱員資訊,呼叫IEmpDAO.findAll()方法
* @return 查詢結果以List集合的形式返回,如果沒有資料則集合長度為0
* @throws Exception SQL執行異常
*/
public List<Emp> list() throws Exception;
/**
* 實現資料的模糊查詢與資料統計,要呼叫IEmpDAO介面的兩個方法:<br>
* <li>呼叫IEmpDAO.findAllSplit()方法,查詢出所有的表資料,返回List<Emp>;
* <li>呼叫IEmpDAO.getAllCount()方法,查詢所有的資料量,返回的Integer;
* @param currentPage 當前所在頁
* @param lineSize 每頁顯示的記錄數
* @param column 模糊查詢的資料列
* @param keyWord 模糊查詢的關鍵字
* @return 本方法由於需要返回多種資料型別,所以使用Map集合返回,由於型別不用一,所以所有value的型別設為Object<br>
* <li> key = allEmps,value = IEmpDAO.findAllSplit();返回結果:List<Emp>;
* <li> key = empCount,value = IempDAO.getAllCount();返回結果:Integer;
* @throws Exception
*/
public Map<String, Object> list(int currentPage, int lineSize, String column, String keyWord) throws Exception;
}
EmpServiceImpl.java
package com.fs.dao.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import com.fs.dbc.DatabaseConnection;
import com.fs.factory.DAOFactory;
import com.fs.service.IEmpService;
import com.fs.vo.Emp;
public class EmpServiceImpl implements IEmpService {
// 在這個類的物件內部就提供有一個數據庫連線類的例項化物件
// 一但呼叫了DatabaseConnection,其就會進行資料庫連線
private DatabaseConnection dbc = new DatabaseConnection();
// 在進行insert過程中可能產生異常,但不管怎樣,最後一定要關閉資料庫,所以使用異常處理
@Override
public boolean insert(Emp vo) throws Exception {
try {
if (DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findById(vo.getEmpno()) == null) {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).doCreate(vo);
}
return false; // 已經存在就返回false
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public boolean update(Emp vo) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).doUpdate(vo);
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public boolean delete(Set<Integer> ids) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).doRemoveBatch(ids);
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public Emp get(int ids) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findById(ids);
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public List<Emp> list() throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findAll();
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public Map<String, Object> list(int currentPage, int lineSize, String column, String keyWord) throws Exception {
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("allEmps", DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findAllSplit(currentPage,
lineSize, column, keyWord));
map.put("empCount", DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).getAllCount(column, keyWord));
return map;
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public Emp getDetails(int id) throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findByIdDetails(id);
} catch (Exception e) {
throw e;
} finally {
this.dbc.close();
}
}
@Override
public List<Emp> listDetails() throws Exception {
try {
return DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findAllDetails();
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
@Override
public Map<String, Object> listDetails(int currentPage, int lineSize, String column, String keyWord)
throws Exception {
try {
Map<String, Object> map = new HashMap<String, Object>();
map.put("allEmps", DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).findAllSplitDetails(currentPage,
lineSize, column, keyWord));
map.put("empCount", DAOFactory.getIEmpDAOInstance(this.dbc.getConnection()).getAllCount(column, keyWord));
return map;
} catch (Exception e) {
throw e; // 如果有問題,就直接向上拋
} finally {
this.dbc.close();
}
}
}
測試:TestEmpSplitDetails.java
package com.fs.test;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import com.fs.factory.ServiceFactory;
import com.fs.vo.Emp;
public class TestEmpSplitDetails {
public static void main(String[] args) {
try {
Map<String, Object> map = ServiceFactory.getIEmpServiceInstance().listDetails(1, 5, "ename", "三");
int count = (Integer) map.get("empCount");
System.out.println("總資料量:" + count);
@SuppressWarnings("unchecked")
List<Emp> all = (List<Emp>) map.get("allEmps");// 此處有警告,但此時的級數解決不了,自己去百度
Iterator<Emp> iter = all.iterator();
while (iter.hasNext()) {
Emp vo = iter.next();
System.out.println(vo.getEmpno() + "," + vo.getEname() + "," + vo.getMgr().getEname() + ","
+ vo.getDept().getDname());
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
如果要想很好的完成開發需求,單表操作必須非常熟練!