Java DAO模式 关系配置

本博客根据《李兴华--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();
		}
	}
}


如果要想很好的完成开发需求,单表操作必须非常熟练!






  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值