相关术语说明
缩写 | 全名 | 说明 |
---|---|---|
POJO | Plain Ordinary Java Objects | 简单Java对象 |
VO | Value Object | 与POJO对应,专门用于传递值的操作上 |
TO | Transfers Object | 传输对象,进行远程传输时,必须实现java.io.Serializable接口 |
DAO | Data Access Object | 数据访问对象,主要用于数据库操作 |
BO | Business Object | 业务对象 ,会将多个原子性的DAO操作进行组合,组合成一个完整的业务对象 |
DAO设计模式
包命名
包 | 名称 | 作用 |
---|---|---|
Factory | 工厂类 | 提供DAO的实例化对象 |
Proxy | 代理实现类 | 数据库打开与关闭,调用真实实现类 |
Impl | DAO真实实现类 | 具体的数据库操作,不负责数据库的打开和关闭 |
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为例
数据库表结构
列编号 | 列名称 | 代表名称 | 数据类型 |
---|---|---|---|
1 | empno | 雇员编号 | 数字,长度4 |
2 | ename | 雇员姓名 | 字符串,长度10 |
3 | job | 雇员工作 | |
4 | hiredate | 雇佣日期 | 日期 |
5 | sal | 基本工资 | 数字,长度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());
}
}
}