hibernate 結合servlet及 jsp 的使用


Hibernate結合JSP使用

前面幾章詳細的介紹了Hibernate的相關知識,這一章介紹Hibernate結合JSPServlet的使用,通過這一章的學習,可以加深對Hibernate的理解。

本章使用的開發工具是MyEclipse5.5,服務器是Tomcat6.0,數據庫是MySQL5.1,本章所有例子源代碼見光盤第14章的工程hibernate_jsp

14.1 搭建Hibernate框架

使用Hibernate進行開發之前,需要先搭建Hibernate框架,Hibernate框架的搭建在前面已經介紹過。新建一個Web工程,工程名為hibernate_jsp。把連接MySQL數據庫的jar包、Hibernate所需的jar包和JSTL標簽庫的jar包拷貝到該工程的WebRoot/WEB-INF/lib目錄下。在MyEclipse中把工程hibernate_jsp發布到Tomcat服務器中。

14.1.1 創建數據庫表

為了使例子簡單易懂,創建數據庫表時,表字段很少。本章的例子只需兩張表,一張部門表和一張員工表。部門表的建表語句如下:

-- Table "dept" DDL

CREATE TABLE dept (

depno int(11) NOT NULL AUTO_INCREMENT,

depname varchar(255) DEFAULT NULL,

PRIMARY KEY (depno)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=gb2312;

部門表的主鍵設置成自動增長。部門表和員工表是一對多的關系,所以在員工表中,部門表的主鍵作為員工表的外鍵,員工表的主鍵設置成自動增長。員工表的建表語句如下:

-- Table "emp" DDL

CREATE TABLE emp (

empno int(11) NOT NULL AUTO_INCREMENT,

empname varchar(255) DEFAULT NULL,

depno int(11) DEFAULT NULL,

PRIMARY KEY (empno),

KEY FK188C86CDD0E0B (depno),

CONSTRAINT FK188C86CDD0E0B FOREIGN KEY (depno) REFERENCES dept (depno)

) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=gb2312;

14.1.2 編寫數據庫表對應的實體類和映射文件

數據庫表對應的實體類和實體類映射文件可以使用MyEclipse的向導來自動生成,也可以手動編寫。這里使用MyEclipse的向導來自動生成。部門表對應的實體類Dept源代碼如下:

package com.cn.vo;

public class Dept implements java.io.Serializable {

// Fields

private Integer depno;

private String depname;

private Set emps = new HashSet(0);//對應的員工實體類

// Constructors

public Dept() {

}

public Dept(Integer depno) {

this.depno = depno;

}

public Dept(Integer depno, String depname, Set emps) {

this.depno = depno;

this.depname = depname;

this.emps = emps;

}

//這里省略了settgetter方法

}

Dept類中有3個屬性depnodepname對應數據庫表的字段。Set集合對應的是一對多的多方,這里是員工實體類。Dept類的對應的映射文件和實體類在同一包下,代碼如下:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!--

Mapping file autogenerated by MyEclipse Persistence Tools

-->

<hibernate-mapping>

<class name="com.cn.vo.Dept" table="dept" catalog="bank">

<id name="depno" type="java.lang.Integer">

<column name="depno" />

<generator class="native" />

</id>

<property name="depname" type="java.lang.String">

<column name="depname" />

</property>

<set name="emps" inverse="true">

<key>

<column name="depno" />

</key>

<one-to-many class="com.cn.vo.Emp" /><!-- 一對多關系映射 -->

</set>

</class>

</hibernate-mapping>

員工實體類是一對多關系中的多方,在員工表對應的實體類中要聲明一方的對象(這里是Dept類對象),員工表對應的實體類Emp代碼如下:

package com.cn.vo;

public class Emp implements java.io.Serializable {

// Fields

private Integer empno;

private Dept dept;//部門實體類對象

private String empname;

// Constructors

public Emp() {

}

public Emp(Integer empno) {

this.empno = empno;

}

public Emp(Integer empno, Dept dept, String empname) {

this.empno = empno;

this.dept = dept;

this.empname = empname;

}

//這里省略了settergetter方法

}

用個實體類中有3個成員變量,empnoempname是數據庫表這段對應的屬性。Dept是員工表外鍵對應的屬性,是一對多關系映射中的一方。Emp類對應的映射文件和實體類在同一包下,代碼如下:

<?xml version="1.0" encoding="utf-8"?>

<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<!--

Mapping file autogenerated by MyEclipse Persistence Tools

-->

<hibernate-mapping>

<class name="com.cn.vo.Emp" table="emp" catalog="bank">

<id name="empno" type="java.lang.Integer">

<column name="empno" />

<generator class="native" />

</id>

<!-- 多對一的關系映射 -->

<many-to-one name="dept" class="com.cn.vo.Dept" fetch="select">

<column name="depno" />

</many-to-one>

<property name="empname" type="java.lang.String">

<column name="empname" />

</property>

</class>

</hibernate-mapping>

14.1.3 編寫Hibernate的配置文件

這個例子中使用XML文件來作為Hibernate的配置文件,文件名為hibernate.cfg.xml,在該文件中配置數據庫連接和實體類映射文件,配置文件在src的跟目錄下,代碼如下:

<?xml version='1.0' encoding='UTF-8'?>

<!DOCTYPE hibernate-configuration PUBLIC

"-//Hibernate/Hibernate Configuration DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<!-- Generated by MyEclipse Hibernate Tools. -->

<hibernate-configuration>

<session-factory>

<!-- 連接數據庫的配置 -->

<property name="connection.username">root</property>

<property name="connection.url">jdbc:mysql://localhost:3306/bank</property>

<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<property name="myeclipse.connection.profile">com.mysql.jdbc.Driver</property>

<property name="connection.password">root</property>

<property name="connection.driver_class">com.mysql.jdbc.Driver</property>

<!-- 實體類的映射文件 -->

<mapping resource="com/cn/vo/Dept.hbm.xml"/>

<mapping resource="com/cn/vo/Emp.hbm.xml"/>

</session-factory>

</hibernate-configuration>

14.1.4 編寫HibernateSessionFactory

HibernateSessionFactory類是原來初始化Hibernate的,使用Hibernate開發時,必須編寫該類。在類中編寫如下代碼(這里省略了import的內容):

package com.cn.factory;

public class HibernateSessionFactory {

private static Configuration cf = null;

private static SessionFactory sf = null;

static{

try {

cf = new Configuration().configure();

sf = cf.buildSessionFactory();//創建session

} catch (HibernateException e) {

throw new RuntimeException("SessionFactory創建失敗",e);

}

}

public static Session getSession(){//獲得session的方法

Session session = null;

try {

if (session==null||session.isOpen()==false)

session = null;

session = sf.openSession();

} catch (HibernateException e) {

throw new RuntimeException("Session創建失敗",e);

}

return session;

}

public static void closed(Session session){//關閉session的方法

try {

if(session!=null)

session.close();

} catch (HibernateException e) {

throw new RuntimeException("Session關閉失敗",e);

}

}

public static void main(String[] args) {//測試方法

getSession();

}

}

14.2 操作員工表

部門表的主鍵作為員工表的外鍵,所以在添加員工信息時,對應的部門信息要存在,否則拋出異常。這一節將介紹對員工表的增刪改查操作。

14.2.1 添加員工信息

在添加員工信息之前,首先在MySQL的控制台中或者客戶端工具中,往部門表中添加幾條數據。添加員工信息的頁面為addEmp.jsp,代碼如下(這里省略了htmlheadbody標簽,用省略號代替)

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

……

<form action="AddEmpServlet" method="post">

<table>

<tr>

<td>員工姓名</td>

<td><input type="text" name="ename"></td>

</tr>

<tr><td>部門編號</td>

<td><input type="text" name="depno"></td>

</tr>

</table>

<input type="submit" value="提交">

<input type="reset" value="重置">

</form>

……

上述代碼中,from表單提交到AddEmpServlet中,使用post提交方式。頁面中有連個文本框,員工編號是自動增長的,所以不用添加。AddEmpServlet的代碼如下(這里省略了import的內容)

package com.cn.service;

public class AddEmpServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

String empname = request.getParameter("ename");//獲得頁面傳遞過來的數據

int depno = Integer.parseInt(request.getParameter("depno"));//獲得頁面傳遞過來的數據

Emp emp = new Emp();

Dept dept = new Dept();

dept.setDepno(depno);//depno設置到dept對象中

emp.setEmpname(empname);//empname設置到emp對象中

emp.setDept(dept);//dept設置到emp對象中

EmpDao dao = new EmpDaoImp();

dao.addEmp(emp);//調用實現類的的添加方法

response.sendRedirect("ShowAllEmpServlet");//重定向到顯示全部的Servlet

out.flush();

out.close();

}

}

