DAO设计模式介绍(连接池和数据源)

一.设计传输对象

所谓的传输对象其实就是可序列化的JavaBeans(可序列化就是implements Serializable接口)
以一个客户类为例:

package com.homework.dao;

import java.io.Serializable;

public class Customer implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 1L;
    private String cust_id;
    private String cname;
    private String email;
    private double balance;

    public Customer(){}

    public Customer(String cust_id, String cname, String email, double balance) {
        super();
        this.cust_id = cust_id;
        this.cname = cname;
        this.email = email;
        this.balance = balance;
    }

    public String getCust_id() {
        return cust_id;
    }

    public void setCust_id(String cust_id) {
        this.cust_id = cust_id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public double getBalance() {
        return balance;
    }

    public void setBalance(double balance) {
        this.balance = balance;
    }   
}

二.设计一个基类BaseDao连接数据库

1.配置数据源
①连接池与数据源简介

数据源是获取数据库连接的首选方法。这种方法是事先建立若干连接对象,将它们存放在数据库连接池中。这样就不需要为每个HTTP请求都创建一个连接对象,这会大大降低请求的响应时间。

②局部数据源和全局数据源

局部数据源只能被定义数据源的应用程序使用,全局数据源可被所有的应用程序使用。(当然不管配置哪种数据源,都要将JDBC驱动程序复制到Tomcat安装目录的lib目录中)

③配置局部数据源

在项目的META-INF目录下新建context.xml文件
sqlserver这样写:

<?xml version="1.0" encoding="utf-8"?>
<Context reloadable = "true">
    <Resource 
        name="jdbc/sqlserver"
        type="javax.sql.DataSource"
        maxActive="4" 
        maxIdle="2" 
        maxWait="10000"
        username="sa" 
        password="123456"
        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"       
        url="jdbc:sqlserver://localhost:1433;DatabaseName=webHomework"/>
</Context>

对各个属性的解释:

属性 解释
name 数据源名
type 指定该资源的类型,这里是DataSource类型
maxActive 最大连接数,一般根据数据库服务器性能设置,自己的机子(非专业服务器)的话4/8就差不多了
maxIdle 连接池中可空闲的连接的最大数
maxWait 无可用连接时连接池在抛出异常前等待的最大毫秒数
username 数据库用户名
password 数据库用户密码
driverClassName 使用的JDBC驱动程序完整类名
url 传递给JDBC驱动程序的数据库URL

注:如果修改了context.xml文件,应将Tomcat安装目录中的conf/Catalina//localhost/用户名.xml文件删除。

④当然也可以选择配置全局数据源

第一步。在server.xml文件的<GlobalNamingResources>元素内增加和上面一样的代码:

<?xml version="1.0" encoding="utf-8"?>
<Context reloadable = "true">
    <Resource 
        name="jdbc/sqlserver"
        type="javax.sql.DataSource"
        maxActive="4" 
        maxIdle="2" 
        maxWait="10000"
        username="sa" 
        password="123456"
        driverClassName="com.microsoft.sqlserver.jdbc.SQLServerDriver"       
        url="jdbc:sqlserver://localhost:1433;DatabaseName=webHomework"/>
</Context>

其中name是全局数据源名,其他都一样。
第二步。还是要和配置局部数据源一样在META-INF目录下新建context.xml文件,但是代码不同。
这时context.xml文件的写法:

<?xml version="1.0" encoding = "utf-8"?>
<Context reloadable = "true">
    <ResourceLink
        global="jdbc/sqlserver"
        name="jdbc/sampleDS"
        type="javax.sql.DataSource"/>
    <WatchedResource>WEB-INF/web.xml</WatchedResource>
</Context>

这里的global属性对应上面的全局数据源名称,name为指定数据源名,该名相对于java:comp/env命名空间前缀。

2.在应用程序中使用数据源
Context context = new InitialContext();
DataSource ds= (DataSource)context.lookup("java:comp/env/jdbc/sqlserver");//这里jdbc后面的取决于前面配置时写的数据源名称
3.示例:BaseDao.java
package com.homework.dao;

import java.sql.Connection;

import javax.naming.*;
import javax.sql.DataSource;

public class BaseDao {

    DataSource dataSource;

    public BaseDao() {
        // TODO Auto-generated constructor stub
        try {
            Context context = new InitialContext();
            dataSource = (DataSource)context.lookup("java:comp/env/jdbc/sqlserver");
        }catch(NamingException ne) {
            ne.printStackTrace();
        }
    }

    public Connection getConnection()throws Exception{
        return dataSource.getConnection();
    }

}

三、编写dao类继承BaseDao,实现添加、查询等方法

一般来说有几张表就写几个dao类。
CustomerDao.java

package com.homework.dao;

import java.sql.*;
import java.util.ArrayList;
import com.homework.dao.Customer;

public class CustomerDao extends BaseDao {
    // 插入一条客户记录
    public boolean addCustomer(Customer customer) {
        String sql = "INSERT INTO customers" + 
    "(cust_id,cname,email,balance)VALUES(?,?,?,?)";
        try (Connection conn = dataSource.getConnection(); 
        PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, customer.getCust_id());
            pstmt.setString(2, customer.getCname());
            pstmt.setString(3, customer.getEmail());
            pstmt.setDouble(4, customer.getBalance());
            pstmt.executeUpdate();
            return true;
        } catch (SQLException se) {
            se.printStackTrace();
            return false;
        }
    }

    // 按姓名检索客户记录
    public Customer findByName(String cname) {
        String sql = "SELECT cust_id,cname,email,balance" 
    + " FROM customers WHERE cname=?";
        Customer customer = new Customer();
        try (Connection conn = dataSource.getConnection();
    PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, cname);
            try (ResultSet rst = pstmt.executeQuery()) {
                if (rst.next()) {           
                    customer.setCust_id(rst.getString("cust_id"));
                    customer.setCname(rst.getString("cname"));
                    customer.setEmail(rst.getString("email"));
                    customer.setBalance(rst.getDouble("balance"));
                }
            }
        } catch (SQLException se) {
            return null;
        }
        return customer;
    }

    // 按姓名模糊检索客户记录
    public ArrayList<Customer> findByFuzzyName(String cname) {
        ArrayList<Customer> custList = new ArrayList<Customer>();
        String sql = "SELECT cust_id,cname,email,balance" + 
                       " FROM customers WHERE cname like ? "
                       + " or cust_id like ?";
        try (Connection conn = dataSource.getConnection(); 
                PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setString(1, "%"+cname+"%");
            pstmt.setString(2, "%"+cname+"%");
            try (ResultSet rst = pstmt.executeQuery()) {

                while (rst.next()) {
                    Customer customer = new Customer();
                    customer.setCust_id(rst.getString("cust_id"));
                    customer.setCname(rst.getString("cname"));
                    customer.setEmail(rst.getString("email"));
                    customer.setBalance(rst.getDouble("balance"));
                    custList.add(customer);
                }
            }
        } catch (SQLException se) {
            return null;
        }
        return custList;
    }

    // 查询所有客户信息
    public ArrayList<Customer> findAllCustomer() {

        ArrayList<Customer> custList = new ArrayList<Customer>();
        String sql = "SELECT * FROM customers";
        try (Connection conn = dataSource.getConnection();
                PreparedStatement pstmt = conn.prepareStatement(sql);
                ResultSet rst = pstmt.executeQuery()) {
            while (rst.next()) {
                Customer customer = new Customer();
                customer.setCust_id(rst.getString("cust_id"));
                customer.setCname(rst.getString("cname"));
                customer.setEmail(rst.getString("email"));
                customer.setBalance(rst.getDouble("balance"));
                custList.add(customer);
            }
            return custList;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
}

四、使用dao对象

①addCutomer.jsp

<%@ page contentType="text/html; charset=UTF-8" %>
<html><head> <title>Input a Customer</title></head>
<body>
<font color=red>${result}</font>
<p>请输入一条新的客户记录</p>
<form action = "addCustomer.do" method = "post">
    <table>
        <tr><td>客户号:</td> <td><input type="text" name="cust_id" ></td></tr>
        <tr><td>客户名:</td> <td><input type="text" name="cname" ></td></tr>
        <tr><td>Email:</td><td><input type="text" name="email"></td></tr>      
        <tr><td>余额:</td><td><input type="text" name="balance" ></td></tr>
        <tr>
            <td><input type="submit" value="确定" ></td>
            <td><input type="reset" value="重置" ></td>
        </tr>
    </table>
</form>
</body></html>

②AddCustomerServlet.java

package com.homework7.servlet;

import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import com.homework.dao.Customer;
import com.homework.dao.CustomerDao;
import javax.servlet.annotation.WebServlet;

@WebServlet("/addCustomer.do")
public class AddCustomerServlet extends HttpServlet {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        CustomerDao dao = new CustomerDao();
        Customer customer = new Customer();
        String message = null;
        try {
            customer.setCust_id(request.getParameter("cust_id"));
            // 将传递来的字符串重新使用utf-8编码,以免产生乱码
            customer.setCname(new String(request.getParameter("cname").getBytes("iso-8859-1"), "UTF-8"));
            customer.setEmail(new String(request.getParameter("email").getBytes("iso-8859-1"), "UTF-8"));
            customer.setBalance(Double.parseDouble(request.getParameter("balance")));
            boolean success = dao.addCustomer(customer);
            if (success) {
                message = "<li>成功插入一条记录!</li>";
            } else {
                message = "<li>插入记录错误!</li>";
            }
        } catch (Exception e) {
            message = "<li>插入记录错误!</li>";
        }
        request.setAttribute("result", message);
        RequestDispatcher rd = getServletContext().getRequestDispatcher("/addCustomer.jsp");
        rd.forward(request, response);
    }
}

猜你喜欢

转载自blog.csdn.net/yogima/article/details/80640718