现在,我们对着浏览器,打开这个图书管理系统的页面,或者打开admin/product/add.jsp,通过里面的字段,我们可以参照这些name的值去创建数据库表,表的名称就是book。
1.数据库表的创建
CREATE TABLE book(
id VARCHAR(50) PRIMARY KEY,
NAME VARCHAR(50),
price DOUBLE,
pnum INT,
category VARCHAR(30),
description VARCHAR(200)
);
数据库你需要本地提前安装MySQL,并创建一个数据库,然后进入这个数据库,执行以上创建表的语句,这样我们book表就创建好 。接下来,我们来插入两条数据。
INSERT INTO book VALUES('123fndc23','Java编程思想',78.9,500,'编程语言','Java从业人员的圣经,实在是一本好书');
INSERT INTO book VALUES('adc2345kid','西游记',34.9,800,'文学艺术','几乎每个人小时候都看过这本书的动画片');
2.把c3p0文件复制
前一篇我们提前拷贝好相关的jar包,现在这里,我们把c3p0的拷贝过来。
这里再贴一次上面的代码
<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
<default-config>
<property name="driverClass">com.mysql.jdbc.Driver</property>
<property name="jdbcUrl">jdbc:mysql://localhost:3306/javaweb</property>
<property name="user">root</property>
<property name="password">123456</property>
<property name="initialPoolSize">10</property>
<property name="maxPoolSize">30</property>
<property name="minPoolSize">10</property>
</default-config>
</c3p0-config>
把数据库改成前面一篇创建book表的数据库
package com.anthony.datasource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mchange.v2.c3p0.ComboPooledDataSource;
public class C3P0Utils {
private static ComboPooledDataSource dataSource = new ComboPooledDataSource();
public static ComboPooledDataSource getDataSource() {
return dataSource;
}
public static Connection getConnection() {
try {
return dataSource.getConnection();
} catch (SQLException e) {
e.printStackTrace();
throw new ExceptionInInitializerError("初始化失败,请检查配置文件");
}
}
public static void release(Connection conn, Statement stmt, ResultSet rs) {
if(rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
rs = null; //赶紧垃圾回收
}
if(stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
3.商品列表显示思路分析
启动服务,打开浏览器,我们点击左侧的 商品查看菜单,右侧可以显示列表。
从效果上来看,我们在left.jsp页面点击一个按钮,这个按钮就是商品查看,然后里面就直接在list.jsp上显示。但是我们分析一下,这么做对不对,我们前面学了MVC模型,知道要分层开发,有Servlet层,有Service层,有Dao层,所以我们分析显示列表的思路应该像下面这张图这样。
在left.jsp和list.jsp之间,我们需要添加一个Servlet来控制,对应有Service层,还有Dao层,Dao负责和数据库读取数据,然后返回数据,例如一个集合方式返回到Servlet,然后通过request对象,把这个集合传给list.jsp页面,在list.jsp页面可以通过for each拿到这些图书,显示出列表。
4.创建Bean对象
很明显,这里我们Bean对象就是Book.java,然后根据数据表字段写属性,生成set和get方法。
package com.anthony.domain;
public class Book implements Serializable {
private String id;
private String name;
private double price;
private int pnum;
private String category;
private String description;
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 double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public int getPnum() {
return pnum;
}
public void setPnum(int pnum) {
this.pnum = pnum;
}
public String getCategory() {
return category;
}
public void setCategory(String category) {
this.category = category;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
}
这里我们还是实现序列号接口,因为Book也有可能添加到购物车,只要添加到购物车,就要序列化。
5.Dao层
还是和前面分层习惯,一个包下写一个接口和一个实现接口的类。
package com.anthony.dao;
import java.sql.SQLException;
import java.util.List;
import com.anthony.domain.Book;
public interface BookDao {
/**
* 查询所有书
* @return
* @throws SQLException
*/
public List<Book> findAllBooks() throws SQLException;
}
然后写实现接口的具体类
package com.anthony.dao;
import java.sql.SQLException;
import java.util.List;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;
import com.anthony.datasource.C3P0Utils;
import com.anthony.domain.Book;
public class BookDaoImpl implements BookDao {
public List<Book> findAllBooks() throws SQLException {
QueryRunner qr = new QueryRunner(C3P0Utils.getDataSource());
List<Book> query = qr.query("select * from book", new BeanListHandler<Book>(Book.class));
return query;
}
}
接下来该写Service层了
6.Service层
Service层接口
package com.anthony.service;
import java.util.List;
import com.anthony.domain.Book;
public interface BookService {
public List<Book> findAllBooks();
}
实现类
package com.anthony.service;
import java.sql.SQLException;
import java.util.List;
import com.anthony.dao.BookDao;
import com.anthony.dao.BookDaoImpl;
import com.anthony.domain.Book;
public class BookServiceImpl implements BookService {
//创建一个Dao对象
BookDao bd = new BookDaoImpl();
public List<Book> findAllBooks() {
try {
return bd.findAllBooks();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
}
7.Servlet层
首先,这里修改前端代码中/admin/login/left.jsp中点击商品查看按钮,跳转到BookListServlet
//子目录添加
d.add(11,1,'商品查看','${pageContext.request.contextPath}/bookListServlet','','mainFrame');
对应的web.xml是这样
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" id="WebApp_ID" version="2.5">
<display-name>BookManger</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<servlet>
<description></description>
<servlet-name>bookListServlet</servlet-name>
<servlet-class>com.anthony.web.servlet.BookListServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>bookListServlet</servlet-name>
<url-pattern>/bookListServlet</url-pattern>
</servlet-mapping>
</web-app>
然后开始写BookListServlet.java的代码
package com.anthony.web.servlet;
import java.io.IOException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.anthony.domain.Book;
import com.anthony.service.BookService;
import com.anthony.service.BookServiceImpl;
public class BookListServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
//调用业务逻辑
BookService bs = new BookServiceImpl();
List<Book> books = bs.findAllBooks();
//跳转页面
if(books != null) {
request.setAttribute("books", books); //把books这个list集合放入request对象中
request.getRequestDispatcher("/admin/products/list.jsp").forward(request, response);
}
}
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
doGet(request, response);
}
}
下面就是处理/admin/products/list.jsp中如何拿到List<Book>
8.list.jsp如何获取集合对象
在7步骤中,我们把list<Book>对象放到了request域中,现在这我们需要在admin/products/list.jsp如何拿到这个集合。
在list.jsp中122和149行插入foreach标签
<c:forEach items="${books }" var="b">
<tr onmouseover="this.style.backgroundColor = 'white'"
onmouseout="this.style.backgroundColor = '#F5FAFE';">
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="23">1</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="18%">java编程思想</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="8%">1200</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="8%">100</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center">计算机</td>
<td align="center" style="HEIGHT: 22px" width="7%"><a
href="${pageContext.request.contextPath}/admin/products/edit.jsp">
<img
src="${pageContext.request.contextPath}/admin/images/i_edit.gif"
border="0" style="CURSOR: hand"> </a>
</td>
<td align="center" style="HEIGHT: 22px" width="7%"><a
href="#">
<img
src="${pageContext.request.contextPath}/admin/images/i_del.gif"
width="16" height="16" border="0" style="CURSOR: hand">
</a>
</td>
</tr>
</c:forEach>
在插入之前,数据是写死,并没有从数据库中获取,而且不知道有多少条结果,tr的数量也不能写死。然后把上面写死的id,name,price,pnum,category全部用变量b去获取。
<c:forEach items="${books }" var="b">
<tr onmouseover="this.style.backgroundColor = 'white'"
onmouseout="this.style.backgroundColor = '#F5FAFE';">
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="23">${b.id}</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="18%">${b.name}</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="8%">${b.price}</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center"
width="8%">${b.pnum}</td>
<td style="CURSOR: hand; HEIGHT: 22px" align="center">${b.category}</td>
<td align="center" style="HEIGHT: 22px" width="7%"><a
href="${pageContext.request.contextPath}/admin/products/edit.jsp">
<img
src="${pageContext.request.contextPath}/admin/images/i_edit.gif"
border="0" style="CURSOR: hand"> </a>
</td>
<td align="center" style="HEIGHT: 22px" width="7%"><a
href="#">
<img
src="${pageContext.request.contextPath}/admin/images/i_del.gif"
width="16" height="16" border="0" style="CURSOR: hand">
</a>
</td>
</tr>
</c:forEach>
重启tomcat
9.联调测试
重启之后,刷新浏览器,点击商品查看菜单,效果是这样的,这个和我们mysql中表的数据是一样的。
下面我们在数据库手动插入一本叫python的书籍,然后刷新浏览器看看。
浏览器刷新后,查询列表显示如下