总结自《Java Web开发实战经典》–李兴华
实例: 这个也是书中的实例:
一.首先建立一张表:
mysql> create table emp(
-> empno int(4) primary key,
-> ename varchar(10),
-> job varchar(9),
-> hiredate date,
-> sal float(7,2)
-> );
Query OK, 0 rows affected (0.15 sec)
二.围绕这张表编写后端代码:
1.首先定义VO类:(就是一个javabean)
注意:VO类中的名称和表中的名称要基本一致(首字母大写)
Emp.java
package DAO;
import java.util.Date;
public class Emp {
private int empno;//定义员工编号
private String ename;//员工姓名
private String job;//职位
private Date hiredate;//雇佣日期
private float sal;//工资
public int getEmpno()
{
return empno;
}
public void setEmpno(int empno)
{
this.empno=empno;
}
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;
}
}
2.定义数据库连接类:
它主要完成数据的打开和关闭:
DatabaseConnection.java
package DAO;
import java.sql.Connection;
import java.sql.DriverManager;
public class DatabaseConnection {
private Connection con=null;
private String url="jdbc:mysql://localhost:3306/jdbc?&useSSL=false&serverTimezone=UTC";
private String classname="com.mysql.cj.jdbc.Driver";
public DatabaseConnection() throws Exception{
try{
Class.forName(classname);//加载驱动
this.con=DriverManager.getConnection(url,"root","root");//建立连接
}catch(Exception e)
{
throw e;
}
}
public Connection getConnection()//得到连接
{
return this.con;
}
public void close() throws Exception{//关闭数据库
if(this.con!=null)
{
try{
this.con.close();
}catch(Exception e)
{
throw e;
}
}
}
}
3.定义DAO接口:
在DAO设计模式中,最重要的就是这一步,它定义了对数据库的具体操作方法。
所以在此之前我们要对业务进行详细的分析,要清楚的知道数据库中的表的功能。
IEmpDAO.java
package DAO;
import java.util.List;
public interface IEmpDAO {
//数据的增加操作
public boolean doCreate(Emp emp)throws Exception;
//数据的查询操作 返回全部查询结果,每一个Emp对象表示表的一行结果
public List<Emp>findAll(String keyWord)throws Exception;
//根据员工编号查询
public Emp findById(int empno)throws Exception;
}
4.接口定义完了后就要实现它,下面我们编写DAO的实现类:
DAO的实现类有两个:
(1).真实主题实现类:主要负责具体的数据库操作:
EmpDAOImpl.java
package DAO;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
public class EmpDAOImpl implements IEmpDAO{
private Connection con=null;
private PreparedStatement pastmt=null;
public EmpDAOImpl(Connection con)
{
this.con=con;
}
@Override
public boolean doCreate(Emp emp) throws Exception {//实现更新数据库方法
// TODO Auto-generated method stub
boolean flag=false;
String sql="insert into emp(empno,ename,job,hiredate,sal) values(?,?,?,?,?)";
this.pastmt=this.con.prepareStatement(sql);//实例化PreparedStatement对象
this.pastmt.setInt(1, emp.getEmpno());
this.pastmt.setString(2, emp.getEname());
this.pastmt.setString(3, emp.getJob());
this.pastmt.setDate(4, new Date(emp.getHiredate().getTime()));
this.pastmt.setFloat(5, emp.getSal());
if(this.pastmt.executeUpdate()>0)//更新记录的行数大于0返回true
flag=true;
this.pastmt.close();
return flag;
}
@Override
public List<Emp> findAll(String keyWord) throws Exception {//实现查询数据库方法
// TODO Auto-generated method stub
List<Emp>all=new ArrayList<Emp>();
String sql="select * from emp where ename like ? or job like ?";
this.pastmt.setString(1, "%"+keyWord+"%");
this.pastmt.setString(2, "%"+keyWord+"%");
ResultSet rs=this.pastmt.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.pastmt.close();
return all;
}
@Override
public Emp findById(int empno) throws Exception {//按照编号查询数据
// TODO Auto-generated method stub
Emp emp=null;
String sql="select * from emp where empno=?";
this.pastmt=this.con.prepareStatement(sql);
this.pastmt.setInt(1, empno);
ResultSet rs=this.pastmt.executeQuery();
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));
}
this.pastmt.close();
return emp;
}
}
上面的代码我们可以看出没有数据库的打开和关闭操作。
其实真正负责打开和关闭的操作的是代理类:
IEmpDAOProxy.java
package DAO;
import java.util.List;
public class IEmpDAOProxy implements IEmpDAO{
private DatabaseConnection dbc=null;//定义数据库连接类
private IEmpDAO dao=null;//接口回调
public IEmpDAOProxy() throws Exception{//实例化连接
this.dbc=new DatabaseConnection();
this.dao=new EmpDAOImpl(this.dbc.getConnection());
}
@Override
public boolean doCreate(Emp emp) throws Exception {
// TODO Auto-generated method stub
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 {
// TODO Auto-generated method stub
List<Emp>all=null;
try{
all=this.dao.findAll(keyWord);
}catch(Exception e)
{
throw e;
}
finally{
this.dbc.close();
}
return all;
}
@Override
public Emp findById(int empno) throws Exception {
// TODO Auto-generated method stub
Emp emp=null;
try{
emp=this.dao.findById(empno);
}catch(Exception e)
{
throw e;
}
finally{
}
return emp;
}
}
5.然后就要编写工厂类,来降低代码直接的耦合度:
DAOFactory.java
package DAO;
public class DAOFactory {
public static IEmpDAO getIEmpDAOInstance() throws Exception{
return new IEmpDAOProxy();
}
}
测试代码:
package DAO;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
public class text {
public static void main(String[] args) throws Exception{
Emp emp=null;
for(int x=0;x<5;x++)
{
emp=new Emp();
emp.setEmpno(66+x);
emp.setEname("文牧之-"+x);
emp.setJob("java程序员-"+x);
emp.setHiredate(new Date());
emp.setSal(1000*x);
DAOFactory.getIEmpDAOInstance().doCreate(emp);
}
List<Emp>all=DAOFactory.getIEmpDAOInstance().findAll("");
Iterator<Emp>iter=all.iterator();
while(iter.hasNext())
{
Emp emp1=iter.next();
System.out.println(emp1.getEmpno()+","+emp1.getEname());
}
}
}
结果: