JavaWeb框架-【Hibernate+Struts2】-框架世界的联手-图书管理系统

来源:互联网 发布:推广平台源码 编辑:程序博客网 时间:2024/05/18 02:07

话说

上一篇博客,单纯用Hibernate写了图书管理系统,在接收参数方面,怎一个累字了得!

团结才是力量,合作促生共赢!框架滴世界也是如此。这篇博客简单总结下Hibernate+Struts2整合来实现上一篇博客的功能——图书管理系统

目录


1、整体框架及效果图

2、环境搭建

3、代码编写

4、页面

5、总结


开发环境:

IntelliJ IDEA(2017.2.5)
MySQL
Mavan web项目

1、整体框架及效果图

这里写图片描述

这里写图片描述

这里写图片描述

这里写图片描述

2、环境搭建

1)hibernate.cfg.xml
2)struts.xml
3)web.xml

1)hibernate.cfg.xml

这个配置达到这样几个目的:
连接数据库、实体类映射、自动创建表、打印SQL语句

<!--  ~ Hibernate, Relational Persistence for Idiomatic Java  ~  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.  --><!DOCTYPE hibernate-configuration PUBLIC    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><hibernate-configuration>    <session-factory>        <!--配置MySQL数据库连接-->        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/sysmgr</property>        <property name="hibernate.connection.username">root</property>        <property name="hibernate.connection.password">119913</property>        <!--配置自动创建表、打印SQL语句-->        <property name="hibernate.show_sql">true</property>        <property name="hibernate.format_sql">true</property>        <property name="hibernate.hbm2ddl.auto">update</property>        <!--配置实体映射-->        <mapping class="com.hmc.bookmgr.model.Book"></mapping>    </session-factory></hibernate-configuration>

2)struts.xml

这个配置达到这几个目的:
配置action、配置DMI

<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.5//EN"    "http://struts.apache.org/dtds/struts-2.5.dtd"><struts>    <!--配置DMI-->  <constant name="struts.enable.DynamicMethodInvocation" value="true"/>    <constant name="struts.devMode" value="true"/>    <package name="default" extends="struts-default">        <!--所有的方法都可以调用-->        <global-allowed-methods>regex:.*</global-allowed-methods>        <!--配置Action-->        <!--一定要注意,这个action类似Servlet,Servlet的name之所以        能够在页面直接访问,是因为Servlet是在web.xml中配置的,但是这里配置的位置        是struts.xml,如何和页面建立联系呢?过滤器!所以,还需要配置web.xml-->        <action name="*_*" class="com.hmc.bookmgr.action.{1}Action" method="{2}">            <result name="success">/{1}/{2}.jsp</result>            <!--为新增图书、修改和显示详情做跳转配置-->            <result name="redirectUrl" type="redirect">${url}</result>        </action>    </package>    <include file="example.xml"/>    <!-- Add packages here --></struts>

3)web.xml

过滤器,只有和struts.xml搭配,struts.xml才能发挥作用

<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd" ><web-app>  <display-name>Archetype Created Web Application</display-name>  <filter>    <filter-name>struts2</filter-name>    <filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>struts2</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping></web-app>

3、代码编写

1)model
2)util
3)dao
4) action

1)model

Book