編寫好Servlet以后,需要在WebRoot/WEB-INF/web.ml文件中配置Servlet信息。上述代碼中有這樣一行代碼:

EmpDao dao = new EmpDaoImp();

其中EmpDao是一個接口,EmpDaoImp是接口實現類。這一行代碼是接口實現類的對象指向接口的引用。接口類EmpDao中代碼如下:

package com.cn.dao;

import java.util.List;

import com.cn.vo.Emp;

public interface EmpDao {

public void addEmp(Emp emp);//添加數據的方法

}

在接口實現類EmpDaoImp中實現addEmp方法。EmpDaoImp類的代碼如下(這里省略了import的內容):

package com.cn.dao.imp;

public class EmpDaoImp implements EmpDao {

Session session = HibernateSessionFactory.getSession();//獲得session

Transaction tr = session.beginTransaction();//開啟事務

public void addEmp(Emp emp) {

session.save(emp);//添加數據

tr.commit();//提交事務

}

}

為了防止添加到數據庫中的數據出現中文亂碼,需要編寫一個處理中文亂碼的過濾器,過濾器的代碼如下:

package com.cn.fileter;

import java.io.IOException;

import javax.servlet.*;

public class ChinaFilter implements Filter {

public void destroy() {

// TODO Auto-generated method stub

}

public void doFilter(ServletRequest request, ServletResponse response,

FilterChain chain) throws IOException, ServletException {

request.setCharacterEncoding("gb2312");//設置request的編碼方式為gb2312

response.setCharacterEncoding("gb2312");//設置response的編碼方式為gb2312

chain.doFilter(request, response);//提交處理

}

public void init(FilterConfig arg0) throws ServletException {

// TODO Auto-generated method stub

}

}

編寫好這些代碼以后,就可以正確的添加數據了。添加員工信息成功以后,頁面跳轉到ShowAllEmpServlet,所以添加數據的演示,放到顯示全部員工信息部分一起演示。

14.2.2 顯示全部員工信息

添加員工信息成功以后,頁面跳轉到ShowAllEmpServlet,該類是一個Servlet,用來顯示全部員工信息,ShowAllEmpServlet的代碼如下(這里省略了import的內容)

package com.cn.service;

public class ShowAllEmpServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

List<Emp> list = new ArrayList<Emp>();

EmpDao dao = new EmpDaoImp();

list = dao.queryAllEmp();//調用實現類的查詢全部方法

request.setAttribute("list", list);//把查詢結果放入request對象中

request.getRequestDispatcher("showAllEmp.jsp").forward(request, response);//轉發到現實全部的頁面

out.flush();

out.close();

}

}

上述代碼中要在doGet方法中調用doPost方法,因為當頁面跳轉到Servlet中沒有特別說明,會進入doGet方法中。在doPost方法中調用了接口實現類EmpDaoImp的查詢全部方法queryAllEmp()方法。在接口EmpDao類中添加如下一行代碼:

public List<Emp> queryAllEmp();//查詢全部數據的方法

在接口實現類EmpDaoImp類中實現queryAllEmp()方法,實現類EmpDaoImpqueryAllEmp()方法的代碼如下:

public List<Emp> queryAllEmp() {

List<Emp> list =session.createQuery("from Emp").list();//查詢全部

tr.commit();//提交事務

return list;

}

ShowAllEmpServlet中把查詢到的全部數據放入List集合中,再把List集合對象放入request對象中。然后轉發到顯示全部員工信息的頁面showAllEmp.jspshowAllEmp.jsp頁面的代碼如下(這里省略了htmlheadbody標簽,用省略號代替):

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

……

<table border="1">

<tr>

<td>員工編號</td>

<td>員工姓名</td>

<td>員工所在部門</td>

<td>操作</td>

</tr>

<c:forEach var="list" items="${list}">

<tr>

<td>${list.empno }</td>

<td>${list.empname }</td>

<td>${list.dept.depname }</td>

<td>

<a href="QueryEmpById?empno=${list.empno }">修改</a>

<a href="DeleteEmpById?empno=${list.empno }">刪除</a>

</td>

</tr>

</c:forEach>

</table>

……

MyEclipse中啟動Toncat服務器,在IE瀏覽器的地址橫縱中輸入地址:“http://localhost:8080/hibernate_jsp/addEmp.jsp”,頁面效果如圖14.1所示。

Hibernate結合JSP使用<轉載>

14.1 添加員工頁面

在圖14.1所示的頁面中輸入員工姓名和閉門編號以后,單擊“提交”按鈕,數據添加成功以后進入圖14.2所示的頁面。

