J2EE--DAO设计模式基础
传统两级模式的问题:
1、所有的JDBC代码写在JSP页面之中,维护困难。
2、JSP中不应该使用任何sql包,即:不能在JSP中直接使用java.sql.*,原因:JSP只关注于数据的显
示,而不关心数据从哪里来,或向哪里存储。
3、所有的数据库操作代码最好使用PreparedStatement
J2EE的组件层次:
客户端 —>表示层(*.jsp/servlet)—>业务层—>数据层—>数据库
DAO属于J2EE数据层的操作:
即:在DAO中封装了一个表在一个项目中所应该具有的全部操作。
有如下数据库脚本:
程序在编程数据库之后,前台页面不会出现太多改变?
首先需要规定整个模块之中对person表的全部操作:
*增加 *修改 *删除 *按ID查询 *查询全部 *模糊查询
按以上要求,规定出操作此张表的标准,之后只要针对不同的数据库实现这些标准即可。
在JAVA中只要通过接口可以定义接口 —>DAO定义的就是一个接口。
案例:
说明:比如说一个图书馆,图书馆可以增加书籍。如果要在增加之前,应该把一本书给图书馆才可以。
插入—>针对对象插入
对象—>VO、TO、POJO(值对象、传输对象、最根本的JAVA对象)即:最包含属性和setter和getter方法的类
一、封装数据库连接
package cn.jdbc;
import java.sql.*;
public class DataBaseConn {
Connection conn = null;
public Connection getConn() {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.print("初始化失败!") ;
e.printStackTrace();
}
try {
this.conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dao", "root", "19871114");
} catch (SQLException e) {
System.out.print("连接失败!") ;
e.printStackTrace();
}
return this.conn;
}
public void close(){
try{
if(conn!= null){
conn.close();
conn = null;
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
二、定义对象的属性和数据库中的表中的字段完全对应
package cn.vo;
//值对象,包含属性,setter和getter方法
public class Person {
String id = null;
String name = null;
String password = null;
int age ;
String email = null;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
三、定义DAO接口
package cn.dao;
import java.util.*;
import cn.vo.*;
public interface PersonDao{
public void insert( Person p) throws Exception;//抛出异常
public void update( Person p) throws Exception;
public void delete(String id) throws Exception;
public Person queryById(String id) throws Exception;
public List queryAll() throws Exception;
public List queryByLikes(String cond) throws Exception;
}
四、定义好接口之后,要定义出接口的具体实现类,具体实现DAO接口中对数据库表中的一切操作。
定义一个数据库连接类,由数据库连接类统一管理数据库连接。
package cn.dao.impl;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
import cn.dao.PersonDao;
import cn.jdbc.DataBaseConn;
import cn.vo.Person;
//此处需要数据库连接
public class PersonImpl implements PersonDao {
public void delete(String id) throws Exception {
String sql = "DELETE FROM person WHERE id=?" ;
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
pstmt.setString(1,id);
// 执行更新操作
pstmt.executeUpdate();
pstmt.close();
} catch (Exception e) {
throw new Exception("删除操作出现异常");
}finally{
dbc.close();
}
}
public void insert(Person person) throws Exception {
String sql = "INSERT INTO person(id,name,password,age,email)VALUES(?,?,?,?,?)";
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
pstmt.setString(1, person.getId());
pstmt.setString(2, person.getName());
pstmt.setString(3, person.getPassword());
pstmt.setInt(4, person.getAge());
pstmt.setString(5, person.getEmail());
// 执行更新操作
pstmt.executeUpdate();
pstmt.close();
} catch (Exception e) {
throw new Exception("插入操作出现异常");
}finally{
dbc.close();
}
}
public List queryAll() throws Exception {
List ls = new ArrayList();
Person person = null;
String sql = "SELECT id,name,password,age,email FROM person " ;
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
// 执行查询操作
ResultSet rs = null;
rs = pstmt.executeQuery();
while(rs.next()){
person = new Person();
person.setId(rs.getString(1));
person.setName(rs.getString(2));
person.setPassword(rs.getString(3));
person.setAge(rs.getInt(4));
person.setEmail(rs.getString(5));
ls.add(person);
}
rs.close();
pstmt.close();
} catch (Exception e) {
throw new Exception("查询全部操作出现异常");
}finally{
dbc.close();
}
return ls;
}
public Person queryById(String id) throws Exception {
Person person = null;
String sql = "SELECT id,name,password,age,email FROM person WHERE id=?" ;
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
pstmt.setString(1, id);
// 执行查询操作
ResultSet rs = null;
rs = pstmt.executeQuery();
if(rs.next()){
person = new Person();
person.setId(rs.getString(1));
person.setName(rs.getString(2));
person.setPassword(rs.getString(3));
person.setAge(rs.getInt(4));
person.setEmail(rs.getString(5));
}
rs.close();
pstmt.close();
} catch (Exception e) {
throw new Exception("按id查询操作出现异常");
}finally{
dbc.close();
}
return person;
}
public List queryByLikes(String cond) throws Exception {
List ls = new ArrayList();
Person person = null;
String sql = "SELECT id,name,password,age,email FROM person WHERE name LIKE ? or email LIKE ?" ;
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
pstmt.setString(1,"%"+cond+"%") ;
pstmt.setString(2,"%"+cond+"%") ;
// 执行查询操作
ResultSet rs = null;
rs = pstmt.executeQuery();
while(rs.next()){
person = new Person();
person.setId(rs.getString(1));
person.setName(rs.getString(2));
person.setPassword(rs.getString(3));
person.setAge(rs.getInt(4));
person.setEmail(rs.getString(5));
ls.add(person);
}
rs.close();
pstmt.close();
} catch (Exception e) {
throw new Exception("模糊查询操作出现异常");
}finally{
dbc.close();
}
return ls;
}
public void update(Person person) throws Exception {
String sql = "UPDATE person SET name=?,password=?,age=?,email=? WHERE id=?" ;
PreparedStatement pstmt = null;
DataBaseConn dbc = null;
try {
dbc = new DataBaseConn();
pstmt = dbc.getConn().prepareStatement(sql);
pstmt.setString(1, person.getName());
pstmt.setString(2, person.getPassword());
pstmt.setInt(3, person.getAge());
pstmt.setString(4, person.getEmail());
pstmt.setString(5, person.getId());
// 执行更新操作
pstmt.executeUpdate();
pstmt.close();
} catch (Exception e) {
throw new Exception("修改操作出现异常");
}finally{
dbc.close();
}
}
}
五、前台JSP可以直接通过VO对象间接访问数据库
<%@ page language="java" pageEncoding="GB18030"%>
<%@ page import="cn.dao.*"%>
<%@ page import="cn.vo.*"%>
<%@ page import="cn.dao.impl.*"%>
<%
Person person = new Person();
person.setId("057229");
person.setName("ma cong");
person.setPassword("19871114");
person.setAge(21);
person.setEmail("macong1114@126.com");
PersonDao dao = new PersonImpl();
try {
dao.insert(person);
out.print("success!!");
} catch (Exception e) {
out.print("erro!!");
}
%>
六、使用工厂类Factory,使前台(JSP页面)不用关心后台具体的子类
package cn.dao.factory;
import cn.dao.PersonDao;
import cn.dao.impl.PersonImpl;
public class DAOFactory {
public static PersonDao getDAOInstance(){
return new PersonImpl();
}
}
前台JSP代码:PersonDao dao = new PersonImpl()
就可以改为 PersonDao dao = DAOFactory.getDAOInstance();