通用DAO设计模式

相关术语说明

缩写全名说明
POJOPlain Ordinary Java Objects简单Java对象
VOValue Object与POJO对应,专门用于传递值的操作上
TOTransfers Object传输对象,进行远程传输时,必须实现java.io.Serializable接口
DAOData Access Object数据访问对象,主要用于数据库操作
BOBusiness Object业务对象 ,会将多个原子性的DAO操作进行组合,组合成一个完整的业务对象

DAO设计模式

包命名

名称作用
Factory工厂类提供DAO的实例化对象
Proxy代理实现类数据库打开与关闭,调用真实实现类
ImplDAO真实实现类具体的数据库操作,不负责数据库的打开和关闭
DAO接口类定义数据库的原子性操作接口 ,如增加、删除、修改、按ID查询等
VO实体类主要由属性、setter、getter组成,属性对应表字段,一个VO对象对应一条记录

类命名

数据库连接xxx.dbc.DBConnection
DAO接口xxx.dao.IXxxDao
DAO真实实现类xxx.dao.impl.XxxDaoImpl
DAO代理实现类xxx.dao.proxy.XxxDaoProxy
VO实体类xxx.vo.Xxx(与表名一致)
工厂类xxx.factory.DaoFactory

示例

以MySQL为例

数据库表结构

列编号列名称代表名称数据类型
1empno雇员编号数字,长度4
2ename雇员姓名字符串,长度10
3job雇员工作
4hiredate雇佣日期日期
5sal基本工资数字,长度7,单位分

示例代码结构

|--cn.xuefeibai.demo
|--|--vo
|--|--|--Emp.java
|--|--dao
|--|--|--impl
|--|--|--|--EmpDaoImpl.java
|--|--|--proxy
|--|--|--|--EmpDaoProxy.java
|--|--|--IEmpDao.java
|--|--factory
|--|--|--DaoFactory.java
|--|--dbc
|--|--|--DBConnection.java

VO类

package cn.xuefeibai.demo.vo;

import java.util.Date;

public class Emp{
	private int empno;
	private String ename;
	private String job;
	private Date hiredate;
	private int sal;
	/***************************getter and setter**************************/
}

DBC类

所有异常,统一交给调用者处理

package cn.xuefeibai.demo.dbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class DBConnection{
	private static final String DRIVER = "com.mysql.cj.jdbc.Driver";
	private static final String URL = "jdbc:mysql://localhost:3306/db_demo?characterEncoding=utf-8&serverTimezone=GMT%2B8&useUnicode=true";
	private static final String USER = "root";
	private static final String PASSWORD = "123456";
	private Connection conn = null;

	public DBConnection() throws Exception{
		Class.forName(DRIVER);
		this.conn = DriverManager.getConnection(URL, USER, PASSWORD);
	}

	public Connection getConn(){
		return this.conn;
	}

	public void close() throws Exception{
		if(this.conn != null){
			this.conn.close();
		}
	}
}

DAO类

package cn.xuefeibai.demo.dao;

import java.util.List;
import cn.xuefeibai.demo.vo.Emp;

public interface IEmpDao{
	/**
	 * 数据的增加操作,一般以doXxx命名
	 * @param emp 要增加的数据对象
	 * @return 是否增加成的标记
	 * @throws Exception 有异常交给被调用者处理
	 */
	public boolean doCreate(Emp emp) throws Exception;

	/**
	 * 查询全部的数据,一般以findXxx命名
	 * @param keyWord 查询关键字
	 * @return 返回全部的查询结果,每一个Emp对象表示表的一行记录
	 * @throws Exception 有异常交给被调用者处理
	 */
	public List<Emp> findAll(String keyWord) throws Exception;

	/**
	 * 根据雇员编号查询雇员信息
	 * @param empno 雇员编号
	 * @return 雇员的vo对象
	 * throws Exception 有异常交给被调用者处理
	 */
	public Emp findById(int empno) throws Exception; 
}

Impl类

package cn.xuefeibai.demo.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.xuefeibai.demo.dao.IEmpDao;
import cn.xuefeibai.demo.vo.Emp;

public class EmpDaoImpl implements IEmpDao{
	private Connection conn = null;
	private PreparedStatement pstmt = null;

	public EmpDaoImpl(Connection conn){
		this.conn = conn;
	}

	public boolean doCreate(Emp emp) throws Exception{
		boolean flag = false;
		String sql = "insert into emp(empno, ename, job, hiredate, sal) values(?,?,?,?,?)";
		this.pstmt = this.conn.preparedStatement(sql);
		this.pstmt.setInt(1, emp.getEmpno());
		this.pstmt.setString(2, emp.getEname());
		this.pstmt.setString(3, emp.getJob());
		this.pstmt.setDate(4, new java.sql.Date(emp.getHiredate().getTime()));
		this.pstmt.setInt(5, emp.getSal());
		if(this.pstmt.executeUpdate() > 0){
			flag = true;
		}
		return flag;
	}

	public List<Emp> findAll(String keyWord) throws Exception{
		List<Emp> all = new ArrayList<>();
		String sql = "select empno, ename, job, hiredate, sal from emp where ename like ? or job like ?";
		this.pstmt = this.coon.preparedStatement(sql);
		this.pstmt.setString(1, "%" + keyWord + "%");
		this.pstmt.setString(2, "%" + keyWord + "%");
		ResultSet rs = this.pstmt.executeQuery();
		Emp emp = null;
		while(rs.next()){
			emp = convertToEmp(rs);
			all.add(emp);
		}
		this.rs.close();
		this.pstmt.close();
		return all;
	}

	public Emp findById(int empno) throws Exception{
		String sql = "select empno, ename, job, hiredate, sal from emp where empno = ?";
		this.pstmt = this.conn.preparedStatement(sql);
		this.pstmt.setInt(1, empno);
		ResultSet rs = this.pstmt.executeQuery();
		Emp emp = convertToEmp(rs);
		this.rs.close();
		this.pstmt.close();
		return emp;
	}

	private Emp convertToEmp(ResultSet rs) throws Exception{
		if(rs.next()){
			Emp emp = new Emp();
			emp.setEmpno(rs.getInt(1));
			emp.setEname(rs.getString(2));
			emp.setJbo(rs.getString(3));
			emp.setHiredate(rs.getDate(4));
			emp.setSal(rs.getInt(5));
			return emp;
		}
		return null;
	}
}

Proxy类

在这里实现了数据库连接的打开和关闭

package cn.xuefeibai.demo.dao.proxy;

import java.util.List;
import cn.xuefeibai.demo.dao.IEmpDao;
import cn.xuefeibai.demo.dao.impl.EmpDaoImpl;
import cn.xuefeibai.demo.dbc.DBConnection;
import cn.xuefeibai.demo.vo.Emp;

public class EmpDaoProxy implements IEmpDao{
	private DBConnection dbc = null;
	private IEmpDao dao = null;

	public EmpDaoProxy() throws Exception{
		this.dbc = new DBConnection();
		this.dao = new EmpDaoImpl(this.dbc.getConn());
	}

	public boolean doCreate(Emp emp) throws Exception{
		boolean flag = false;
		try{
			if(this.dao.findById(emp.getEmpno()) == null){
				flag = this.dao.doCreate(emp);
			}
		}catch(Exception e){
			throw e;
		}finally{
			this.dbc.close();
		}
		return flag;
	}

	public List<Emp> findAll(String keyWord) throws Exception{
		List<Emp> all = null;
		try{
			all = this.dao.findAll(keyWord);
		}catch(Exception e){
			throw e;
		}finally{
			this.dbc.close();
		}
		return all;
	}

	public Emp findById(int empno) throws Exception{
		Emp emp = null;
		try{
			emp = this.dao.findById(empno);
		}catch(Exception e){
			throw e;
		}finally{
			this.dbc.close();
		}
		return emp;
	}

Factory类

package cn.xuefeibai.demo.factory;

import cn.xuefeibai.demo.dao.IEmpDao;
import cn.xuefeibai.demo.dao.proxy.EmpDaoProxy;

public class DaoFactory{
	public static IEmpDao getEmpDaoInstance() throws Exception{
		return new EmpDaoProxy();
	}
}

测试

package cn.xuefeibai.demo.dao.test;

import cn.xuefeibai.demo.factory.DaoFactory;
import cn.xuefeibai.demo.vo.Emp;

public class TestDao{
	public static void main(String[] args) throws Exception{
		testInsert();
		testSelect();
	}

	public static void testInsert() throws Exception{
		Emp emp = null;
		for(int x = 0; x < 5; x++){
			emp = new Emp();
			emp.setEmpno(1000 + x);
			emp.setEname("张三-" + x);
			emp.setJob("程序员-" + x);
			emp.setHireDate(new java.util.Data());
			emp.setSal(50000 * x);
			DaoFactory.getEmpDaoInstance().doCreate(emp);
		}
	}

	public static void testSelect() throws Exception{
		List<Emp> all = DaoFactory.getEmpDaoInstance().findAll("");
		Iterator<Emp> it = all.iterator();
		while(it.hasNext()){
			Emp emp = it.next();
			System.out.println(emp.getEmpno() + ": " + emp.getEname() + " -> " + emp.getJob());
		}
	}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值