Hibernate結合JSP使用<轉載>

14.2 顯示全部員工信息頁面

在圖14.2所示的頁面中,顯示了全部員工信息,同時提供了修改和刪除的操作。接下來介紹修改和刪除操作。

14.2.3 修改員工信息

修改數據的流程是:在頁面通過超鏈接跳轉顯示單條數據信息的頁面,在顯示單條數據信息的頁面中修改需要修改的數據,然后提交,把修改的數據提交到數據庫中。然后再次跳轉到顯示全部員工信息的頁面。

在圖14.2所示的頁面中,點擊“修改”插連接時,傳遞員工編號參數進入根據編號查詢的Servlet中(這里是QueryEmpById)。QueryEmpById的代碼如下(這里省略import的內容):

package com.cn.service;

public class QueryEmpById extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

int empno = Integer.parseInt(request.getParameter("empno"));//獲得頁面傳遞的參數

Emp emp = new Emp();

EmpDao dao = new EmpDaoImp();

emp = dao.queryEmpById(empno);//調用實現類中根據id查詢的方法

request.setAttribute("emp", emp);//把獲得的對象放入request對象中

//轉發到現實單條記錄的頁面

request.getRequestDispatcher("showEmpById.jsp").forward(request, response);

out.flush();

out.close();

}

}

上述代碼中,在doGet()方法中調用doPost()方法,Servlet默認的進入的是doGet()方法,所以要在doGet()方法中調用doPost()方法。在doPost()方法中調用了實現類EmpDaoImp中的queryEmpById()方法。所以在接口EmpDao類中添加如下一行代碼:

public Emp queryEmpById(int id);//根據id查詢的方法

在實現類EmpDaoImp中要實現queryEmpById(int id)方法,所以在EmpDaoImp中編寫queryEmpById(int id)方法,queryEmpById(int id)方法代碼如下:

public Emp queryEmpById(int id) {

Emp emp = new Emp();

emp = (Emp) session.load(Emp.class, id);//根據id查詢

return emp;

}

查詢出數據以后,把數據放入request對象中,頁面轉發到顯示單條記錄的頁面showEmpById.jspshowEmpById.jsp頁面的代碼如下(這里省略了htmlheadbody標簽,用省略號代替)

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

……

<form action="UpdateEmpServlet" method="post">

<table>

<tr>

<td>員工編號</td>

<td><input type="text" name="empno" value="${emp.empno }" readonly="readonly"></td>

</tr>

<tr>

<td>員工姓名</td>

<td><input type="text" name="ename" value="${emp.empname }"></td>

</tr>

<tr><td>部門編號</td>

<td><input type="text" name="depno" value="${emp.dept.depno }"></td>

</tr>

</table>

<input type="submit" value="提交">

<input type="reset" value="重置">

</form>

……

上述代碼中,form表單提交到UpdateEmpServletUpdateEmpServlet是一個修改數據的ServletUpdateEmpServlet的代碼如下(這里省略了import的內容):

package com.cn.service;

public class UpdateEmpServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

int empno = Integer.parseInt(request.getParameter("empno"));//獲得頁面傳遞過來的參數

String empname = request.getParameter("ename");//獲得頁面傳遞過來的參數

int depno = Integer.parseInt(request.getParameter("depno"));//獲得頁面傳遞過來的參數

Dept dept = new Dept();

Emp emp = new Emp();

dept.setDepno(depno);//設置depnoDept的對象中

emp.setDept(dept);//設置deptEmp對象中

emp.setEmpname(empname);//設置empnameEmp對象中

emp.setEmpno(empno);//設置empnoEmp對象中

EmpDao dao = new EmpDaoImp();

dao.updateEmp(emp);//調用實現類的修改方法

response.sendRedirect("ShowAllEmpServlet");//重定向到查詢全部的Servlet

out.flush();

out.close();

}

}

Servlet中的doGet方法調用doPost方法,修改的業務處理在doPost方法中處理。在doPost方法中,獲得頁面傳遞過來的數據以后,把數據設置到相應的對象中,調用了接口實現類EmpDaoImp中的修改方法。在接口EmpDao中添加修改方法updateEmp()方法,代碼如下:

public void updateEmp(Emp emp);//修改數據的方法

在接口實現類EmpDaoImp中實現修改的方法,修改數據的方法updateEmp()方法的代碼如下:

public void updateEmp(Emp emp) {

session.update(emp);//修改

tr.commit();//提交事務

}