package com.hmc.bookmgr.model;import org.hibernate.annotations.GenericGenerator;import javax.persistence.Entity;import javax.persistence.GeneratedValue;import javax.persistence.Id;import javax.persistence.Table;import java.util.Date;/** * User:Meice * 2017/11/2 */@Entity@Table(name = "book")public class Book {    private int bookid;    private String bookname;    private String bookauthor;    private String bookpress;    private double bookprice;    private Date bookdate;    public Book() {}    public Book(int bookid,String bookname,String bookauthor,String bookpress    ,double bookprice,Date bookdate) {        this.bookid = bookid;        this.bookname = bookname;        this.bookauthor = bookauthor;        this.bookpress = bookpress;        this.bookprice = bookprice;        this.bookdate = bookdate;    }    public Book(String bookname, String bookauthor, String bookpress, double bookprice, Date bookdate) {        this.bookname = bookname;        this.bookauthor = bookauthor;        this.bookpress = bookpress;        this.bookprice = bookprice;        this.bookdate = bookdate;    }    @Id    @GenericGenerator(name = "myid" ,strategy = "native")    @GeneratedValue(generator = "myid")    public int getBookid() {        return bookid;    }    public void setBookid(int bookid) {        this.bookid = bookid;    }    public String getBookname() {        return bookname;    }    public void setBookname(String bookname) {        this.bookname = bookname;    }    public String getBookauthor() {        return bookauthor;    }    public void setBookauthor(String bookauthor) {        this.bookauthor = bookauthor;    }    public String getBookpress() {        return bookpress;    }    public void setBookpress(String bookpress) {        this.bookpress = bookpress;    }    public double getBookprice() {        return bookprice;    }    public void setBookprice(double bookprice) {        this.bookprice = bookprice;    }    public Date getBookdate() {        return bookdate;    }    public void setBookdate(Date bookdate) {        this.bookdate = bookdate;    }    @Override    public String toString() {        return "Book{" +                "bookid=" + bookid +                ", bookname='" + bookname + '\'' +                ", bookauthor='" + bookauthor + '\'' +                ", bookpress='" + bookpress + '\'' +                ", bookprice=" + bookprice +                ", bookdate=" + bookdate +                '}';    }}

2)util

HibernateUtil

package com.hmc.bookmgr.util;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.boot.MetadataSources;import org.hibernate.boot.registry.StandardServiceRegistry;import org.hibernate.boot.registry.StandardServiceRegistryBuilder;/** * User:Meice * 2017/11/2 */public class HibernateUtil {    /**     * 得到session,关闭session     * 为方便调用,全部static!     */    private static SessionFactory sessionFactory = null;    // A SessionFactory is set up once for an application!    static{        //这里要注意,默认配置文件名不要改,改了以后这里也要同步修改        final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure().build();        try {            sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();        } catch (Exception e) {            // The registry would be destroyed by the SessionFactory, but we had trouble building the SessionFactory            // so destroy it manually.            StandardServiceRegistryBuilder.destroy(registry);        }    }    /**     * 获取session     */    public static Session getSession() {       Session session = sessionFactory.openSession();       return session;    }    /**     * 关闭session     */    public static void closeSession(Session session){        session.close();    }}

StringConvertInt

package com.hmc.bookmgr.util;/** * User:Meice * 2017/11/2 */public class StringConvertInt {    /**     * 和以前一样,转换一下接受的id     */    public static int getVal(String str){        if(str != null && !"".equals(str)) {          return    Integer.parseInt(str);        }        return 0;    }}

3)dao

BookDao

package com.hmc.bookmgr.dao;import com.hmc.bookmgr.model.Book;import com.hmc.bookmgr.util.HibernateUtil;import com.opensymphony.xwork2.ActionContext;import org.hibernate.Session;import org.junit.jupiter.api.Test;import java.util.List;/** * User:Meice * 2017/11/2 */public class BookDao {    /**     * 实现增删改查     * 之前是方便Servlet调用 Struts2+ Hibernate整合后,方便Action调用,替代Servlet     * 为什么要替代呢?因为Servlet接收参数是在太繁琐;一旦参数多起来,接收晕乎了     */    Session session = HibernateUtil.getSession();    //增    public int add(Book book) {        session.beginTransaction();       session.save(book);       session.getTransaction().commit();        return 1;    }    //删    public int del(int id) {        Book book = new Book();        book.setBookid(id);        session.beginTransaction();        session.delete(book);        session.getTransaction().commit();        return 1;    }    //改    /**     * 这里的修改,不在时给Id,因为struts2底层已经封装好,直接给对象     */    public int update(Book book) {        session.beginTransaction();        session.update(book);        session.getTransaction().commit();        return 1;    }    //查-所有    @Test    public List<Book> getBooks() {      List<Book> books =  session.createQuery("from Book").list();        return  books;        /**         * 测试:         * Hibernate:select         book0_.bookid as bookid1_0_,         book0_.bookauthor as bookauth2_0_,         book0_.bookdate as bookdate3_0_,         book0_.bookname as bookname4_0_,         book0_.bookpress as bookpres5_0_,         book0_.bookprice as bookpric6_0_         from  book book0_         Book{bookid=4, bookname='三国演义', bookauthor='罗贯中', bookpress='人民文学出版社', bookprice=77.77, bookdate=2017-11-02 07:46:14.0}         */    }    //查-单个    @Test    public Book getBookById(int id) {      Book book =  session.get(Book.class,id);       return book;        //测试结果无误    }    //查——分页显示    public List<Book> getBooksPager(int offset,int pageSize) {     List<Book> books =   session.createQuery("from Book")                .setFirstResult(offset)                .setMaxResults(pageSize)                .list();     return books;    }    /**     * 查总条目数     */    public int countBooks() {       Long longCount =(Long) session.createQuery("select count(bookid) from Book")                .uniqueResult();       int count = longCount.intValue();       return  count;    }}

4) action

