数据

DAO的开发完全围绕着数据进行,先在数据库中准备几个要用到的表:

sqlcreate table emp (
    empno int(4)    PRIMARY KEY,
    ename varchar(10),
    job varchar(9),
    hiredate    date,
    sal float(7,2)
    );

VO类

根据表中的字段建立对应的VO类:

javapackage temp.vo;

import java.util.Date;

/**
 * Created by mcbird on 14/11/20.
 */
public class Emp {
    private int empno;
    private String ename;
    private String job;
    private Date hiredate;
    private float sal;

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public float getSal() {
        return sal;
    }

    public void setSal(float sal) {
        this.sal = sal;
    }

    public int getEmpno() {
        return empno;

    }

    public void setEmpno(int empno) {
        this.empno = empno;
    }
}

可以看到,VO类中只包含getter和setter方法。定义完VO类之后,接下来定义一个DatebaseConnection类,用来完成数据库的打开及关闭操作。

DatabaseConnection类

考虑到实践当中,有可能使用不同的数据库,所用,我们需要写一个通用接口,以及相应的数据库的实现类。

DatabaseConnection通用接口

javapackage temp.dbc;


import java.sql.Connection;

/**
 * Created by mcbird on 14/11/20.
 */
public interface DatebaseConnection {
    public Connection getConnection() throws Exception;  // 取得数据库连接
    public void close() throws Exception;                //关闭数据库连接
}

通过这样一个接口,能够更好的松耦合、更抽象。

DatabaseConnection实现类

javapackage temp.dbc.impl;

import temp.dbc.DatebaseConnection;

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

/**
 * Created by mcbird on 14/11/20.
 */
public class MySQLDatabaseConnection implements DatebaseConnection {
    private static final String DBDRIVER = "org.gjt.mm.mysql.Driver";
    private static final String DBURL = "jdbc://localhost:3306/temp";
    private static final String DBUSER = "root";
    private static final String DBPASSWORD = "cloudSoft@Skybility";
    private Connection conn = null;


    @Override
    public Connection getConnection() throws Exception {
        try {
            Class.forName(DBDRIVER);
            this.conn = DriverManager.getConnection(DBURL, DBUSER, DBPASSWORD);
        }catch (Exception e) {
            throw e;
        }
        return this.conn;
    }

    @Override
    public void close() throws Exception {
        if(this.conn != null) {
            try {
                this.conn.close();
            } catch (Exception e) {
                throw e;
            }
        }
    }
}

这是针对MySQL的一个实现类,还可以针对不同的数据库编写不同的实现类。

DAO类

在DAO设计模式中,最重要的就是定义DAO接口,在定义DAO接口之前必须对业务进行详细的分析,要清楚地知道一张表在整个系统中应该具备何种功能。

DAO接口

javapackage temp.dao;

import temp.vo.Emp;

import java.util.List;

/**
 * Created by mcbird on 14/11/20.
 */
public interface IEmpDAO {
    /**
     * 数据的增加操作
     * @param emp 要增加的数据对象
     * @return 是否成功增加标志
     */
    public boolean doCreate(Emp emp) throws Exception;


    /**
     * 查询全部数据
     * @param keyWord
     * @return
     * @throws Exception
     */
    public List<Emp> findAll(String keyWord) throws Exception;

    /**
     * 根据编号查询雇员信息
     * @param empno
     * @return
     * @throws Exception
     */
    public Emp findById(int empno) throws Exception;
}

DAO实现类

javapackage temp.dao.impl;

import temp.dao.IEmpDAO;
import temp.vo.Emp;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by mcbird on 14/11/20.
 */
public class EmpDAOImpl implements IEmpDAO {
    private Connection conn = null;
    private PreparedStatement pstmt = null;     //数据库操作对象

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

    @Override
    public boolean doCreate(Emp emp) throws Exception {
        boolean flag = false;
        String sql = "insert int emp (empno,ename,job,hiredate,sal) values (?,?,?,?,?)";
        this.pstmt = this.conn.prepareStatement(sql);
        this.pstmt.setInt(1, emp.getEmpno());
        this.pstmt.setString(2, emp.getEname());
        this.pstmt.setString(3, emp.getJob());
        this.pstmt.setDate(4, new Date(emp.getHiredate().getTime()));
        this.pstmt.setFloat(5, emp.getSal());

        if(this.pstmt.executeUpdate() > 0) {    //更新记录的行数大于0
            flag = true;
        }
        this.pstmt.close();
        return flag;
    }

