话说
这篇博客也是为后面博客做铺垫的。之所以把它放在这个位置,是因为Hibernate在接收参数方面和Struts2形成了鲜明的对比;Hibernate侧重方法;Struts侧重参数传递和页面跳转。
目标:实现Meice的图书管理系统,功能还是自己重复多次的CURD!
希望读者不要嫌弃。正如生活大多数还是柴米油盐酱醋茶一样,代码世界里,CURD是个无论如何都值得深刻体会并掌握得炉火纯青!
目录
一、整体框架
二、前期准备
三、环境搭建
四、代码编写
五、页面
六、总结
开发环境:IntelliJ IDEA(2017.2.5)
Maven web项目开发
MySQL数据库
一、整体框架
效果图
二、前期准备
1、数据库
新建sysmgr数据库即可
数据表配置Hibernate.cfg.xml自动生成
2、心态
CURD虽然简单,但是用不同的框架,总会温故知新。
三、环境搭建
1、新建Maven web项目
2、配置hibernate.cfg.xml
这个参考源码包project下面的etc文件下的default.properties来配置
hibernate.cfg.xml
<!--
~ 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"/>
</session-factory>
</hibernate-configuration>
没有特别需要注意的。自动创建表选择update,没有就创建,有就覆盖。
四、代码编写
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/1
*/
@Entity
@Table(name = "book")
public class Book {
private int bookid;
private String bookname;
private double bookprice;
private String bookauthor;
private String bookpress;
private Date bookdate;
public Book() {}
public Book(int bookid,String bookname,double bookprice,String bookauthor,String bookpress,Date bookdate) {
this.bookid = bookid;
this.bookname = bookname;
this.bookprice = bookprice;
this.bookauthor = bookauthor;
this.bookpress = bookpress;
this.bookdate = bookdate;
}
public Book(String bookname, double bookprice, String bookauthor, String bookpress, Date bookdate) {
this.bookname = bookname;
this.bookprice = bookprice;
this.bookauthor = bookauthor;
this.bookpress = bookpress;
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 double getBookprice() {
return bookprice;
}
public void setBookprice(double bookprice) {
this.bookprice = bookprice;
}
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 Date getBookdate() {
return bookdate;
}
public void setBookdate(Date bookdate) {
this.bookdate = bookdate;
}
@Override
public String toString() {
return "Book{" +
"bookid=" + bookid +
", bookname='" + bookname + '\'' +
", bookprice=" + bookprice +
", bookauthor='" + bookauthor + '\'' +
", bookpress='" + bookpress + '\'' +
", bookdate=" + bookdate +
'}'+"\n";
}
}
BookPager
为实现分页,单独创建一个实体类,便于传参
package com.hmc.bookmgr.model;
import java.util.List;
/**
* User:Meice
* 2017/11/2
*/
public class BookPager {
/**
* 定义图书管理系统分页
*/
private int pageIndex=1;//当前页
private int count;//总条目数
private int pageSize = 15;//每页显示条目数
private int totalPage;//总页数
private int offset;//偏移量 limit用
private List<Book> books;//存放所有书籍信息
public int getPageIndex() {
return pageIndex;
}
public void setPageIndex(int pageIndex) {
this.pageIndex = pageIndex;
}
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 getTotalPage() {
//赋值要在get()方法里面赋值
totalPage = (int)Math.ceil((double)count/pageSize);
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
public List<Book> getBooks() {
return books;
}
public void setBooks(List<Book> books) {
this.books = books;
}
public int getOffset() {
//偏移量和当前页和每页显示数量有关系
offset = pageSize*(pageIndex-1);
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
@Override
public String toString() {
return "BookPager{" +
"pageIndex=" + pageIndex +
", count=" + count +
", pageSize=" + pageSize +
", totalPage=" + totalPage +
", offset=" + offset +
", books=" + books +
'}';
}
}
2、dao层
BookDao
package com.hmc.bookmgr.dao;
import com.hmc.bookmgr.model.Book;
import com.hmc.bookmgr.util.HibernateUtil;
import org.hibernate.Session;
import org.junit.jupiter.api.Test;
import java.util.List;
/**
* User:Meice
* 2017/11/1
*/
public class BookDao {
Session session = null;
/**
* 增加图书
*/
public int add(Book book) {
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.save(book);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}finally {
HibernateUtil.closeSession(session);
}
return 1;
}
/**
* 修改图书
*/
public int update(Book book) {
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.update(book);
session.getTransaction().commit();
} catch (Exception e) {
session.getTransaction().rollback();
}finally {
HibernateUtil.closeSession(session);
}
return 1;
}
/**
* 删除图书
*/
public int del(int id) {
try {
session = HibernateUtil.getSession();
Book book = new Book();
book.setBookid(id);
session.beginTransaction();
session.delete(book);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}
return 1;
}
/**
* 显示图书列表
*/
@Test
public List<Book> getBooks() {
try {
session = HibernateUtil.getSession();
return session.createQuery("from Book").list();
} catch (Exception e) {
e.printStackTrace();
return null;
}finally{
HibernateUtil.closeSession(session);
}
}
/**
* 根据id查询图书信息
*/
public List<Book> getBookById(int id) {
try {
session = HibernateUtil.getSession();
return session.createQuery("from Book where bookid = ?")
.setParameter(0,id)
.list();
//这里还可以直接用session.get()更简单
//session.get(Book.class,id);
} catch (Exception e) {
e.printStackTrace();
return null;
}finally{
HibernateUtil.closeSession(session);
}
}
/**
* 查询书籍总条目数
*/
@Test
public int booksCount() {
session = HibernateUtil.getSession();
Long longCount =(Long) session.createQuery("select count(bookid) from Book ")
.uniqueResult();
//如何把Long转为int?
int count = longCount.intValue();
return count;
/**
* 测试结果:
* 十一月 02, 2017 11:40:09 上午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
* INFO: HHH000397: Using ASTQueryTranslatorFactory
*Hibernate:select count(book0_.bookid) as col_0_0_ from book book0_
* 1393
*/
}
/**
* 显示图书列表——分页
*/
@Test
public List<Book> getBooksPage(int offset,int pageSize) {
try {
session = HibernateUtil.getSession();
List<Book> books = session.createQuery("from Book")
.setFirstResult(offset)
.setMaxResults(pageSize)
.list();
return books;
//System.out.println(books);
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
HibernateUtil.closeSession(session);
}
/**
* 测试结果:
* 十一月 02, 2017 12:01:02 下午 org.hibernate.hql.internal.QueryTranslatorFactoryInitiator initiateService
INFO: HHH000397: Using ASTQueryTranslatorFactory
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 ?,
?
[Book{bookid=2, bookname='上帝掷骰子吗?', bookprice=33.66, bookauthor='曹天元', bookpress='中国科学出版社', bookdate=2017-11-02 07:44:05.0}
, Book{bookid=3, bookname='红楼梦?', bookprice=88.88, bookauthor='曹雪芹', bookpress='人民文学出版社', bookdate=2017-11-02 07:45:31.0}
, Book{bookid=4, bookname='三国演义', bookprice=77.77, bookauthor='罗贯中', bookpress='人民文学出版社', bookdate=2017-11-02 07:46:14.0}
]
*
*/
}
}
3、工具层
HibernateUitl
主要是获取session、关闭session
package com.hmc.bookmgr.util;
/**
* User:Meice
* 2017/11/1
*/
import org.hibernate.HibernateException;
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;
/**
* 这个工具类作用就是获取session
* 构建session参考官网配置
*/
public class HibernateUtil {
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的方法;为方便调用,static
public static Session getSession() {
Session session = sessionFactory.openSession();
return session;
}
//定义关闭session的方法
public static void closeSession(Session session) {
//关闭什么的,都是要先判断下
if(session != null) {
session.close();
}
}
}
StringConvertInt
把ID转换过来
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;
}
}
4、Servlet
BaseServlet——实现一个Servlet里面写多个方法
package com.hmc.bookmgr.servlet;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* User:Meice
* 2017/11/1
*/
public class BaseServlet extends HttpServlet {
@Override
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8");
String op = req.getParameter("method");
if(op !=null && !"".equals(op)) {
try {
Method method = this.getClass().getDeclaredMethod(op,HttpServletRequest.class,HttpServletResponse.class);
/**
* 调用invoke方法,自动根据方法名op调用相同名的方法
* 参数一:方法所在的对象
* 参数二:调用方法的参数
*/
method.invoke(this,req,resp);
} catch (NoSuchMethodException e) {
// e.printStackTrace();
req.getRequestDispatcher("error.jsp").forward(req,resp);
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
} else{
System.out.println("参数缺失...");
}
}
}
BookServlet——接收参数、调用方法、页面跳转
package com.hmc.bookmgr.servlet;
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 javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
/**
* User:Meice
* 2017/11/1
*/
@WebServlet(urlPatterns = "/book.do")
public class BookServlet extends BaseServlet {
/**
* 2次用BaseServlet的时候,在业务类Servlet中写
* 方法,都忘记带参(HttpServletRequest req,HttpServletResponse resp
*/
BookDao bd = new BookDao();
//定义显示图书界面方法
public void index(HttpServletRequest req,HttpServletResponse resp) {
//调用方法
List<Book> books = bd.getBooks();
//存储值
req.setAttribute("books",books);
//页面跳转
try {
req.getRequestDispatcher("index.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//增加图书
public void add(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
/**
* 这里非常明显感觉到接受参数多么的麻烦!所以,struts2就方便多了
*/
String bookname = req.getParameter("bookname");
String strBookPrice = req.getParameter("bookprice");
double bookprice =0;
if( strBookPrice !=null &&!"".equals(strBookPrice)) {
bookprice = Double.parseDouble(strBookPrice);
}
String bookauthor = req.getParameter("bookauthor");
String bookpress = req.getParameter("bookpress");
String strBookDate = req.getParameter("bookdate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date bookdate = null;
try {
bookdate = sdf.parse(strBookDate);
} catch (ParseException e) {
e.printStackTrace();
}
//调用方法
Book book = new Book(bookname,bookprice,bookauthor,bookpress,bookdate);
int result =bd.add(book);
//页面跳转
if(result>0) {
req.getRequestDispatcher("book.do?method=listBook").forward(req,resp);
}else{
req.getRequestDispatcher("book_add.jsp").forward(req,resp);
}
}
//显示图书详情与显示要修改的图书
public void detail(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
int bookid = 0;
String strBookId = req.getParameter("bookid");
String action = req.getParameter("action");
bookid = StringConvertInt.getVal(strBookId);
//调用方法
Book book = bd.getBookById(bookid).get(0);
//储存值
req.setAttribute("book",book);
//页面跳转
/**
* 这一点不同于以往的R,因为查询图书详情和显示要修改的图书界面调用方法一样,
* 怎么区别呢?就需要重新增加一个参数,根据这个参数action来决定页面最终去向
*/
if(action != null &&! "".equals(action) &&"update".equals(action)) {
req.getRequestDispatcher("book_update.jsp").forward(req,resp);
}else {
req.getRequestDispatcher("book_detail.jsp").forward(req,resp);
}
}
//修改图书
public void update(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
//这个bookid是页面连接的bookid,注意页面的隐藏域的bookid,那个才是表单提交时候用到的
int bookid = 0;
String strBookId = req.getParameter("bookid");
String action = req.getParameter("action");
bookid = StringConvertInt.getVal(strBookId);
String bookname = req.getParameter("bookname");
String strBookPrice = req.getParameter("bookprice");
double bookprice =0;
if( strBookPrice !=null &&!"".equals(strBookPrice)) {
bookprice = Double.parseDouble(strBookPrice);
}
String bookauthor = req.getParameter("bookauthor");
String bookpress = req.getParameter("bookpress");
String strBookDate = req.getParameter("bookdate");
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date bookdate = null;
try {
bookdate = sdf.parse(strBookDate);
} catch (ParseException e) {
e.printStackTrace();
}
//你看看,参数一多,类型一旦负责,接收参数有点累呢
//调用方法
//注意这里修改是根据bookid修改的,这个bookid是通过隐藏域传过来的,所以页面一定需要写,不然找不到
Book book = new Book(bookid,bookname,bookprice,bookauthor,bookpress,bookdate);
int result = bd.update(book);
//页面跳转
if(result>0) {
req.getRequestDispatcher("book.do?method=listBook").forward(req,resp);
}else {
//这里跳转也要注意下参数,如果修改不成功,要跳转到修改页面
req.getRequestDispatcher("book.do?method=detail&bookid="+bookid+"&action=update").forward(req,resp);
}
}
public void del(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
//接受参数
int bookid = 0;
String strBookId = req.getParameter("bookid");
bookid = StringConvertInt.getVal(strBookId);
//调用方法
bd.del(bookid);
//页面跳转
req.getRequestDispatcher("book.do?method=listBook").forward(req,resp);
}
/**
* 定义显示图书管理分页界面的方法
*/
public void listBook(HttpServletRequest req,HttpServletResponse resp) throws ServletException, IOException {
BookPager bp = new BookPager();
//接受参数
String strPageIndex = req.getParameter("pageIndex");
int pageIndex = StringConvertInt.getVal(strPageIndex);
pageIndex = pageIndex<1?pageIndex=1:pageIndex;
bp.setPageIndex(pageIndex);
//调用方法
List<Book> books = bd.getBooksPage(bp.getOffset(),bp.getPageSize());
//为bp中的books属性赋值
bp.setBooks(books);
//为bp中的count赋值
int count = bd.booksCount();
bp.setCount(count);
//把bp作为对象传值
req.setAttribute("bp",bp);
//页面跳转
req.getRequestDispatcher("book_page.jsp").forward(req,resp);
}
}
五、页面
book_page——分页显示全部图书信息
<%--
User: Meice
Date: 2017/11/2
Time: 11:19
--%>
<%@ 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%" align="center" border="1">
<caption><h2>Meice的图书管理系统</h2></caption>
<thead>
<tr>
<th>图书编号</th>
<th>图书名称</th>
<th>图书价格</th>
<th>出版社</th>
<th>图书作者</th>
<th>出版日期</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="book" items="${bp.books}">
<tr>
<td>${book.bookid}</td>
<td>${book.bookname}</td>
<td>${book.bookprice}</td>
<td>${book.bookpress}</td>
<td>${book.bookauthor}</td>
<td>${book.bookdate}</td>
<td align="center">
<a href="book.do?method=detail&bookid=${book.bookid}">查询</a>
<a href="book.do?method=detail&bookid=${book.bookid}&action=update">修改</a>
<a href="book.do?method=del&bookid=${book.bookid}" onclick="return confirm('真的忍心删除我麽?')">删除</a>
</td>
</tr>
</c:forEach>
<tr align="center">
<td colspan="7">
<c:if test="${bp.pageIndex>1}">
<a href="book.do?method=listBook&pageIndex=1">首页</a>
<a href="book.do?method=listBook&pageIndex=${bp.pageIndex-1}"> 上一页</a>
</c:if>
<c:forEach var="x" begin="${bp.pageIndex}" end="${bp.pageIndex+4}">
<a href="book.do?method=listBook&pageIndex=${x}">${x}</a>
</c:forEach>
<c:if test="${bp.pageIndex<bp.totalPage}">
<a href="book.do?method=listBook&pageIndex=${bp.pageIndex+1}">下一页</a>
<a href="book.do?method=listBook&pageIndex=${bp.totalPage}">末页</a>
</c:if>
</td>
</tr>
</tbody>
</table>
<a href="book_add.jsp">新增图书</a>
</body>
</html>
这里面比较核心的是要明白参数是如何传递的以及JSTL标签的灵活运用。最好写一个方法测试一下效果,及时反馈。
book_add——新增图书
<%--
User: Meice
Date: 2017/11/1
Time: 19:58
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>图书管理系统</title>
</head>
<body>
<form action="book.do?method=add" method="post">
<table width="40%" border="1" align="center">
<caption><h2>增加图书</h2></caption>
<tr>
<td align="center">书籍名称</td>
<td><input type="text" name="bookname"/></td>
</tr>
<tr>
<td align="center">书籍价格</td>
<td><input type="text" name="bookprice"/></td>
</tr>
<tr>
<td align="center">出版社</td>
<td><input type="text" name="bookpress"/></td>
</tr>
<tr>
<td align="center">书籍作者</td>
<td><input type="text" name="bookauthor"/></td>
</tr>
<tr>
<td align="center">书籍出版时间</td>
<td><input type="text" name="bookdate"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="增加书籍"/> <input type="reset"/> </td>
</tr>
<tr>
<td colspan="2" align="center"><a href="book.do?method=listBook">返回主页面</a></td>
</tr>
</table>
</form>
</body>
</html>
book_update——修改图书
<%--
User: Meice
Date: 2017/11/1
Time: 19:58
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>图书管理系统</title>
</head>
<body>
<form action="book.do?method=update" method="post">
<input type="hidden" name="bookid" value="${book.bookid}">
<table width="40%" border="1" align="center">
<caption><h2>Meice修改图书</h2></caption>
<tr>
<td align="center">书籍名称</td>
<td><input type="text" name="bookname" value="${book.bookname}"/></td>
</tr>
<tr>
<td align="center">书籍价格</td>
<td><input type="text" name="bookprice" value="${book.bookprice}"/></td>
</tr>
<tr>
<td align="center">出版社</td>
<td><input type="text" name="bookpress" value="${book.bookpress}"/></td>
</tr>
<tr>
<td align="center">书籍作者</td>
<td><input type="text" name="bookauthor" value="${book.bookauthor}"/></td>
</tr>
<tr>
<td align="center">书籍出版时间</td>
<td><input type="text" name="bookdate" value="${book.bookdate}"/></td>
</tr>
<tr>
<td colspan="2" align="center"><input type="submit" value="确认修改"/> <input type="reset"/> </td>
</tr>
<tr>
<td colspan="2" align="center"><a href="book.do?method=index">返回主页面</a></td>
</tr>
</table>
</form>
</body>
</html>
book_detail——显示图书详情
<%--
User: Meice
Date: 2017/11/1
Time: 19:58
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>图书管理系统</title>
</head>
<body>
<table width="40%" border="1" align="center">
<caption><h2>Meice图书详情</h2></caption>
<tr>
<td align="center">书籍名称</td>
<td>${book.bookname}</td>
</tr>
<tr>
<td align="center">书籍价格</td>
<td>${book.bookprice}</td>
</tr>
<tr>
<td align="center">出版社</td>
<td>${book.bookpress}</td>
</tr>
<tr>
<td align="center">书籍作者</td>
<td>${book.bookauthor}</td>
</tr>
<tr>
<td align="center">书籍出版时间</td>
<td>${book.bookdate}</td>
</tr>
<tr>
<td colspan="2" align="center"><a href="book.do?method=index">返回主页面</a></td>
</tr>
</table>
</body>
</html>
error.jsp ——错误页面跳转
<%--
User: Meice
Date: 2017/11/2
Time: 8:15
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<title>提示界面</title>
<head>
</head>
<body>
<img src="images/noMethod.png">
</body>
</html>
六、总结
1、Hibenate自动创建表,测试的时候报错,说SQL语法有问题?SQL语句是Hibernate自动打印的,怎么会出问题呢?( 2017/11/02 07:35 )
十一月 02, 2017 7:32:01 上午
Hibernate:
create table book (
bookid integer not null auto_increment,
bookauthor varchar(255),
bookdate datetime,
bookname varchar(255),
bookpress varchar(255),
bookprice double precision not null,
primary key (bookid)
) type=MyISAM
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'type=MyISAM' at line 9
这个问题把我困扰的。
1)首先查测试方法。因为我测试的时候,为了让其自动创建表,就调用了下add()方法。检查了下book对象,发现赋值没啥问题,在date类型纠结了一下;
2)把这条语句直接粘贴到控制台,发现book表还是创建不了,根据提示信息,我把type=MyISAM改为了type=InnoDB,也是不行;
3)后来…….脑子一直都是这个问题。终于灵光一现,原来是MySQL默认的表类型是ENGINE=MyISAM或者ENGINE=InnoDB;一旦Hibernate使用native自动创表策略的时候,他默认的表类型用type表示,自然搞不定啦。应该是ENGINE=MyISAM
2、如果页面跳转逻辑不清,就会导致页面重复跳转,生成大量数据;如果BaseServlet没有处理编码,数据库就会出现大量乱码;
3、这次IDEA实现了页面的自动更新,原来每次都要重启,页面才能自动更新。哈哈。
4、当多个连接调用同一个方法,但是在方法处理完毕后,返回的页面不同时候,如何处理?传参的时候多传一个,然后在页面跳转时候做判断。比如book_detail 和book_update这两个界面,开始都是调用detail方法,最后页面一个跳转到修改页面,一个跳转到book_deatil页面,所以传参的时候,修改就多传了个action的参数,根据这个判断页面最终去向。
5、增加了错误页面处理。任何Bug,只许我们自己看到,即便是Bug,也要牢牢掌控住,不然多没面子啊。
好了,午安,下期再会!
图书管理系统
本文介绍了一个基于Hibernate的图书管理系统实现过程,包括整体框架搭建、环境配置、代码编写等方面,并详细记录了开发过程中遇到的问题及解决方法。
2316

被折叠的 条评论
为什么被折叠?