BookAction
这里面把分页一块实现了,就避免在多出一个BookPage实体类

package com.hmc.bookmgr.action;import com.hmc.bookmgr.dao.BookDao;import com.hmc.bookmgr.model.Book;import com.hmc.bookmgr.model.BookPager;import com.hmc.bookmgr.util.StringConvertInt;import com.opensymphony.xwork2.ActionContext;import com.opensymphony.xwork2.ModelDriven;import java.util.List;/** * User:Meice * 2017/11/2 */public class BookAction implements ModelDriven<Book> {        BookDao bd = new BookDao();        private Book book;    private int pageIndex=1;//当前页    private int totalPage;//总页数    private int count;//总条目数    private int pageSize=15;//每页显示书目    private int offset;//偏移量 limit第一个参数    private String action;//用来区别调转到修改页面还是detail页面    /**     * 这里面实现原来Servlet的功能     * 接收参数、业务逻辑处理、页面跳转     */    //显示图书    public String  index() {        //接受参数        pageIndex = pageIndex<1? 1:pageIndex;        count = bd.countBooks();        /**         * 之前我们是在get()方法里面写的,发现接收不到参数,所以必须写在这里         */        offset = (pageIndex-1)*pageSize;        //调用方法         List<Book> books = bd.getBooksPager(offset,pageSize);         //存储值        ActionContext.getContext().put("books",books);        //页面跳转        return  "success";    }    /**     * 运行结果:     * Hibernate:     select  count(book0_.bookid) as col_0_0_  from book book0_     Hibernate:     select book0_.bookid as bookid1_0_, book0_.bookauthor as bookauth2_0_,     book0_.bookdate as bookdate3_0_, book0_.bookname as bookname4_0_,     book0_.bookpress as bookpres5_0_, book0_.bookprice as bookpric6_0_     from book book0_ limit ?,?     */    //增加图书    public String  add() {        return "success";    }    public String doAdd() {        //接收参数        //调用方法        bd.add(book);        //        ActionContext.getContext().put("url","Book_index");        return "redirectUrl";        /**         * 运行结果         * Hibernate:         * insert into book (bookauthor, bookdate, bookname, bookpress, bookprice)         * values  (?, ?, ?, ?, ?)         * Struts2多方便,参数根本不用像Servlet那样一个一个的接收,而且date类型都不用你处理         * 只要你写的符合YYYY-mm-dd格式就可以         */    }    /**     * 显示图书信息     * @return     */    public String detail() {     book =   bd.getBookById(book.getBookid());     ActionContext.getContext().put("book",book);         return "success";    }    public String update() {        book =   bd.getBookById(book.getBookid());        ActionContext.getContext().put("book",book);        return "success";    }    /**     * 执行修改     * @return     */    public String doUpdate () {        //看看当年走过的弯路....       /* book.setBookname(book.getBookname());        book.setBookauthor(book.getBookauthor());        book.setBookprice(book.getBookprice());        book.setBookpress(book.getBookpress());        book.setBookdate(book.getBookdate());*/        bd.update(book);        ActionContext.getContext().put("url","Book_index");        return "redirectUrl";    }    /**     * 删除     */    public String del() {        bd.del(book.getBookid());        ActionContext.getContext().put("url","Book_index");        return "redirectUrl";    }    public Book getModel() {        if(book == null) {            book = new Book();        }        return book;    }    /**     * 以下这些都是为了分页     * 因为Book的ModelDriven已经实现了,这些就我所知,     * 暂只能以这种方式接收连接传递过来的参数     * @return     */    public int getPageIndex() {        return pageIndex;    }    public void setPageIndex(int pageIndex) {        this.pageIndex = pageIndex;    }    public int getTotalPage() {        totalPage = (int)Math.ceil((double)count/pageSize);        return totalPage;    }    public void setTotalPage(int totalPage) {        this.totalPage = totalPage;    }    public int getCount() {        return count;    }    public void setCount(int count) {        this.count = count;    }    public int getPageSize() {        return pageSize;    }    public void setPageSize(int pageSize) {        this.pageSize = pageSize;    }    public int getOffset() {        return offset;    }    public void setOffset(int offset) {        this.offset = offset;    }    public String getAction() {        return action;    }    public void setAction(String action) {        this.action = action;    }}

4、页面

1) index.jsp——显示图书