    @Override
    public List<Emp> findAll(String keyWord) throws Exception {
        List<Emp> all = new ArrayList<Emp>();
        String sql = "select empno,ename,job,hiredate,sal from emp where ename like ? or job like ?";
        this.pstmt = this.conn.prepareStatement(sql);
        this.pstmt.setString(1, "%" + keyWord + "%");
        this.pstmt.setString(2, "%" + keyWord + "%");
        ResultSet rs = this.pstmt.executeQuery();
        Emp emp = null;
        while (rs.next()) {
            emp = new Emp();
            emp.setEmpno(rs.getInt(1));
            emp.setEname(rs.getString(2));
            emp.setJob(rs.getString(3));
            emp.setHiredate(rs.getDate(4));
            emp.setSal(rs.getFloat(5));
            all.add(emp);
        }
        this.pstmt.close();
        return all;
    }

    @Override
    public Emp findById(int empno) throws Exception {
        Emp emp = null;
        String sql = "select empno,ename,job,hiredate,sal from emp where empno=?";
        this.pstmt = this.conn.prepareStatement(sql);
        this.pstmt.setInt(1, empno);
        ResultSet rs = this.pstmt.executeQuery();
        if(rs.next()) {
            emp = new Emp();
            emp.setEmpno(rs.getInt(1));
            emp.setEname(rs.getString(2));
            emp.setJob(rs.getString(3));
            emp.setHiredate(rs.getDate(4));
            emp.setSal(rs.getFloat(5));
        }
        this.pstmt.close();
        return emp;
    }
}

可以发现,在这个实现类中,根本没有数据库的打开和链接操作,只是通过构造方法取得了数据库的链接,那么真正负责打开和关闭的操作是由谁来完成的呢?答案是,代理类。

代理类

javapackage temp.dao.proxy;

import temp.dao.IEmpDAO;
import temp.dao.impl.EmpDAOImpl;
import temp.dbc.DatebaseConnection;
import temp.dbc.impl.MySQLDatabaseConnection;
import temp.vo.Emp;

import java.util.List;

/**
 * Created by mcbird on 14/11/20.
 */
public class EmpDAOProxy implements IEmpDAO {
    private DatebaseConnection dbc = null;
    private IEmpDAO dao = null;
    public EmpDAOProxy() throws Exception {
        this.dbc = new MySQLDatabaseConnection();
        this.dao = new EmpDAOImpl(this.dbc.getConnection());
    }

    @Override
    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;
    }

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

    @Override
    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;
    }
}

可以发现,在代理类的构造方法中实例化了数据库连接类的对象以及DAO的实现类,而在代理中的各个方法只是调用了真实DAO实现类的相应方法。在代理类完成以后,最后还需要编写工厂类,以降低代码间的耦合度。

工厂类

工厂类的功能就是直接返回DAO接口的实例化对象,这样客户端就可以直接通过工厂类取得DAO接口的实例化对象。

javapackage temp.dao.factory;

import temp.dao.IEmpDAO;
import temp.dao.proxy.EmpDAOProxy;

/**
 * Created by mcbird on 14/11/20.
 */
public class DAOFactory {
    public static IEmpDAO getIEmpDAOInstance() throws Exception {
        return new EmpDAOProxy();
    }
}

测试

javapackage temp.test;

import temp.dao.factory.DAOFactory;
import temp.vo.Emp;

import java.util.Date;

/**
 * Created by mcbird on 14/11/20.
 */
public class TestDAOInsert {
    public static void main(String[] args) throws Exception {
        Emp emp = null;
        for(int x = 0; x < 5; x++) {
            emp = new Emp();
            emp.setEmpno(1000 + x);
            emp.setEname("McBird_" + x);
            emp.setJob("Singer_" + x);
            emp.setHiredate(new Date());
            emp.setSal(100 * x);

            DAOFactory.getIEmpDAOInstance().doCreate(emp);
        }
    }
}

MockingBird
5.8k 声望743 粉丝