本博客根据《李兴华--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();
}
}
}
如果要想很好的完成开发需求,单表操作必须非常熟练!