1、目的:学习Servlet、面向接口编程、工厂模式
2、开发环境:Ecplise(Java SE)、SQLyog数据库管理工具、Tomcat服务器
3、Tomcat安装要注意环境变量的设置
4、Ecplise项目中导入jar包:Window->Preferences->Java->Build Path->User Libraries->new->命名,如MyWebLib->点击MyWebLib,点击Add External JARs->导入Tomcat的lib目录下的servlet-api.jar和jsp-api.jar,再导入MySQL驱动包
5、添加导航器:Window->Show View->Navigator
6、构建工程(项目)目录结构——包设计
根据系统分层体系结构,我们可以设置
1)ui/WebRoot包:对应表现层,在这节课的例子中暂时不用
2)controller包:对应控制层,负责协调、调度业务逻辑层的功能方法。业务逻辑层提供的方法也许只是相对独立的基本功能,如果某项操作需要按一定顺序调用好几个基本的业务功能,控制器就能起到协调、调度的作用。在 JavaWeb应用中,Servlet通常就是承担控制器的作用。
3)business/service包:对应业务逻辑层,提供完成各项业务功能的方法。
4)dao 包:对应数据访问层,提供访问数据资源(如数据库、文件等)的方法。
5)entity/vo/pojo包:对应 Model层,实体类/值对象(ValueObject)/简单 Java对象(Plain Ordinary Java Object),封装了需要处理的业务数据,采用 JavaBean-style 定义
6)common包:通常是较底层的公共的服务(工具)类,比如特殊字符处理,数据源连接等。
7、分层设计——从底向上
新建工程时,将bin目录改名为classes
(一)、定义 entity类(JavaBean-style)
1)每个属性的访问权限都是 private
2)为每个属性提供 public的 setter和 getter
3)必须有不带参数的构造方法
/**
* entity包,对应Model层,简单Java对象
*/
package edu.gdut.imis.library.entity;
/**
* Book的实体类,封装了我们要处理的数据,采用JavaBean style来定义
*
* @author PC
*
*/
public class BookModel {
private String isbn; // 图书的分类编码
private String name; // 图书名称
private String author; // 图书作者
private float price; // 图书价格
public BookModel() {
}
public String getIsbn() {
return isbn;
}
public void setIsbn(String isbn) {
this.isbn = isbn;
}
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 float getPrice() {
return price;
}
public void setPrice(float price) {
this.price = price;
}
}
(二)、编写脚本在数据库中创建关系表
DROP DATABASE IF EXIST Library;
CREATE DATABASE Library;
USE Library;
CREATE TABLE Book_info(
isbn varchar(13) not null primary key,
name varchar(30) not null,
author varchar(20) not null,
publisher varchar(50) not null,
price float(6,2)
);
COMMIT;
(三)、在 common中定义连接数据库的公用类
/**
* common包,通常是较底层的公共的服务(工具)类,比如特殊字符处理,数据源连接等
*/
package edu.gdut.imis.library.common;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 连接数据库和应用程序
* @author PC
*
*/
public class DBConnector {
//返回数据库的连接对象
public static Connection getConn() throws SQLException{
/**
* 通过DriverManager得到数据库的连接对象,要用URL描述要连接的数据库
*/
//主协议jdbc:次要协议mysql://连接本地主机:默认的端口号3306/要连接的数据库名称
String url="jdbc:mysql://localhost:3306/library";
//用户名
String username="root";
//密码
String password="123456";
//加载驱动程序
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//通过DriverManager得到数据库的连接对象
Connection conn=DriverManager.getConnection(url,username,password);
//返回数据库的连接对象
return conn;
}
}
(四)、定义 DataAccessObject
1)定义 dao 包中的子包
idao:dao 接口
factory:dao 工厂,用于返回 dao 接口的实现类
impl:dao 接口的实现类
2)定义 dao 接口
/**
* dao包,对应数据访问层,提供访问数据资源(如数据库、文件等)的方法
*/
package edu.gdut.imis.library.dao.dai;
import java.util.List;
import edu.gdut.imis.library.entity.BookModel;
/**
* dao接口
* @author PC
*
*/
public interface IBaseDAO {
boolean create(BookModel bm); //增
boolean delete(String isbn); //删:根据图书编号来删除
boolean update(BookModel bm); //改
List findAll(); //查1:返回所有图书记录
BookModel findByIsbn(String isbn); //查2:根据图书编号来查找
}
3)定义 dao 接口实现类
package edu.gdut.imis.library.dao.dao;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import edu.gdut.imis.library.common.DBConnector;
import edu.gdut.imis.library.dao.dai.IBaseDAO;
import edu.gdut.imis.library.entity.BookModel;
/**
* dao接口的实现类
* @author PC
*
*/
public class BookDAO implements IBaseDAO{
@Override
public boolean create(BookModel bm){
Connection conn=null;
PreparedStatement pstmt=null;
try {
//1、获得数据库连接对象
conn=DBConnector.getConn();
//2、定义SQL语句的字符串描述
String sql="INSERT INTO book_info VALUES(?,?,?,?)";
//3、获得预编译SQL陈述对象
pstmt=conn.prepareStatement(sql);
//4、设置各占位符
pstmt.setString(1, bm.getIsbn());
pstmt.setString(2, bm.getName());
pstmt.setString(3, bm.getAuthor());
pstmt.setFloat(4, bm.getPrice());
//5、执行SQL语句
pstmt.execute();
} catch (SQLException e) {
e.printStackTrace();
} finally{
try {
pstmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return true;
}
@Override
public boolean delete(String isbn) {
return false;
}
@Override
public boolean update(BookModel bm) {
return false;
}
@Override
public List findAll() {
Connection conn=null;
//这里可以用静态的SQL陈述对象,因为查询是不变化的
Statement stmt=null;
//用来存放返回的书的集合
List list=new ArrayList();
BookModel bm=null;
try {
conn=DBConnector.getConn();
String sql="select * from book_info";
stmt=conn.createStatement();
ResultSet rs=stmt.executeQuery(sql);
while(rs.next()){
//取出一条记录,生成一个BookModel的实例对象
bm=new BookModel();
//将结果集第1列数值设为编号
bm.setIsbn(rs.getString(1));
//第2列数值设为名称
bm.setName(rs.getString(2));
//第3列设为作者
bm.setAuthor(rs.getString(3));
//第4列设为价格
bm.setPrice(rs.getFloat(4));
//将BookModel对象添加到list列表中
list.add(bm);
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
try {
stmt.close();
} catch (SQLException e1) {
e1.printStackTrace();
}
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return list;
}
@Override
public BookModel findByIsbn(String isbn) {
return null;
}
}
4)定义 dao 工厂 factory
package edu.gdut.imis.library.dao.factory;
import edu.gdut.imis.library.dao.dao.BookDAO;
/**
* dao工厂,用于返回dao接口的实现类
* @author PC
*
*/
public class DAOFactory {
public static BookDAO getBookDAO(){
return new BookDAO();
}
}
(五).定义业务逻辑层,业务逻辑层也分为
1)ebi : 业务逻辑层接口
package edu.gdut.imis.library.business.ebi;
import java.util.List;
import edu.gdut.imis.library.entity.BookModel;
/**
* 业务逻辑层接口ebi
* @author PC
*
*/
public interface BookEBI {
boolean create(BookModel bm); //增
boolean delete(String isbn); //删:根据图书编号来删除
boolean update(BookModel bm); //改
List findAll(); //查1:返回所有图书记录
BookModel findByIsbn(String isbn); //查2:根据图书编号来查找
void sortByIsbn(); //按图书编号进行排序
}
2)ebo : ebi 的实现类
package edu.gdut.imis.library.business.ebo;
import java.util.List;
import edu.gdut.imis.library.business.ebi.BookEBI;
import edu.gdut.imis.library.dao.dai.IBaseDAO;
import edu.gdut.imis.library.dao.factory.DAOFactory;
import edu.gdut.imis.library.entity.BookModel;
/**
* ebi的实现类
* @author PC
*
*/
public class BookEBO implements BookEBI{
//业务逻辑层的功能:通过调用数据访问层的功能实现
@Override
public boolean create(BookModel bm) {
IBaseDAO bdao=DAOFactory.getBookDAO();
return bdao.create(bm);
}
@Override
public boolean delete(String isbn) {
return false;
}
@Override
public boolean update(BookModel bm) {
return false;
}
@Override
public List findAll() {
IBaseDAO bdao=DAOFactory.getBookDAO();
List list=bdao.findAll();
return list;
}
@Override
public BookModel findByIsbn(String isbn) {
return null;
}
@Override
public void sortByIsbn() {
}
}
3)factory : 生产 ebo 的工厂
package edu.gdut.imis.library.business.factory;
import edu.gdut.imis.library.business.ebo.BookEBO;
/**
* 生产ebo的工厂
* @author PC
*
*/
public class EBOFactory {
public static BookEBO getBookEBO(){
return new BookEBO();
}
}
(六)、定义控制器(controller),即 Servlet
package edu.gdut.imis.library.controller;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import edu.gdut.imis.library.business.factory.EBOFactory;
import edu.gdut.imis.library.entity.BookModel;
public class BookServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req, resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String submitFlag=req.getParameter("submitFlag");
if("add".equals(submitFlag)){
//若插入成功
if(this.add(req)){
List list=EBOFactory.getBookEBO().findAll();
//设置响应的MIME类型
resp.setContentType("text/html;charset=utf-8");
PrintWriter out=resp.getWriter();
//拼HTML页面
out.print("");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("");
out.print("ISBN ");
out.print("书名 ");
out.print("作者 ");
out.print("价格 ");
out.print(" ");
for(int i=0;i
out.print("");
out.print(""+list.get(i).getIsbn()+" ");
out.print(""+list.get(i).getName()+" ");
out.print(""+list.get(i).getAuthor()+" ");
out.print(""+list.get(i).getPrice()+" ");
out.print(" ");
}
out.print("
");
out.print("");
out.print("");
}
}
}
//收集请求的数据,创建BookModel的实例,并设置其属性
private boolean add(HttpServletRequest req){
BookModel bm=new BookModel();
bm.setIsbn(req.getParameter("isbn"));
bm.setName(req.getParameter("name"));
bm.setAuthor(req.getParameter("author"));
String priceStr=req.getParameter("price");
float price=Float.parseFloat(priceStr);
bm.setPrice(price);
//调用业务逻辑层的工厂,获得业务层的处理对象,获得新增方法
return EBOFactory.getBookEBO().create(bm);
}
}
(七)、点击Eclipse窗格中的Project,勾选“Build Automatically”,保存java文件,classes目录会出现编译后的.class文件。到Tomcat目录下,进入webapps目录,新建一个文件夹LibraryMIS,将ROOT目录下的WEB-INF复制到LibraryMIS目录下,再将Ecplise中LibraryMIS项目的classes包整个复制到Tomcat->webapps->LibraryMIS->WEB-INF目录下,修改该目录下的web.xml文件,配置Servlet。
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
version="3.1"
metadata-complete="true">
<servlet>
<servlet-name>BookServletservlet-name>
<servlet-class>edu.gdut.imis.library.controller.BookServletservlet-class>
servlet>
<servlet-mapping>
<servlet-name>BookServletservlet-name>
<url-pattern>/lxcurl-pattern>
servlet-mapping>
web-app>
(八)写 add.html页面
<html>
<head>
<meta charset="utf-8"/>
head>
<body>
<form action="/LibraryMIS/lxc" method="post">
<input type="hidden" name="submitFlag" value="add"/>
<table align="center" width="20%">
<tr>
<td colspan="3" align="center">新增图书td>
tr>
<tr>
<td align="right">ISBN:td>
<td><input type="text" name="isbn"/>td>
tr>
<tr>
<td align="right">书名:td>
<td><input type="text" name="name"/>td>
tr>
<tr>
<td align="right">作者:td>
<td><input type="text" name="author"/>td>
tr>
<tr>
<td align="right">价格:td>
<td><input type="text" name="price"/>td>
tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="保存"/> <input type="reset" value="重置"/>td>
tr>
table>
form>
body>
html>
(九)、运行程序
启动Tomcat->bin->startup.bat,在浏览器地址栏输入“http://127.0.0.1:8080/LibraryMIS/add.html”,回车:
填入图书信息:
点击“保存”,这里显示了保存的图书信息:
再保存一本图书:
点击保存,可以看到之前保存的图书也被记录着:
本文只完成了增加图书的功能,其余的功能有空再补上。