要修改數據,需要在顯示全部數據的頁面中,點擊修改超鏈接進入修改數據頁面。啟動Tomcat服務器,在IE瀏覽器地址欄中輸入地址:“http://localhost:8080/hibernate_jsp/ShowAllEmpServlet”,在顯示全部數據的頁面中點擊一個修改超鏈接,進入圖14.3所示的頁面。

Hibernate結合JSP使用<轉載>

14.3 修改數據頁面

在圖14.3所示的頁面中,員工編號是只讀的,不能修改。員工姓名和閉門編號可以修改。輸入修改后的數據,提交表單。修改成功后,頁面跳轉到圖14.4所示的頁面。

Hibernate結合JSP使用<轉載>

14.4 修改成功后跳轉到顯示全部頁面

14.2.4 刪除員工信息

刪除員工信息的可以通過在圖14.4所示的頁面中點擊刪除超鏈接,進入刪除員工信息的Servlet,由Servlet調用刪除的方法,實現刪除員工信息的操作,刪除成功后,頁面跳轉到顯示全部員工信息的頁面。

刪除員工信息的Servlet——DeleteEmpById是處理刪除信息的ServletDeleteEmpById的代碼如下(這里省略了import的內容):

package com.cn.service;

public class DeleteEmpById extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

int empno = Integer.parseInt(request.getParameter("empno"));//獲得頁面傳遞的empno

EmpDao dao = new EmpDaoImp();

dao.deleteEmp(empno);//調用實現類中的查詢方法

response.sendRedirect("ShowAllEmpServlet");//重定向到顯示全部員工信息頁面

out.flush();

out.close();

}

}

DeleteEmpById類中的doGet方法中調用了doPost()方法,進入該Servlet時,默認進入的是doGet()方法,處理刪除的過程在doPost()方法中實現,該方法中調用了接口實現類中的刪除員工信息的方法,所以在接口EmpDao類中添加刪除員工信息的方法deleteEmp()方法,代碼如下:

public void deleteEmp(int id);//刪除數據的方法

在接口實現類EmpDaoImp中要實現deleteEmp()方法,deleteEmp()方法的代碼如下:

public void deleteEmp(int id) {

//使用Query對象來刪除

Query query = (Query) session.createQuery("delete Emp where empno=:id");

query.setParameter("id", id);

query.executeUpdate();//刪除

tr.commit();//提交事務

}

刪除員工信息的代碼都寫好以后,可以在顯示全部數據的頁面中刪除需要刪除的員工信息,啟動Tomcat服務器,在IE瀏覽器地址欄中輸入地址:“http://localhost:8080/hibernate_jsp/ShowAllEmpServlet”,效果如圖14.5所示。

Hibernate結合JSP使用<轉載>

14.5 刪除員工信息之前的頁面

在圖14.5所示的頁面中刪除應改變好為2的員工信息。員工編號為2的員工姓名是小張,所在部門是Java開發部。刪除該條數據以后,進入圖14.6所示的頁面。

Hibernate結合JSP使用<轉載>

14.6 刪除員工信息以后的頁面

在圖14.6所示的頁面中可以看到,員工編號為2的數據已經被刪除了,這說明刪除員工信息成功。這里的刪除是單表刪除,在下一節操作部門表中會講到級聯刪除。

14.3 操作部門表

部門表的主鍵作為員工表的外鍵,所在在刪除部門表信息的時候,需要級聯刪除員工表信息。本節中將介紹部門表信息的添加、查詢和刪除。修改操作和員工表的修改方法類似,這里就不再重復。

14.3.1 添加部門信息

添加部門信息時在頁面中輸入部門信息,提交表單后由后台處理添加業務。添加部門的頁面addDept.jsp代碼如下(這里省略了htmlheadbody標簽,用省略號代替)

<%@ page language="java" pageEncoding="gb2312"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

……

<form action="AddDeptServlet" method="post">

<table>

<tr>

<td>部門名稱</td>

<td><input name="deptName" type="text"></td>

</tr>

<tr>

<td><input type="submit" value="提交"></td>

<td><input type="reset" value="重置"></td>

</tr>

</table>

</form>

……

添加數據的表單提交到AddDeptServlet中,使用post方式提交表單內容。AddDeptServlet是處理添加數據層的ServletAddDeptServlet的代碼如下(這里省略了import的內容):

package com.cn.service;

public class AddDeptServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

response.setCharacterEncoding("gb2312");//設置response編碼方式

request.setCharacterEncoding("gb2312");//設置request編碼方式

String depname = request.getParameter("deptName");//獲得頁面傳遞過來的數據

