这篇文章建立在有比较好的java基础之上。没有学过web开发的也能学习,主要是如何操作数据库比较合理。
资源层主要是对一些数据进行储存,比如数据库。
数据层就是对资源层的数据进行操作。对数据库进行操作。
业务层是整个项目的核心。
DAO中定义的接口有规范性:
数据库的更新操作用 doXXX()
数据库的查找用findXXX()或者getXXX();
其实DAO设计模式就是通过javabean完成功能,Jsp进行显示,实现数据操作和显示相分离。
第一步:写我们的VO(类似于一个javabean)
package cn.luoji.vo;
import java.util.Date; //Date类用来处理时间。
public class Emp
{
private String empno;
private String ename;
private String job;
private Date hiredate;
private float sal;
public void setEmpno(String empno)
{
this.empno = empno;
}
public String getEmpno()
{
return this.empno;
}
public void setEname(String ename)
{
this.ename = ename;
}
public String getEname()
{
return this.ename;
}
public void setJob(String job)
{
this.job = job;
}
public String getJob()
{
return this.job;
}
public void setHiredate(Date hiredate)
{
this.hiredate = hiredate;
}
public Date getHiredate()
{
return this.hiredate;
}
public void setSal(float sal)
{
this.sal = sal;
}
public float getSal()
{
return this.sal;
}
}
第二步:连接数据库,关闭数据库的类。在这一步,我们要得到已经取得连接的Connection对象。所以要有此方法,还要有关闭的方法。
package cn.luoji.dbc;
import java.sql.*;
public class DatabaseConnection
{
public static final String DB_DRIVER = "com.mysql.jdbc.Driver";
public static final String DB_URL = "jdbc:mysql://localhost/db_emp";//emp是数据库名
public static final String DB_USER = "root";
public static final String DB_PASS = "root";
private Connection con = null;
public DatabaseConnection() throws Exception
{
Class.forName(DB_DRIVER);
con = DriverManager.getConnection(DB_URL,DB_USER,DB_PASS);
}
//获取已经连接到的Connection对象
public Connection getConnection()
{
return this.con;
}
//关闭连接
public void close() throws Exception
{
if(this.con != null)
{
try
{
this.con.close();
}
catch (Exception e)
{
throw e;
}
}
}
}
第三步:设置操作数据库的接口:
package cn.luoji.dao;
import cn.luoji.vo.*;
import java.util.*;
public interface IEmpDAO
{
public boolean doCreate(Emp emp) throws Exception;//添加一个
public List<Emp> findAll(String keyword) throws Exception;//列出全部
public Emp findById(String empno) throws Exception;//查找一个
//需要对数据库进行其他操作就在这里添加相应接口
}
第四步:具体实现类,实现上面的接口,复写里面的方法,就是利用PreparedStatement和ResultSet类进行相应的增删查改
package cn.luoji.daoimpl;
import java.sql.*;
import cn.luoji.dao.*;
import cn.luoji.vo.*;
import java.util.*;
public class EmpDAOImpl implements IEmpDAO
{
private Connection con = null;
private PreparedStatement pstmt = null;
private ResultSet rs = null;
public EmpDAOImpl(Connection con)
{
this.con = con;
}
public boolean doCreate(Emp emp) throws Exception
{
boolean flag = false;
String sql = "insert into tb_person(empno,ename,job,hiredate,sal) values(?,?,?,?,?)";
this.pstmt = this.con.prepareStatement(sql);
this.pstmt.setString(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.setFloat(5,emp.getSal());
if(this.pstmt.executeUpdate()>0)
{//如果有更新
flag = true;
}
this.pstmt.close();
return flag;
}
public List<Emp> findAll(String keyword) throws Exception
{
List <Emp>all = new ArrayList<Emp>();
String sql = "select * from tb_person where ename like ? or job like ?";
this.pstmt = this.con.prepareStatement(sql);
this.pstmt.setString(1,"%"+keyword+"%");
this.pstmt.setString(2,"%"+keyword+"%");
this.rs = this.pstmt.executeQuery();
Emp emp = null;
while(rs.next())
{
emp = new Emp();
emp.setEmpno(rs.getString(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;
}
public Emp findById(String empno) throws Exception
{
String sql = "select * from tb_person where empno like ?";
this.pstmt = this.con.prepareStatement(sql);
this.pstmt.setString(1,empno);
this.rs = this.pstmt.executeQuery();
Emp emp = null;
if(rs.next())
{
emp = new Emp();
emp.setEmpno(rs.getString(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;
}
}
第五步:代理类,也实现接口,代理类要在构造方法中,获取第二步中取得的Connection对象。并把这个对象送给第三步主要类的构造方法。然后不要忘记了数据库的关闭操作。
package cn.luoji.proxy;
import java.sql.*;
import cn.luoji.dao.*;
import cn.luoji.vo.*;
import java.util.*;
import cn.luoji.dbc.*;
import cn.luoji.daoimpl.*;
public class EmpDAOProxy implements IEmpDAO
{
private Connection con = null;
private DatabaseConnection dbc = null;
private IEmpDAO dao = null;
public EmpDAOProxy() throws Exception
{
//得到连接到数据库的对象
this.dbc = new DatabaseConnection();
//获得取得dao对象的类
this.dao = new EmpDAOImpl(dbc.getConnection());//接口通过子类实例化
}
public boolean doCreate(Emp emp) throws Exception
{
boolean flag = false;
try{
if(this.dao.findById(emp.getEmpno()) == null)//保证没有重复的id,即原来并不存在这个用户。
{
flag = this.dao.doCreate(emp);
}
}catch(Exception e)
{
throw e;
}finally
{
dbc.close();
}
return flag;
}
public List<Emp> findAll(String keyword) throws Exception
{
List <Emp>all = null;
try{
all = dao.findAll(keyword);
}catch(Exception e)
{
throw e;
}finally
{
dbc.close();
}
return all;
}
public Emp findById(String empno) throws Exception
{
Emp emp = null;
try{
emp = this.dao.findById(empno);
}catch(Exception e)
{
throw e;
}finally
{
dbc.close();
}
return emp;
}
}
第六步:工厂类
package cn.luoji.daofactory;
import cn.luoji.dao.*;
import cn.luoji.proxy.*;
public class DAOFactory
{
public static IEmpDAO getIEmpDAOInstance() throws Exception
{
return new EmpDAOProxy();
}
}
//工厂是接口和代理的汇合点。直接通过这个静态方法获取一个代理,然后调用你想要的方法进行数据库操作。
第七步:测试类
package cn.luoji.test;
import cn.luoji.daofactory.DAOFactory;
import cn.luoji.vo.*;
import java.util.*;
public class TestDAO
{
public static void main(String args[]) throws Exception
{
Emp emp = new Emp();
emp.setEmpno("007");
emp.setEname("罗");
emp.setJob("新手");
emp.setHiredate(new java.util.Date());
emp.setSal(5000.00f);
DAOFactory.getIEmpDAOInstance().doCreate(emp);
System.out.println(DAOFactory.getIEmpDAOInstance().findById("09424").getEname());
}
}
这时在数据库中会添加一个007 "罗" .....的用户。并打印出empno为09424的用户的姓名。
第八步:用jsp页面进行显示
由于在jsp页面中,应该尽量避免 import 指令,一般最好只导入java.util.*包。而且我们需要减少jsp中的scriptlet代码。所以model1,也就是dao设计模式需要改进。这里暂时不在jsp页面中进行处理了。这就要应用我们的Model2 。由Servlet处理问题,再提交到Jsp页面进行显示。
(待续)