话说:
各位读者,中午好呀。有前面2篇Hibernate的博客作铺垫,今天这篇横空出世自然顺理成章啦。
目标:Hibernate实现CURD和分页。
整体思路和之前一样,只是换一个工具啦。
目录
一、整体布局
二、结果展示
三、几大板块
1、pom.xml
2、model层
3、resources
4、dao层
5、util工具层
6、servlet层
7、Web页面
四、总结
开发工具:IDEA(2017.2.5)
一、整体布局
二、结果展示
如果是第一页: 首页 上一页 就不在显示,避免后台做无效的查询;同理末页也如此处理。
第二页,就全部显示。
最后一页效果图
三、几大板块
1、pom.xml
这个作用是实现MySQL数据库的连接、实体类映射、HQL相关配置(如打印SQL语句等)、导各种包(eg:JSTL)
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.hmc.hibernate</groupId>
<artifactId>Hibernate_News</artifactId>
<packaging>war</packaging>
<version>1.0-SNAPSHOT</version>
<name>Hibernate_News Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<!--换一个高级一点的版本-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!--Hibernate core-->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.2.12.Final</version>
</dependency>
<!--Mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>RELEASE</version>
</dependency>
<!--jstl包-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
</dependencies>
<build>
<finalName>Hibernate_News</finalName>
</build>
</project>
2、model层
News——新闻的实体类
package com.hmc.hibernate_news.model;
import org.hibernate.annotations.GenericGenerator;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
/**
* User:Meice
* 2017/10/28
*/
@Entity
@Table(name = "t_news")
public class News {
private int id;
private String title;
private String author;
private String pic;
public News() {}
public News(int id,String title,String author,String pic) {
this.id = id;
this.title = title;
this.author = author;
this.pic = pic;
}
public News(String title,String author,String pic) {
this.title = title;
this.author= author;
this.pic = pic;
}
public News(String title,String author) {
this.title = title;
this.author = author;
}
public News(int id,String title,String author) {
this.id = id;
this.title = title;
this.author = author;
}
@Id
@GenericGenerator(name = "myid",strategy = "native")
@GeneratedValue(generator = "myid")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public String getPic() {
return pic;
}
public void setPic(String pic) {
this.pic = pic;
}
@Override
public String toString() {
return "News{" +
"id=" + id +
", title='" + title + '\'' +
", author='" + author + '\'' +
", pic='" + pic + '\'' +
'}';
}
}
Pager——分页的实体类
package com.hmc.hibernate_news.model;
import java.util.List;
/**
* User:Meice
* 2017/10/28
*/
public class Pager<E> {
private int totalPage;//总页数
private int pageIndex=2; //当前页
private int count;//总记录数
private int pageSize=15;//显示条目
private int offset;//分页偏移量
private int start;
private int end;
private List<E> datas;//记录数据
public Pager() {}
public Pager(int totalPage, int pageIndex, int pageSize, int offset, List<E> datas) {
this.totalPage = totalPage;
this.pageIndex = pageIndex;
this.pageSize = pageSize;
this.offset = offset;
this.datas = datas;
}
public Pager(int pageIndex, int pageSize, int offset, List<E> datas) {
this.pageIndex = pageIndex;
this.pageSize = pageSize;
this.offset = offset;
this.datas = datas;
}
public Pager(int totalPage, int pageIndex, int count, int pageSize, int offset, int start, int end, List<E> datas) {
this.totalPage = totalPage;
this.pageIndex = pageIndex;
this.count = count;
this.pageSize = pageSize;
this.offset = offset;
this.start = start;
this.end = end;
this.datas = datas;
}
public int getTotalPage() {
//我们在为属性设置值的时候,这里需要在get()方法中控制,后面类似
totalPage = (int)Math.ceil((double)(count)/pageSize);
return totalPage;
}
public void setTotalPage(int totalPage) {
this.totalPage = totalPage;
}
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 getOffset() {
//这里表明,Servlet中要注意给属性赋值的顺序
offset = (pageIndex-1)*pageSize;
return offset;
}
public void setOffset(int offset) {
this.offset = offset;
}
public int getStart() {
return start;
}
public void setStart(int start) {
this.start = start;
}
public int getEnd() {
return end;
}
public void setEnd(int end) {
this.end = end;
}
public List<E> getDatas() {
return datas;
}
public void setDatas(List<E> datas) {
this.datas = datas;
}
}
整个分页用Pager封装起来,好处不言而喻。页面显示的时候,直接.属性即可。
3、resources
hibernate.cfg.xml
在实体类加注解的时候,不要忘了在配置文件里面配置mapping
<!--
~ 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/news_db</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">119913</property>
<!--配置自动生成表-->
<property name="hibernate.hbm2ddl.auto">update</property>
<!--配置打印SQL语句-->
<property name="hibernate.show_sql">true</property>
<!--配置实体映射-->
<mapping class="com.hmc.hibernate_news.model.News"></mapping>
</session-factory>
</hibernate-configuration>
4、dao层
HibernateNewsDao
在这里面实现HibernateAPI,对比之前的JDBC的BaseDao,简直简单得爽翻天!
package com.hmc.hibernate_news.dao;
import com.hmc.hibernate_news.model.News;
import com.hmc.hibernate_news.util.HibernateUtil;
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;
import org.junit.jupiter.api.Test;
import java.util.List;
/**
* User:Meice
* 2017/10/28
*/
public class HibernateNewsDao {
Session session = null;
/**
* 查
* 查询所有
*/
@Test
public List<News> list() {
try {
session = HibernateUtil.getSession();
List<News> list = session.createQuery("from News")
.list();
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
HibernateUtil.closeSession(session);
}
}
/**
* 查
* 查询单个对象
*/
@Test
public News listOne(int id) {
try {
session = HibernateUtil.getSession();
News news =(News)session.createQuery("from News where id = :id")
.setParameter("id",id)
.uniqueResult();
return news;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally {
HibernateUtil.closeSession(session);
}
}
/**
* 增、改
* 增改删操作一定要开启事务和提交事务,这是与查最大的区别
*/
public void add(News news) {
try {
session = HibernateUtil.getSession();
session.beginTransaction();
session.saveOrUpdate(news);
session.getTransaction().commit();
System.out.println("我是增、改方法....");
} catch (Exception e) {
session.getTransaction().rollback();
}finally{
HibernateUtil.closeSession(session);
}
}
/**
* 删除
* 删除新闻
*/
public void del(int id) {
try {
session = HibernateUtil.getSession();
News news = new News();
news.setId(id);
session.beginTransaction();
session.delete(news);
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
}finally{
HibernateUtil.closeSession(session);
}
}
/**
* 分页
*
*/
@Test
public List<News> showPage(int offset,int pageSize) {
try {
session = HibernateUtil.getSession();
List<News> list = session.createQuery("from News")
.setFirstResult(offset)
.setMaxResults(pageSize)
.list();
System.out.println(list);
return list;
} catch (Exception e) {
e.printStackTrace();
return null;
}finally{
HibernateUtil.closeSession(session);
}
}
/**
* 总条目数
*
*/
@Test
public int count() {
try {
session = HibernateUtil.getSession();
//再次提醒以下:count(*)返回的是Long类型
Long countInt =(Long)session.createQuery("select count(id) from News")
.uniqueResult();
System.out.println("我是总条目数:"+countInt);
//lang.ClassCastException: java.lang.Long cannot be cast to java.lang.Integer
int count =countInt.intValue();
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}finally{
HibernateUtil.closeSession(session);
}
}
public static void main(String[] args) {
HibernateNewsDao hnd = new HibernateNewsDao();
hnd.add(new News("666","888"));
// System.out.println(news);
}
}
5、util工具层
HibernateUtil——这个作用是获取session
package com.hmc.hibernate_news.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/10/28
*/
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的方法getSession()
public static Session getSession() {
Session session = sessionFactory.openSession();
return session;
}
//定义关闭session的方法closeSession()
public static void closeSession(Session session) {
session.close();
}
}
StringConvertInt——作用:Sting类型的Id转换为整型
package com.hmc.hibernate_news.util;
/**
* User:Meice
* 2017/10/28
*/
public class StringConvertInt {
public static int getVal(String strId) {
if(strId != null && !"".equals(strId)) {
int id = Integer.parseInt(strId);
return id;
}else {
return 0;
}
}
}
6、servlet层
BaseServlet
作用:和之前一样,实现把多个Servlet写在一个Servlet里面,核心是Method的invoke()方法
package com.hmc.hibernate_news.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/10/28
*/
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("op");
if(op != null && !"".equals(op)) {
try {
Method method = this.getClass().getDeclaredMethod(op,HttpServletRequest.class,HttpServletResponse.class);
method.invoke(this,req,resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}else {
System.out.println("参数缺失...");
}
}
}
NewsServlet
处理参数、调用dao层方法及页面跳转
package com.hmc.hibernate_news.servlet;
import com.hmc.hibernate_news.dao.HibernateNewsDao;
import com.hmc.hibernate_news.model.News;
import com.hmc.hibernate_news.model.Pager;
import com.hmc.hibernate_news.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.util.List;
/**
* User:Meice
* 2017/10/28
*/
@WebServlet(urlPatterns = "/news.do")
public class NewsServlet extends BaseServlet {
HibernateNewsDao hnd = new HibernateNewsDao();
/**
* 查
* 显示新闻列表
*/
public void list(HttpServletRequest req, HttpServletResponse resp) {
//调用方法
List<News> list = hnd.list();
System.out.println("进来了");
// System.out.println(list);
//设置参数
req.setAttribute("list",list);
//页面跳转
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) {
//接收参数
String title =(String)req.getParameter("title");
String author = (String)req.getParameter("author");
System.out.println("title " + title);
System.out.println("author " + author);
News news = new News(title,author);
//调用方法
hnd.add(news);
//页面跳转
try {
req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 改
* 修改新闻
*/
//显示单个新闻
public void listOne(HttpServletRequest req,HttpServletResponse resp) {
//接收参数
String strId = req.getParameter("id");
int id = StringConvertInt.getVal(strId);
//调用方法
News news = hnd.listOne(id);
//设置参数
req.setAttribute("news",news);
//页面跳转
try {
req.getRequestDispatcher("newsUpdate.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
//执行修改操作
public void change(HttpServletRequest req, HttpServletResponse resp) {
//接收参数
String strId = req.getParameter("id");
int id = StringConvertInt.getVal(strId);
String title = req.getParameter("title");
String author = req.getParameter("author");
News news = new News(id,title,author);
//调用方法
hnd.add(news);
//页面跳转
try {
req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 删
*
*/
public void del(HttpServletRequest req,HttpServletResponse resp) {
//接收参数
String strId = req.getParameter("id");
int id = StringConvertInt.getVal(strId);
//调用方法
hnd.del(id);
//页面跳转
try {
req.getRequestDispatcher("news.do?op=listPage").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 分页显示新闻
*/
public void listPage(HttpServletRequest req,HttpServletResponse resp) {
//接受参数
String strPageIndex = req.getParameter("pageIndex");
int pageIndex = StringConvertInt.getVal(strPageIndex);
//调用方法
Pager<News> pg= new Pager<News>();
//根据页面传递的当前页来设置
pageIndex = pageIndex==0?1:pageIndex;
pg.setPageIndex(pageIndex);
//因为pageIndex会影响到count,所以需要在设置之后在调用方法
List<News> listPage = hnd.showPage(pg.getOffset(),pg.getPageSize());
pg.setDatas(listPage);
//调用总记录数方法
int count = hnd.count();
pg.setCount(count);
//设置参数
req.setAttribute("datas",pg.getDatas());
req.setAttribute("pager",pg);
req.setAttribute("totalPage",pg.getTotalPage());
//页面跳转
try {
req.getRequestDispatcher("newsPage.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
**7、Web页面
界面和之前一样。唯一需要注意的是isELIgnored=”false”
newsPage.jsp——新闻显示页面
newsAdd.jsp——发布新闻界面
newsUpdate.jsp——修改新闻界面
newsPage.jsp——新闻显示页面
<%--
User: Meice
Date: 2017/10/29
Time: 0:26
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<html>
<head>
<h2 align="center">Meice的新闻分页显示</h2>
<title>新闻分页</title>
</head>
<body>
<a href="newsAdd.jsp">发布新闻</a>
<table border="1" align="center" width="80%">
<thead>
<tr>
<th>编号</th>
<th>标题</th>
<th>作者</th>
<th>图片</th>
<th>操作</th>
</tr>
</thead>
<tbody>
<c:forEach var="news" items="${datas}">
<tr>
<td>${news.id}</td>
<td>${news.title}</td>
<td>${news.author}</td>
<td>${news.pic}</td>
<td>
<a href="news.do?op=listOne&id=${news.id}">修改</a>
<a href="news.do?op=del&id=${news.id}" onclick="return confirm('真的忍心删除么?')">删除</a>
</td>
</tr>
</c:forEach>
<tr>
<td colspan="5" align="center">
<c:if test="${pager.pageIndex>1}">
<a href="news.do?op=listPage&pageIndex=1">首页</a>
<a href="news.do?op=listPage&pageIndex=${pager.pageIndex-1}">上一页</a>
</c:if>
<c:forEach var="x" begin="${pager.pageIndex}" end="${pager.pageIndex+4}" >
<c:if test="${pager.pageIndex<pager.totalPage}">
<a href="news.do?op=listPage&pageIndex=${x}">${x}</a>
</c:if>
</c:forEach>
<c:if test="${pager.pageIndex<pager.totalPage}">
<a href="news.do?op=listPage&pageIndex=${pager.pageIndex+1}">下一页</a>
<a href="news.do?op=listPage&pageIndex=${pager.totalPage}">末页</a>
</c:if>
</td>
</tr>
</tbody>
</table>
</body>
</html>
newsAdd.jsp——发布新闻界面
<%--
User: Meice
Date: 2017/10/28
Time: 21:32
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>发布新闻</title>
</head>
<body>
<form action="news.do" method="post">
<input type="hidden" name="op" value="add">
<table>
<tr>
<td>标题</td>
<td><input type="text" name="title"></td>
</tr>
<tr>
<td>作者</td>
<td><input type="text" name="author"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="发布"></td>
</tr>
</table>
</form>
</body>
</html>
newsUpdate.jsp——修改新闻界面
<%--
User: Meice
Date: 2017/10/28
Time: 23:23
--%>
<%@ page contentType="text/html;charset=UTF-8" language="java" isELIgnored="false" %>
<html>
<head>
<title>修改新闻</title>
</head>
<body>
<form action="news.do?op=change" method="post">
<table>
<tr>
<td>编号</td>
<td><input type="text" name="id" value="${news.id}" readonly="readonly"></td>
</tr>
<tr>
<td>标题</td>
<td><input type="text" name="title" value="${news.title}"></td>
</tr>
<tr>
<td>作者</td>
<td><input type="text" name="author" value="${news.author}"></td>
</tr>
<tr>
<td colspan="2"><input type="submit" value="修改"></td>
</tr>
</table>
</form>
</body>
</html>
四、总结**
22:50 2017/10/28
1、EL表达式在Hibernate的Maven项目里的页面中,默认没有此属性,且默认关闭EL。即isELIgnored = “false”,只有开启EL,即isELIgnored=”true”,EL表达式才会生效。
2、在写BaseServlet的时候,Method.invoke()方法调用,传递参数有误,应该传递Method.invoke(当前类,request,resposne)即Method.invoke(this.req,resp);在写NewsServlet中的方法时候,开始方法忘记写参数:HttpServletRequeset req,HttpServletResponse resp;在Servlet中,request,response是至关重要的两个参数。所以BaseServlet、NewsServlet的核心就是这2个参数。
3、在表单接收参数的时候,竟然把接收参数写成了:
String author = (String) req.getAttribute(“author”);??
很无语,查了半天……
表单接收参数,要用req.getParameter好不好!
如果是自己传递的值,setAttribute()
自己接收的话,用getAttribute()
不知道怎么滴,今天总是犯一些低级错误,奇怪的是,之前怎么没有遇到过呢?
4、confirm的用法
<a href="news.do?op=del&id=${news.id}" onclick="confirm('真的忍心删除我麽?')">删除</a>
注意:这里的confirm如果没有return,不论确定还是取消,都会删除!所以,正确的写法是这样的:
<a href="news.do?op=del&id=${news.id}" onclick=" return confirm('真的忍心删除我麽?')">删除</a>
5、比较奇怪的是,一旦方法有返回值,在Hibernate API中就不好测试,怎么测试都没有结果。无法打印输出。
6、包装类要转化为基本类型,用自带的方法.intValue();
int count =countInt.intValue();
7、分页这次简化了下,简化地方在于分页安装固定步长显示;文件上传功能这次暂不实现。
好了!开午饭!
109

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