<%--  User: Meice  Date: 2017/11/2  Time: 17:24--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"  %><html><head>    <title>图书管理系统</title></head><body>    <table width="80%" border="1" align="center">        <caption>            <h2>Meice滴图书管理系统【Struts2+Hibernate】</h2>        </caption>        <thead>            <tr>                <th>编号</th>                <th>图书名称</th>                <th>图书作者</th>                <th>图书价格</th>                <th>出版社</th>                <th>出版日期</th>                <th>操作</th>            </tr>        </thead>        <tboday>            <c:forEach var="book" items="${books}">               <tr>                   <td align="center">${book.bookid}</td>                   <td>${book.bookname}</td>                   <td>${book.bookauthor}</td>                   <td>${book.bookprice}</td>                   <td>${book.bookpress}</td>                   <td>${book.bookdate}</td>                   <td align="center">                       <a href="Book_detail?bookid=${book.bookid}">详情</a>|                       <a href="Book_update?bookid=${book.bookid}">修改</a>|                       <a href="Book_del?bookid=${book.bookid}" onclick="return confirm('真的忍心删除么?')">删除</a>                   </td>               </tr>            </c:forEach>            <tr align="center">                <td colspan="7">                    <c:if test="${pageIndex>1}">                        <a href="Book_index?pageIndex=1">首页</a>                        <a href="Book_index?pageIndex=${pageIndex-1}">上一页</a>                    </c:if>                    <%--以下是有Bug的,不完美,暂且搁置,面子上过得去了,后续完善--%>                  <c:if test="${pageIndex<totalPage-9}">                      <c:forEach var="x" begin="${pageIndex}" end="${pageIndex+9}">                          <a href="Book_index?pageIndex=${x}">${x}</a>                      </c:forEach>                  </c:if>                    <c:if test="${pageIndex < totalPage}">                        <a href="Book_index?pageIndex=${pageIndex+1}">下一页</a>                        <a href="Book_index?pageIndex=${totalPage}">末页</a>                    </c:if>                </td>            </tr>        </tboday>    </table><a href="Book_add">新增图书</a></body></html>

2)add.jsp——新增图书

<%--  User: Meice  Date: 2017/11/2  Time: 17:24--%><%@ page contentType="text/html;charset=UTF-8" language="java"  isELIgnored="false" %><html><head>    <title>新增图书</title></head><body>    <form action="Book_doAdd" method="post">        <table width="40%" align="center" border="1">            <caption>                <h2>Meice-新增图书</h2>            </caption>            <tr>                <td>图书名称</td>                <td><input type="text" name="bookname"/></td>            </tr>            <tr>                <td>作者</td>                <td><input type="text" name="bookauthor"/></td>            </tr>            <tr>                <td>出版社</td>                <td><input type="text" name="bookpress"></td>            </tr>            <tr>                <td>价格</td>                <td><input type="text" name="bookprice" /></td>            </tr>            <tr>                <td>出版日期</td>                <td><input  type="text" name="bookdate" /></td>            </tr>            <tr>                <td colspan="2" align="center"><input type="submit" value="新增"/></td>            </tr>            <tr>                <td colspan="3" align="center">                 <a href="Book_index">返回主页面</a>                </td>            </tr>        </table>    </form></body></html>

