数据
DAO的开发完全围绕着数据进行,先在数据库中准备几个要用到的表:
sql
create table emp ( empno int(4) PRIMARY KEY, ename varchar(10), job varchar(9), hiredate date, sal float(7,2) );
VO类
根据表中的字段建立对应的VO类:
java
package 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通用接口
java
package 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实现类
java
package 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接口
java
package 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实现类
java
package 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; } }
可以发现,在这个实现类中,根本没有数据库的打开和链接操作,只是通过构造方法取得了数据库的链接,那么真正负责打开和关闭的操作是由谁来完成的呢?答案是,代理类。
代理类
java
package 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接口的实例化对象。
java
package 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(); } }
测试
java
package 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); } } }
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。