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,暂且搁置。
好了,亲爱的各位读者,下期再会!
- JavaWeb框架-【Hibernate+Struts2】-框架世界的联手-图书管理系统
- JavaWeb框架-Hibernate-4-沙场秋练兵-图书管理系统!
- SSH框架图书管理系统
- Struts2+Hibernate实现图书管理系统
- javaweb图书管理系统
- 三大Javaweb框架的工作原理--Struts2+Hibernate+Spring3
- SSH框架开发实例:图书管理系统
- SSM框架应用实例《图书管理系统》
- 自己设计开发的通用后台管理系统开发框架(struts2+hibernate+spring+easyui)
- javaWeb 原生图书管理系统
- Struts2简单的图书管理系统
- 图书发行管理系统(extjs框架)和图书零售系统(jquery框架)
- JavaWeb -- Struts2 验证框架
- JavaWeb(框架----Struts2):-----配置
- JavaWeb(框架--Hibernate):----配置
- JavaWeb(框架--Hibernate):----配置
- JavaWeb框架----hibernate入门
- JavaWeb三大框架(Hibernate+Struts2+Spring)
- Tetris_Java(I)千里之行始于足下
- Parallel&Distributed Algorithm-1
- 每天一道LeetCode-----某个数在递增序列第一次和最后一次出现的位置
- AFN提交类型和回应类型
- SpringBatch配置多线程step
- JavaWeb框架-【Hibernate+Struts2】-框架世界的联手-图书管理系统
- LLVM学习笔记(21)
- leetcode 6 ZigZag Conversion
- Android,沉浸式状态栏,状态栏以及Toolbar颜色分开设置
- 提示错误:A child Container failed during start
- C99中的for语句
- Linux 中mysql-5.7.9 64位 RPM 详细安装
- vue学习07--进入/离开&列表过渡
- mybatis原生态开发基本配置文件