3)update.jsp——修改图书

<%--  User: Meice  Date: 2017/11/2  Time: 17:25--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><html><head>    <title>图书修改</title>    <style type="text/css">       tr td{            text-align: center;        }    </style></head><body><form action="Book_doUpdate" method="post">    <input name="bookid" type="hidden" value="${book.bookid}">    <table width="40%" align="center" border="1">        <caption>            <h2>Meice-修改图书</h2>        </caption>        <tr>            <td>图书名称</td>            <td><input type="text" name="bookname" value="${book.bookname}"/></td>        </tr>        <tr>            <td>作者</td>            <td><input type="text" name="bookauthor"  value="${book.bookauthor}"/></td>        </tr>        <tr>            <td>出版社</td>            <td><input type="text" name="bookpress"  value="${book.bookpress}"></td>        </tr>        <tr>            <td>价格</td>            <td><input type="text" name="bookprice"  value="${book.bookprice}"/></td>        </tr>        <tr>            <td>出版日期</td>            <td><input  type="text" name="bookdate"   value="${book.bookpress}"/></td>        </tr>        <tr>            <td colspan="2" align="center"><input type="submit" value="确认修改"/></td>        </tr>        <tr>            <td colspan="2" align="center">                <a href="Book_index">返回主页面</a>            </td>        </tr>    </table></form></body></html>

4)detail.jsp——图书详情

<%--  User: Meice  Date: 2017/11/2  Time: 17:24--%><%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %><html><head>    <title>图书详情</title>    <style type="text/css">        tr td{            text-align: center;        }    </style></head><body>    <table width="40%" align="center" border="1">        <caption>            <h2>Meice-图书详情</h2>        </caption>        <tr>            <td align="center">图书名称</td>            <td>${book.bookname}</td>        </tr>        <tr>            <td align="center">作者</td>            <td>${book.bookauthor}</td>        </tr>        <tr>            <td align="center">出版社</td>            <td>${book.bookpress}</td>        </tr>        <tr>            <td align="center">价格</td>            <td>${book.bookprice}</td>        </tr>        <tr>            <td align="center">出版日期</td>            <td>${book.bookdate}</td>        </tr>        <tr>            <td colspan="2" align="center">                <a href="Book_index?pageIndex=${pageIndex}">返回主页面</a>            </td>        </tr>    </table></body></html>

5、总结


1、每一个框架的配置流程要炉火纯青,信手拈来。记忆是不靠谱的,知道快速寻找记忆,才是靠谱的。官网就是很好的方式。不用记忆过多东西,因为那些都是死的。知道怎么快速找到才最重要。

2、框架操作起来是简单了,配置要繁琐点,不过相比大数据,根本不算啥。所以,配置要细心,一定要配置全。配置全否,就要看对框架的理解是否深刻。自己操作就忘记配置web.xml的过滤器了。为什么会忘记呢?因为对struts2认识还是不够深刻。struts.xml中的action相当于Servlet,之前Servlet是在web.xml中配置的,所以一旦页面访问name,服务器就知道你想访问这个页面。但是,我们的action是配置在struts.xml中的,你在页面访问name,Web服务器怎么知道呢?所以嘛,中间的桥梁就是靠过滤器来实现的。所以要配置web.xml,这样理解,就根本不会忘记配置。

3、Hibernate优点:连接数据库方便、API方便、实体类映射方便
Struts2优点:Action接受参数、页面跳转(DMI)方便。
如果读者是从JDBC开始看在下的博客,并真的实际操作过,一定深有体会。

4、这次整合遇到的问题是:分页的参数怎么在BookAction中传递。最后想到的办法是,按照struts2的第一种接收参数的方式,把分页的几个参数全部定义为变量,并且生成get()、set()方法,这样链接传过来的参数就可以直接接收了。因为没法实现2个不同的ModelDrivet呢。

5、增加和修改的时候,页面跳转用到了动态结果集,很灵活的跳转方式。

6、分页中的末页还有bug,暂且搁置。


好了,亲爱的各位读者,下期再会!