Dept dept = new Dept();

dept.setDepname(depname);//把獲得的頁面數據設置到Dept對象中

DeptDao deptDao = new DeptDaoImp();

deptDao.addDept(dept);//調用實現類DeptDaoImpaddDept方法

response.sendRedirect("ShowAllDeptServlet");//頁面重定向到ShowAllDeptServlet

out.flush();

out.close();

}

}

上述代碼中,在doPost()方法中獲得頁面表單提交的數據,然后調用接口實現類DeptDaoImp中的addDept方法。首先編寫接口DeptDao類,代碼如下:

package com.cn.dao;

import java.util.List;

import com.cn.vo.Dept;

public interface DeptDao {

public void addDept(Dept dept);//添加部門

}

在接口實現類DeptDaoImp中實現addDept()方法,接口實現類DeptDaoImp的代碼如下(這里省略了import的內容)

package com.cn.dao.imp;

public class DeptDaoImp implements DeptDao {

Session session = HibernateSessionFactory.getSession();//獲得session

Transaction tr = session.beginTransaction();//開啟事務

public void addDept(Dept dept) {

session.save(dept);//添加數據

tr.commit();//提交事務

}

}

在添加部門信息的Servlet中,添加數據成功以后,頁面跳轉到查詢全部數據的Servlet中,所以添加數據的演示留到和查詢全部數據一起演示。

14.3.2 查詢全部部門信息

添加部門信息成功以后,頁面跳轉到查詢全部部門信息的Servlet中,查詢全部部門信息的Servlet——ShowAllDeptServlet的代碼如下(這里省略了import的內容):

package com.cn.service;

public class ShowAllDeptServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

DeptDao dao = new DeptDaoImp();//接口實現類對象指向接口的引用

List<Dept> list =new ArrayList<Dept>();

list = dao.queryAllDept();//調用接口實現類中的queryAllDept方法

request.setAttribute("list", list);//把查詢得到的集合放到request對象中

//轉發到顯示全部的頁面中

request.getRequestDispatcher("showAllDept.jsp").forward(request, response);

out.flush();

out.close();

}

}

ShowAllDeptServletdoGet()方法中調用了doPost()方法,查詢數據的操作的doPost()方法中處理。在doPost()方法中調用了接口實現類中的queryAllDept()方法。在接口DeptDao中添加queryAllDept()方法,代碼如下:

public List<Dept> queryAllDept();//顯示全部部門信息

在接口實現類DeptDaoImp中實現queryAllDept()方法,queryAllDept()方法代碼如下:

public List<Dept> queryAllDept() {

//查詢全部部門信息

List<Dept> list = session.createQuery("from Dept").list();

eturn list;

}

查詢出全部的部門信息后,ShowAllDeptServlet轉發到顯示全部部門信息的頁面showAllDept.jsp中,showAllDept.jsp的代碼如下(這里省略了htmlheadbody標簽,用省略號代替):

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

……

<table border="1">

<tr><td>部門號</td><td>部門名稱</td><td>操作</td></tr>

<c:forEach var="list" items="${list}">

<tr>

<td>${list.depno }</td>

<td>${list.depname }</td>

<td>

<a href="DeleteDeptServlet?depno=${list.depno }">刪除</a>

</td>

</tr>

</c:forEach>

</table>

……

現在來演示添加部門信息和查詢全部部門信息。啟動Tomcat服務器,在IE瀏覽器地址欄中輸入地址:“http://localhost:8080/hibernate_jsp/addDept.jsp”,頁面效果如圖14.7所示。

Hibernate結合JSP使用<轉載>

14.7 添加部門信息頁面

在圖14.7所示的頁面中輸入部門名稱后,提交表單。添加部門信息成功后頁面中顯示出全部的部門信息,效果如圖14.8所示。

Hibernate結合JSP使用<轉載>

14.8 顯示全部部門信息的頁面

14.3.3 刪除部門信息

部門表的主鍵是員工表的外鍵,在刪除部門信息時,如果該條信息是員工表一些數據的外鍵時,需要把員工表的信息業刪除掉。在編寫刪除操作之前,要在Dept.hbm.xml映射文件中設置一對多的級聯操作,<set>中的代碼修改成如下代碼:

<set name="emps" inverse="true" lazy="false" cascade="all">

<key>

<column name="depno" />

</key>

<one-to-many class="com.cn.vo.Emp" />

</set>

