思維導圖 – Servlet+ThreadLocal分包管理實例
一:本文思維導圖
二:ThreadLocal原理圖
三:代碼:
實體層entity Book.java
package entity;
public class Book {
/*私有屬性*/
private int id;
private String name;
private String author;
private String publisher;
private int price;
/*默認構造函數*/
public Book() {
super();
}
public Book(String name, String author, String publisher, int price) {
super();
this.name = name;
this.author = author;
this.publisher = publisher;
this.price = price;
}
public Book(int id, String name, String author, String publisher, int price) {
super();
this.id = id;
this.name = name;
this.author = author;
this.publisher = publisher;
this.price = price;
}
/*對象屬性操作*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPublisher() {
return publisher;
}
public void setPublisher(String publisher) {
this.publisher = publisher;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
數據訪問層data access object(dao)—BaseDao.java
package dao;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class BaseDao {
// 數據庫驅動
private static final String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
// 連接數據庫的url路徑
private static final String url = "jdbc:sqlserver://localhost:1433;DatabaseName=MyDB";
// 用戶名
private static final String user = "sa";
// 密碼
private static final String password = "sqlpass";
// 在靜態塊中完成驅動的加載
// 靜態塊中的業務邏輯在類加載器加載類的時候執行
// 只會執行一次
static {
try {
Class.forName(driver);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
protected Connection conn;
protected PreparedStatement pstmt;
protected ResultSet rs;
// 該函數負責創建Connection對象
protected void getConnection() {
if (conn == null) {
try {
conn = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
protected void getPreparedStatement(String sql) {
if (conn == null) {
getConnection();
}
try {
pstmt = conn.prepareStatement(sql);
} catch (SQLException e) {
e.printStackTrace();
}
}
// 該函數適合沒有佔位符的查詢語句
protected void getResultSet(String sql) {
if (pstmt == null) {
getPreparedStatement(sql);
}
try {
rs = pstmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void close() {
if (rs != null) {
try {
rs.close();
rs = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if (pstmt != null) {
try {
pstmt.close();
pstmt = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
conn = null;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
dao層實例接口–IBookDao.java
package dao;
import java.util.ArrayList;
import entity.Book;
public interface IBookDao {
public ArrayList<Book> queryBooksByPublihser(String publisher);
}
dao層接口實現 \impl\BookDaoImpl.java–
package dao.impl;
import dao.BaseDao;
import entity.Book;
import dao.IBookDao;
import java.sql.SQLException;
import java.util.ArrayList;
public class BookDaoImpl extends BaseDao implements IBookDao {
@Override
public ArrayList<Book> queryBooksByPublihser(String publisher) {
ArrayList<Book> bookList = new ArrayList<Book>();
String sql = "select * from tbook where publisher=?";
getPreparedStatement(sql);
try {
pstmt.setString(1, publisher);
rs = pstmt.executeQuery();
/*循環讀取數據*/
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
String author = rs.getString("author");
String publisherval = rs.getString("publisher");
int price = rs.getInt("price");
Book book = new Book(id, name, author, publisherval, price);
bookList.add(book);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 釋放連接資源
close();
}
/*返回bookList*/
return bookList;
}
}
本文精華Mark:線程池 – datasource\ThreadLocalData.java
package datasource;
import dao.*;
import service.*;
public class ThreadLocalData {
//與控制層相連,靜態對象
public static ThreadLocal<IBookService> threadLocalBookService = new ThreadLocal<IBookService>();
//與業務邏輯層相連,靜態對象
public static ThreadLocal<IBookDao> threadLocalBookDao = new ThreadLocal<IBookDao>();
}
業務邏輯層service – IBookService接口
package service;
import java.util.ArrayList;
import entity.Book;
public interface IBookService {
public ArrayList<Book> queryBooksByPublihser(String publisher);
}
本文精華Mark:業務邏輯層service – BookServiceImpl接口的實現
package service.impl;
import java.util.ArrayList;
import dao.IBookDao;
import dao.impl.BookDaoImpl;
import datasource.ThreadLocalData;
import entity.Book;
import service.IBookService;
public class BookServiceImpl implements IBookService {
@Override
public ArrayList<Book> queryBooksByPublihser(String publisher) {
IBookDao bookDao;
//在線程池中獲取key-value的鍵值,不存在新建threadLocal對象
if (ThreadLocalData.threadLocalBookDao.get() == null) {
bookDao = new BookDaoImpl();
ThreadLocalData.threadLocalBookDao.set(bookDao);
}
//從threadLocal對象中取值
bookDao = ThreadLocalData.threadLocalBookDao.get();
//返回BookList列表
return bookDao.queryBooksByPublihser(publisher);
}
}
本文精華Mark:控制層control control\BookServlet.java
package control;
import java.awt.print.Book;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import datasource.ThreadLocalData;
import service.IBookService;
import service.impl.BookServiceImpl;
@SuppressWarnings("serial")
public class BookServlet extends HttpServlet {
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/*中文編碼UTF-8*/
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=utf-8");
PrintWriter out = response.getWriter();
String publisher = request.getParameter("publisher");
/*Book接口對象service*/
IBookService bookService;
/*如果線程池中找不到實例對象,則新建*/
if (ThreadLocalData.threadLocalBookService.get() == null) {
bookService = new BookServiceImpl();
ThreadLocalData.threadLocalBookService.set(bookService);
}
/*從線程池中取值*/
bookService = ThreadLocalData.threadLocalBookService.get();
/*bookService調用queryBookByPublisher方法後返回BookList列表*/
ArrayList<entity.Book> books = bookService.queryBooksByPublihser(publisher);
/*綁定對象*/
request.setAttribute("books", books);
/*重定向*/ request.getRequestDispatcher("/result.jsp").forward(request, response);
out.flush();
out.close();
}
}
result.jsp [JSTL庫]
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%
String path = request.getContextPath();
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";
%>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'result.jsp' starting page</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<style type="text/css">
div{
width:800px;
height: 600px;
margin:0 auto;
}
</style>
</head>
<body>
<div>
<h1>查詢結果</h1>
<table width="600px" border="1px">
<tr>
<td>ID</td>
<td>NAME</td>
<td>AUTHOR</td>
<td>PUBLISHER</td>
<td>PRICE</td>
</tr>
<c:forEach items="${requestScope.books}" var="book">
<tr>
<td>${book.id}</td>
<td>${book.name}</td>
<td>${book.author}</td>
<td>${book.publisher}</td>
<td>${book.price}</td>
</tr>
</c:forEach>
</table>
</div>
</body>
</html>
四:小結
1)服用方式:結合前篇博文一起服用,記得參考思維導圖,效果更佳;
2)有效日期:2XXX-XX-XX;
3)詳情諮詢:[email protected] 歡迎打擾;
4)版權所有:如有雷同,純屬巧合;
5)如何修改:如有更好的實現方法或者實例,請fork;
6)本人撰博純屬巧合;
7)如有不足之處,提出必改正;
8)後續內容:Ajax[異步js and xml]引擎訪問數據數內容;
9)附上層與層之間的邏輯圖[request,response],請參見下圖;