在顯示全部部門信息的頁面中,點擊刪除超鏈接時,頁面進入刪除部門信息的Servlet——DeleteDeptServletDeleteDeptServlet的代碼如下(這里省略了import的內容):

package com.cn.service;

public class DeleteDeptServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

int depno = Integer.parseInt(request.getParameter("depno"));//獲得路徑中的參數

DeptDao dao = new DeptDaoImp();

dao.deleteDept(depno);//調用刪除方法

response.sendRedirect("ShowAllDeptServlet");//頁面重定向到查詢全部部門信息的Servlet

out.flush();

out.close();

}

}

DeleteDeptServletdoGet()方法中調用了doPost()方法,doPost()方法中獲得路徑中傳遞的參數,然后調用接口實現類DeptDaoImp中的deleteDept()方法。在接口DeptDao中添加deleteDept()方法,代碼如下:

public void deleteDept(int id);//根據id刪除數據

在接口實現類DeptDaoImp中要實現deleteDept()方法,deleteDept()方法代碼如下:

public void deleteDept(int id) {

Dept dept = (Dept) session.load(Dept.class, id);

session.delete(dept);//刪除數據

session.flush();

tr.commit();//提交事務

}

刪除部門信息以后,該條信息對於的員工表外鍵數據也被刪除,啟動Tomcat服務器,在IE瀏覽器地址欄中輸入地址:“http://localhost:8080/hibernate_jsp/ShowAllDeptServlet”,頁面效果如圖14.9所示。

Hibernate結合JSP使用<轉載>

14.9 刪除部門信息之前的頁面

在圖14.9所示的頁面中刪除掉部門編號為2的數據,該條數據對應的部門名稱為市場部。刪除成功后,頁面進入圖14.10所示的頁面。

Hibernate結合JSP使用<轉載>

14.10 刪除部門信息成功以后的頁面

再到數據中查詢員工表的信息,發現外鍵為2的員工表信息都被刪除了,這是因為在刪除部門表信息時,使用了一對多的級聯刪除操作。

14.4 Hibernate的分頁查詢

當查詢結果時很多數據時,一個頁面無法全部顯示出來,這個時候就用到了分頁查詢。Hibernate的頁面查詢方法是必須要掌握的一個知識點。這一節將介紹簡單的Hibernate分頁查詢。為了便於理解,本節中的例子也采用分層來介紹,hql語句寫在數據庫訪問層(即DAO層),Servlet中調用DAO層代碼,在JSP頁面中分頁顯示出來。

14.4.1 數據庫訪問層代碼

數據庫訪問層也稱DAO層,在DAO層中,要定義兩個方法,一個方法是查詢數據信息的方法,一個方法是求最大頁數的方法。接口EmpPageDAO的代碼如下:

package com.cn.page;

import java.util.List;

import com.cn.vo.Emp;

public interface EmpPageDAO {

public List<Emp> getAll(int pageNo, int pageSize);// 查詢數據信息的方法

public int maxPage();//求最大頁數的方法

}

在接口中定義的方法,要在接口實現類EmpPageDAOImp中實現這些方法,接口實現類EmpPageDAOImp的代碼如下(這里省略了import的內容)

package com.cn.page;

public class EmpPageDAOImp implements EmpPageDAO{

Session session = HibernateSessionFactory.getSession(); //獲得Session

public List<Emp> getAll(int pageNo, int pageSize) {

session.beginTransaction();

List<Emp> list = new ArrayList<Emp>();

//把查詢結果放入list集合中,查詢結果是根據頁數來顯示記錄數

list = session.createQuery("from Emp")

.setFirstResult((pageNo-1)*pageSize)//每頁顯示的起始數據pageNo表示頁數

.setMaxResults(pageSize) //每頁顯示的末條數據pageSize表示每頁顯示的數量

.list();

session.getTransaction().commit(); //提交事務

return list;

}

public int maxPage(){//求最大頁數的方法

int count =0;//聲明一個count變量用於存儲記錄數

int maxpage = 0;//聲明一個maxpage變量原來表示最大頁數

session.beginTransaction();

//獲取總記錄數

count = (Integer)session.createQuery("select count(*) from Emp").uniqueResult();

maxpage =(count+4)/5;// 這里的5是每頁顯示的條數,4是每頁顯示條數減1

return maxpage;

}

}

14.4.2 Servlet層的代碼

在數據庫訪問層中聲明了最大頁數和查詢數據信息的方法后,需要在Servlet中調用這些方法。這個例子中是在ShowEmpByPageServlet類中調用DAO層的方法,ShowEmpByPageServlet類的代碼如下(這里省略了import的內容):

package com.cn.page;

public class ShowEmpByPageServlet extends HttpServlet {

public void doGet(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

this.doPost(request, response);//調用doPost方法

out.flush();

out.close();

}

public void doPost(HttpServletRequest request, HttpServletResponse response)

throws ServletException, IOException {

response.setContentType("text/html");

PrintWriter out = response.getWriter();

String page = request.getParameter("page");//獲得地址欄中傳遞的頁數

int pageNo=1;//聲明pageNo表示當前頁數

int pageSize=5;//聲明pageSize表示每頁顯示的數量

if(page!=null){//如果獲得地址欄中的頁數不為null。賦值給pageNo

pageNo = Integer.parseInt(page);

}

EmpPageDAO empPageDAOImp = new EmpPageDAOImp();

List<Emp> list = new ArrayList<Emp>();

//調用EmpPageDAOImpgetAll方法獲得查詢結果

list = (List<Emp>) empPageDAOImp.getAll(pageNo, pageSize);

int maxPage = empPageDAOImp.maxPage();//獲得最大頁數

request.setAttribute("list", list);

request.setAttribute("page", pageNo);

request.setAttribute("maxpage", maxPage);

//轉發到showEmpByPage.jsp頁面

request.getRequestDispatcher("showEmpByPage.jsp").forward(request, response);

out.flush();

out.close();

}

}

Servlet中調用接口實現類EmpPageDAOImp中的getAll()方法來獲得查詢信息,調用maxPage()方法來獲得最大頁數。把獲得的當前頁數、最大頁數和查詢結果放入request對象中,轉發到JSP頁面中。在JSP頁面獲得這些信息。

14.4.3 JSP頁面分頁

JSP頁面中獲得Servlet轉發過來的數據信息后,分頁顯示出獲得的數據信息。在JSP頁面中使用到JSTL標簽庫來遍歷數據。分頁顯示的JSP頁面——showEmpByPage.jsp代碼如下

<%@ page language="java" import="java.util.*" pageEncoding="gb2312"%>

<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">

<html>

<head><title>My JSP 'showEmpByPage.jsp' starting page</title></head>

<body>

<table border="1" align="center">

<tr>

<td>員工編號</td>

<td>員工姓名</td>

<td>員工所在部門</td>

<td>操作</td>

</tr>

<c:forEach var="list" items="${list}">

<tr>

<td>${list.empno }</td>

<td>${list.empname }</td>

<td>${list.dept.depname }</td>

<td>

<a href="QueryEmpById?empno=${list.empno }">修改</a>

<a href="DeleteEmpById?empno=${list.empno }">刪除</a>

</td>

</tr>

</c:forEach>

</table>

<div align="center">

<c:if test="${page ==1}">首頁</c:if>

<c:if test="${page > 1}"><a href="/hibernate_jsp/ShowEmpByPageServlet?page=1">首頁</a></c:if>

<c:if test="${page ==1}">上一頁</c:if>

<c:if test="${page > 1}"><a href="/hibernate_jsp/ShowEmpByPageServlet?page=${page-1 }">上一頁</a></c:if>

<c:if test="${page == maxpage}">下一頁</c:if>

<c:if test="${page < maxpage}"><a href="/hibernate_jsp/ShowEmpByPageServlet?page=${page+1 }">下一頁</a></c:if>

<c:if test="${page == maxpage}">末頁</c:if>

<c:if test="${page < maxpage}"><a href="/hibernate_jsp/ShowEmpByPageServlet?page=${maxpage }">末頁</a></c:if>

</div>

</body>

</html>

showEmpByPage.jsp頁面中,如果當前頁面是第一頁,則首頁和上一頁變成不可點擊狀態,如果當前頁數是最大頁,則下一頁和末頁變成不可點擊狀態。啟動Tomcat服務器,在IE瀏覽器地址欄中輸入地址:“http://localhost:8080/hibernate_jsp/ShowEmpByPageServlet”,頁面效果如圖14.11所示。

Hibernate結合JSP使用<轉載>

14.11 分頁顯示的首頁

14.5 本章小結

本章中使用Hibernate結合ServletJSP對數據庫表數據進行了操作。操作員工表時,添加數據涉及到部門表的信息,所以在添加員工信息時,要確保外鍵存在。在操作部門表時,刪除部門信息需要把員工表中有外鍵關聯的數據刪除,涉及到級聯刪除。本章好介紹了Hibernate的分頁查詢。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM