实验六 Hibernate的体系结构——登录用户信息的增删改查
一、基础实验——Hibernate常用API
(一)实验目的
- 进一步掌握Hibernate 应用的开发方法,理解Hibernate 配置文件中主要元素的作用,会开发持久化类,并进行相应的Hibernate 映射文件配置;
- 学习并掌握Hibernate 框架的常用API,掌握利用Hibernate 基本API 载入配置文件、建立数据库连接的基本步骤;
- 理解Hibernate 基本API 中Session 的主要作用,掌握利用Session 进行数据库操作的基本步骤。
(二)基本知识与原理
- Hibernate 进行持久化操作,通常有如下操作步骤:
- 开发持久化类和映射文件;
- 获取Configuration;
- 获取SessionFactory;
- 获取Session,打开事务;
- 用面向对象的方式操作数据库;
- 关闭事务,关闭Session。
- 对PO 的操作必须在Session 管理下才能同步到数据库,Session 是应用程序与持久储存层之间交互操作的一个单线程对象,它底层封装了JDBC 连接,主要用来对PO 进行创建、读取、删除等操作;
- Session 由SessionFactory 工厂产生,SessionFactory 是数据库编译后的内存镜像,通常一个应用对应一个SessionFactory 对象;
- SessionFactory 对象由Configuration 对象生成,Configuration 对象负责加载Hibernate 配置文件,每个Hibernate 配置文件对应一个Configuration 对象。
(三)实验过程与记录
-
在阿里云RDS云数据库服务器上创建名为hibernatedb的数据库,并在数据库中创建名为customer的数据表,结构如表6-1-1所示:
表6-1-1 customer数据表 字段名称 类型 中文含义 customerid INTEGER(11),Primart key, Not Null 用户编号 account VARCHAR(20) 用户名 password VARCHAR(20) 密码 name VARCHAR(20) 真实姓名 sex BOOLeAN(1) 性别 birthday DATE 出生日期 phone VARCHAR(20) 联系电话 email VARCHAR(100) 电子邮箱 address VARCHAR(20) 联系地址 zipcode VARCHAR(10) 邮政编码 fax VARCHAR(20) 传真号码 -
IntelliJ IDEA新建Webhibernate-proj2,添加MySQL驱动陈旭库文件、commons-logging-1.2.jar、Struts2核心包和Hibernate核心包到工程中;
图6-1-2 核心jar包
-
新建配置文件hibernate.cfg.xml;
-
创建cn.edu.zjut.po包,创建持久化类Customer.java以及配置文件hibernate.cfg.xml;
-
修改hibernate.cfg.xml文件,增加Customer.hbm.xml映射文件声明;
-
新建cn.edu.zjut.dao包,创建DAO操作辅助类HibernateUtil.java,用于生成Configuration对象和SessionFactory对象:
package cn.edu.zjut.dao; import org.hibernate.Session; import org.hibernate.SessionFactory; import org.hibernate.cfg.Configuration; public class HibernateUtil { private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml"; private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>(); private static Configuration configuration = new Configuration(); private static SessionFactory sessionFactory; private static String configFile = CONFIG_FILE_LOCATION; static { try{ configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); }catch (Exception e){ System.err.println("%%% Error Creating SessionFactory %%%"); e.printStackTrace(); } } private HibernateUtil(){} public static Configuration getConfiguration() { return configuration; } public static void setConfiguration(String configFile) { HibernateUtil.configFile = configFile; sessionFactory = null; } public static SessionFactory getSessionFactory() { return sessionFactory; } public static void rebuildSessionFactory(){ try{ configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); }catch (Exception e){ System.err.println("%%% Error Creating SessionFactory %%%"); e.printStackTrace(); } } }
-
完善辅助类HibernateUtil.java,添加“获取Session对象”和“关闭Session对象”的方法:
public static Session getSession() throws HibernateException{ Session session = (Session) threadLocal.get(); if(session == null || !session.isOpen()){ if(sessionFactory == null){ rebuildSessionFactory(); } session = (sessionFactory != null)?sessionFactory.openSession():null; threadLocal.set(session); } return session; } public static void closeSession() throws HibernateException{ Session session = (Session) threadLocal.get(); threadLocal.set(null); if(session != null){ session.close(); } }
-
在cn.edu.zjut.dao包中创建BasehibernateDAO.java,作为数据库操作基础类:
package cn.edu.zjut.dao; import org.hibernate.Session; public class BaseHibernateDAO { public Session getSession(){ return HibernateUtil.getSession(); } }
-
在cn.edu.zjut.dao包中创建CustomerDAO.java,继承BaseHibernateDAO.java,在其中实现增删改查操作:
package cn.edu.zjut.dao; import cn.edu.zjut.po.Customer; import org.apache.commons.logging.LogFactory; import org.apache.commons.logging.Log; import org.hibernate.query.Query; import java.util.List; public class CustomerDAO extends BaseHibernateDAO{ private Log log = LogFactory.getLog(CustomerDAO.class); public List findByHql(String hql){ log.debug("finding Customer instance by hql"); try{ String queryString = hql; Query queryObject = getSession().createQuery(queryString); return queryObject.list(); }catch (Exception e){ log.error("find by hql failed", e); throw e; } } public void save(Customer instance){ log.debug("saving Customer instance"); try{ getSession().save(instance); log.debug("save successful"); }catch (Exception e){ log.error("save failed", e); throw e; } } public void update(Customer instance){ log.debug("updating Customer instance"); try{ getSession().update(instance); log.debug("update successful"); }catch (Exception e){ log.error("update failed", e); throw e; } } public void delete(Customer instance){ log.debug("deleting Customer instance"); try{ getSession().delete(instance); log.debug("delete successful"); }catch (Exception e){ log.error("delete failed"); throw e; } } }
-
创建cn.edu.zjut.service包,创建UserService.java,用于实现登录、注册、个人信息修改和删除逻辑:
package cn.edu.zjut.service; import cn.edu.zjut.dao.CustomerDAO; import cn.edu.zjut.po.Customer; import com.opensymphony.xwork2.ActionContext; import org.hibernate.Transaction; import java.util.List; import java.util.Map; public class UserService { private Map<String, Object> request, session; public boolean login(Customer loginUser){ ActionContext ctx = ActionContext.getContext(); session = (Map) ctx.getSession(); request = (Map) ctx.get("request"); String account = loginUser.getAccount(); String password = loginUser.getPassword(); String hql = "from Customer as user where account='" + account + "' and password='" + password + "'"; CustomerDAO dao = new CustomerDAO(); List list = dao.findByHql(hql); dao.getSession().close(); if(list.isEmpty()){ return false; } else { session.put("user", account); request.put("tip", "登录成功!"); loginUser=(Customer) list.get(0); request.put("loginUser", loginUser); return true; } } public boolean register(Customer loginUser){ ActionContext ctx = ActionContext.getContext(); session = (Map) ctx.getSession(); request = (Map) ctx.get("request"); CustomerDAO dao = new CustomerDAO(); Transaction tran = null; try{ tran = dao.getSession().beginTransaction(); dao.save(loginUser); tran.commit(); request.put("tip", "注册成功!"); return true; }catch (Exception e){ e.printStackTrace(); return false; }finally { dao.getSession().close(); } } public boolean update(Customer loginUser){ ActionContext ctx = ActionContext.getContext(); session = (Map) ctx.getSession(); request = (Map) ctx.get("request"); CustomerDAO dao = new CustomerDAO(); Transaction tran = null; try{ tran = dao.getSession().beginTransaction(); dao.update(loginUser); tran.commit(); request.put("tip", "修改个人信息成功!"); return true; }catch (Exception e){ e.printStackTrace(); return false; }finally { dao.getSession().close(); } } public boolean delete(Customer loginUser){ ActionContext ctx = ActionContext.getContext(); session = (Map) ctx.getSession(); request = (Map) ctx.get("request"); CustomerDAO dao = new CustomerDAO(); Transaction tran = null; try{ tran = dao.getSession().beginTransaction(); dao.delete(loginUser); tran.commit(); session.remove("user"); request.put("tip", "删除个人信息成功,请重新登录!"); return true; }catch (Exception e){ e.printStackTrace(); return false; }finally { dao.getSession().close(); } } }
-
新建cn.edu.zjut.action包,创建UserAction.java:
package cn.edu.zjut.action; import cn.edu.zjut.po.Customer; import cn.edu.zjut.service.UserService; public class UserAction { private Customer loginUser; public Customer getLoginUser() { return loginUser; } public void setLoginUser(Customer loginUser) { this.loginUser = loginUser; } public String login(){ UserService userService = new UserService(); if(userService.login(loginUser)){ return "loginsuccess"; } else { return "loginfail"; } } public String register(){ UserService userService = new UserService(); if(userService.register(loginUser)){ return "registersuccess"; } else{ return "registerfail"; } } public String update(){ UserService userService = new UserService(); if(userService.update(loginUser)){ return "updatesuccess"; } else{ return "updatefail"; } } public String delete(){ UserService userService = new UserService(); if(userService.delete(loginUser)){ return "deletesuccess"; } else{ return "deletefail"; } } }
-
新建login.jsp页面,作为用户登录视图:
<%-- Created by IntelliJ IDEA. User: YIYI Date: 2021/10/27 Time: 14:34 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>登录</title> </head> <body> <s:property value="#request.tip"/> <s:form action="login" method="POST"> <s:textfield name="loginUser.account" label="请输入用户名"/> <s:textfield name="loginUser.password" label="请输入密码"/> <s:submit value="登录"/> </s:form> </body> </html>
-
新建loginSuccess.jsp页面,作为登录成功视图,并在其中能修改个人信息或删除个人信息:
<%@ taglib prefix="s" uri="/struts-tags" %> <%@taglib prefix="sx" uri="/struts-dojo-tags" %> <%-- Created by IntelliJ IDEA. User: YIYI Date: 2021/10/27 Time: 14:39 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>登录成功</title> </head> <body> <s:property value="#request.tip"/> <p>修改个人信息</p> <s:form action="update" method="POST"> <s:hidden name="loginUser.customerID" value="%{#request.loginUser.customerID}"/> <s:textfield name="loginUser.account" label="用户名不能修改" value="%{#request.loginUser.account}" readonly="true"/> <s:textfield type="password" name="loginUser.password" label="密码" value="%{#request.loginUser.password}"/> <s:textfield name="loginUser.name" value="%{#request.loginUser.name}" label="用户名"/> <s:if test="#request.loginUser.sex==1"> <s:radio name="loginUser.sex" list="#{'0':'女', '1':'男'}" label="性别" value="1"/> </s:if> <s:else> <s:radio name="loginUser.sex" list="#{'0':'女', '1':'男'}" label="性别" value="0"/> </s:else> <s:textfield name="loginUser.birthday" value="%{#request.loginUser.birthday}" label="生日"/> <s:textfield name="loginUser.contactInfo.phone" label="手机号" value="%{#request.loginUser.contactInfo.phone}"/> <s:textfield name="loginUser.contactInfo.email" label="邮箱" value="%{#request.loginUser.contactInfo.email}"/> <s:textfield name="loginUser.contactInfo.address" label="地址" value="%{#request.loginUser.contactInfo.address}"/> <s:textfield name="loginUser.contactInfo.zipcode" label="邮编地址" value="%{#request.loginUser.contactInfo.zipcode}"/> <s:textfield name="loginUser.contactInfo.fax" label="传真号码" value="%{#request.loginUser.contactInfo.fax}"/> <s:submit value="修改"/> </s:form> <p>删除个人信息</p> <s:form action="delete" method="POST"> <s:hidden name="loginUser.customerID" value="%{#request.loginUser.customerID}"/> <s:submit value="删除"/> </s:form> </body> </html>
-
新建register.jsp页面,作为用户注册视图;
-
新建registerSuccess.jsp页面,作为注册成功视图;
-
新建CURDFail.jsp页面,作为”修改个人信息和删除个人信息“操作失败视图;
-
配置struts.xml文件,用于配置Action并设置页面导航,使得:
- 登录成功转向loginSuccess.jsp
- 登录失败转向login.jsp
- 注册成功转向registerSuccess.jsp
- 失败转向register.jsp
- 修改个人信息成功转向loginSuccess.jsp
- 失败转向CURDFail.jsp
- 删除成功转向login.jsp
- 失败转向CURDFail.jsp
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd"> <struts> <constant name="struts.i18n.encoding" value="UTF-8" /> <constant name="struts.enable.DynamicMethodInvocation" value="true"/> <package name="strutsBean" extends="struts-default" namespace="/"> <action name="login" class="cn.edu.zjut.action.UserAction" method="login"> <result name="loginsuccess">/loginSuccess.jsp</result> <result name="loginfail">/login.jsp</result> </action> <action name="register" class="cn.edu.zjut.action.UserAction" method="register"> <result name="registersuccess">/registerSuccess.jsp</result> <result name="registerfail">/register.jsp</result> </action> <action name="update" class="cn.edu.zjut.action.UserAction" method="update"> <result name="updatesuccess">/loginSuccess.jsp</result> <result name="updatefail">/CURDFail.jsp</result> </action> <action name="delete" class="cn.edu.zjut.action.UserAction" method="delete"> <result name="deletesuccess">/login.jsp</result> <result name="deletefail">/CURDFail.jsp</result> </action> </package> </struts>
-
编辑web.xml文件,增加Struts2核心Filter配置;
-
部署到Tomcat服务器运行:
图6-1-3 注册页面图
<center>
图6-1-4 注册成功页面图
</center>
<center>图6-1-5 数据库表</center>
<center>图6-1-6 登录</center>
<center>图6-1-7 登录成功</center>
<center>图6-1-8 修改个人信息</center>
<center>图6-1-9 修改完成</center>
<center>图6-1-10 删除个人信息</center>
<center>图6-1-11 删除后数据表图</center>
(四)实验总结
-
总结Hibernate基本AI载入配置文件、建立数据库连接并进行数据库操作的基本步骤:
- 先通过configuration.configure(configFile)读取到配置文件生产Configuration对象;
- configFile文件中填写了数据库连接的配置信息;
- 由Configuration对象创建SessionFactory()对象;
- 再由SessionFactory创建Session对象;
- 通过Session进行数据库操作;
-
总结Session中的主要方法:
- createQuery()通过HQL语言对数据库进行操作;
- save()保存数据,可以通过映射的对象进行;
- update()更新数据,可以通过映射的对象进行;
- delete()删除数据,可以通过映射的对象进行;
- close()关闭Session对象;
- isopen()判断session是否开启;
-
Service与DAO之间的调用关系:
在Service中创建DAO对象,获取DAO对象的Session对象,开启事务之后,进行事务内逻辑,完成之后关闭事务。
事务操作应位于Service中,DAO层应该专注于封装需要的数据库操作,在业务层可能会涉及复杂的事务逻辑,事务逻辑因交由Service层处理;
-
表达域中value值写法:value="%{OGNL表达式}"
-
按照实验要求将sex属性设置成了布尔类型,这样不论如何前端提交的数据始终是false,应该需要在注入数据之前转换数据类型。
二、基础实验——HQL语言
(一)实验目的
- 学习HQL 的使用方法,掌握select 子句、from 子句、where 子句、order by子句、聚合函数、group by 子句、子查询等基本语法并能正确运用;
- 理解HQL 语言是一种面向对象的查询语言,能正确区分HQL 语言与SQL 语言的差别。
(二)基本知识与原理
- HQL(Hibernate Query Language)语言是Hibernate 框架定义的查询语言;
- HQL 语言的语法结构与SQL 语言非常类似,但HQL 是面向对象的查询语言,HQL 语句中使用的是Java 类名和属性名,大小写敏感;
- HQL 语言包括select 子句、from 子句、where 子句、order by 子句、聚合函数、group by 子句、子查询、连接查询等。
(三)实验过程与记录
-
在hibernatedb数据库中创建名为item的数据表,结构如下:
表6-2-1 item数据表 字段名称 类型 中文含义 isbn VARCHAR(20),Primary key,Not Null ISBN号 title VARCHAR(30) 书名 description VARCHAR(100) 说明 cost FLOAT 单价 image BLOB 图片 -
在表item中添加2条记录,具体如表所示:
表6-2-2 item中的记录 ISBN号 书名 说明 单价 978-7-121-12345-1 JAVAEE技术实验指导教程 WEB程序设计知识回顾、轻量级JAVAEE应用框架、企业级EJB组件编程技术、JAVAEE综合应用开发. 19.95 978-7-121-12345-2 JAVAEE技术 Struts框架、Hibernate框架、Spring框架、会话Bean、实体Bean、消息驱动Bean 29.95 -
在cn.edu.zjut.po包中创建持久化类Item.java及其Hibernate映射文件Item.hbm.xml;
-
修改hibernate.cfg.xml,增加Item.hbm.xml映射文件的声明;
-
在cn.edu.zjut.dao中创建数据库操作类ItemDAO.java,继承数据库操作基础类BaseHibernateDAO.java:
package cn.edu.zjut.dao; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.hibernate.query.Query; import java.util.List; public class ItemDAO extends BaseHibernateDAO{ private static final Log log = LogFactory.getLog(CustomerDAO.class); public List findByHql(String hql){ log.debug("finding Item instance by hql"); try{ String queryString = hql; Query queryObject = getSession().createQuery(queryString); return queryObject.list(); }catch (Exception e){ log.error("find by hql failed", e); throw e; } } }
-
在cn.edu,zjut.service中创建ItemService.java,使用from子句实现最简单查询,获取所有商品信息:
package cn.edu.zjut.service; import cn.edu.zjut.dao.ItemDAO; import java.util.ArrayList; import java.util.List; public class ItemService { private List items = new ArrayList(); public List findByHql(){ ItemDAO dao = new ItemDAO(); String hql = "from cn.edu.zjut.po.Item"; List list = dao.findByHql(hql); dao.getSession().close(); return list; } }
-
在cn.edu.zjut.action中 创建ItemAction.java,并在其中定义findItems()方法用于调用“获取商品信息”逻辑:
package cn.edu.zjut.action; import cn.edu.zjut.service.ItemService; import java.util.List; public class ItemAction { private List items; public List getItems() { return items; } public void setItems(List items) { this.items = items; } public String findItems(){ ItemService itemService = new ItemService(); items = itemService.findByHql(); System.out.println("Item Action executed!"); return "success"; } }
-
创建itemList.jsp页面,作为商品信息展示视图:
<%-- Created by IntelliJ IDEA. User: yiyi Date: 2021/10/28 Time: 16:19 To change this template use File | Settings | File Templates. --%> <%@ page contentType="text/html;charset=UTF-8" language="java" %> <%@taglib prefix="s" uri="/struts-tags" %> <html> <head> <title>商品列表</title> </head> <body> <center>商品列表</center> <table border=1> <tr> <th>编号</th> <th>书名</th> <th>说明</th> <th>单价</th> </tr> <s:iterator value="items" > <tr> <td><s:property value="ipk.isbn"/></td> <td><s:property value="ipk.title"/></td> <td><s:property value="description"/></td> <td><s:property value="cost"/></td> </tr> </s:iterator> </table> </body> </html>
-
修改loginSuccess.jsp页面,增加超链接查看商品信息:
<a href="findItems.action">查看商品信息</a>
-
修改struts2的struts.xml文件,增加ItemAction的配置并设置页面导航;
-
部署到Tomcat服务器运行:
图6-2-3 查询所有Item
-
修改ItemService.java,将hql语句替换成"form Item":
String hql = "from Item";
-
重新部署到Tomcat服务器运行:
图6-2-4 修改hql之后
-
修改ItemService.java,将hql语句替换成"from Item as item",以便在其它地方使用;
String hql = "from Item as item";
-
重新部署到Tomcat服务器运行:
图6-2-4 用as取名之后
-
修改ItemService.java中的hql语句,使用select子句查询商品名称:
String hql = "select item.ipk.title from Item as item";
-
因为通过select子句只返回了title属性,结果被封装到了List集合中,需要修改itemList.jsp:
<table border=1> <tr> <th>书名</th> </tr> <s:iterator value="items" id="title"> <tr> <td><s:property value="title"/></td> </tr> </s:iterator> </table>
-
重新部署到Tomcat服务器上运行:
图6-2-5 只返回title属性
-
修改ItemService.java中的hql语句,使用select子句查询商品名称和商品价格:
String hql = "select item.ipk.title, item.cost from Item as item";
-
若select子句返回多个属性,则返回结果将被封装到List<Object[]>集合中,因此需要修改itemList.jsp页面,显示商品名称和商品价格:
<table border=1> <tr> <th>书名</th> <th>单价</th></tr> <s:iterator value="items" id="object"> <tr> <td><s:property value="#object[0]"/></td> <td><s:property value="#object[1]"/></td> </tr> </s:iterator> </table>
-
重新部署到Tomcat服务器上运行:
图6-2-6 select子句返回多个属性值
-
使用order属性,按照单价降序:
String hql = "select item.ipk.title, item.cost from Item as item order by cost desc";
-
重新部署到Tomcat服务器上运行:
图6-2-7 按照单价降序
(四)实验总结
HQL常用语法及语法规则:
- from子句:从持久化类中选出全部实例;
- select子句: 选择需要筛选出的列;
- 聚集函数:可以如sql一般使用avg、count、min、max、sum等函数;
- where子句:如sql一般定义查询条件;
- order by子句:按指定列升序或降序排列;
- group by子句:将查询结果分组;
遇到的问题总结:
- 没有加上标签库引入语句,导致标签无法正常获取数据;
- 因为采用了将isbn与title作为主键,需要修改路径才能正确访问;
三、基础实验——深入Hibernate配置文件
(一)实验目的
- 深入学习Hibernate 配置文件中的配置属性,了解数据库连接池配置等可选配置属性的作用;
- 深入学习Configuration 对象,能通过编程方式创建Configuration 实例并为该对象设置一系列属性。
(二)基本知识与原理
-
Hibernate 配置文件中包括JDBC 连接属性、数据库方言、Hibernate 事务属性、二级缓存等配置属性;
-
一个Configuration 实例代表了一个应用程序中Java 类型到SQL 数据库映射的完整集合;
-
每个Hibernate 配置文件对应一个Configuration 对象,但在没有任何配置文件的情况下,也可以通过编程方式创建Configuration 对象;
-
Configuration 对象提供了若干方法,如:
(1)Configuration addResource(String resourceName):用于为Configuration 对象添加一个映射文件;
(2)Configuration setProperty(String property, String value):用于为Configuration对象设置属性。
(三)实验过程与记录
-
修改hibernate.cfg.xml,增加配置属性,使得能在控制台输出Hibernate生成的SQL语句,并在其中添加有助于调试的注释:
<property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.use_sql_comments">true</property>
-
重新部署到Tomcat服务器,查看登录时候的SQL语句:
图6-3-1 生产的SQL语句
-
修改hibernate.cfg.xml,增加C3P0连接池配置属性:
<property name="connection.autocommit">true</property> <property name="hibernate.c3p0.max_size">20</property> <property name="hibernate.c3p0.min_size">1</property> <property name="hibernate.c3p0.timeout">2000</property> <property name="hibernate.c3p0.max_statements">50</property>
-
重新部署到Tomcat服务器,登录时查看控制台的相关输出(INFO):
图6-3-2 控制台相关输出
-
删除Hibernate配置文件hibernate.cfg.xml;
-
修改HibernateUtil.java,通过编程方式创建Configuration对象:
static { try{ configuration //通过setProperty 方法设置Hibernate 的连接属性 .setProperty("hibernate.connection.driver_class", "com.mysql.cj.jdbc.Driver") .setProperty("hibernate.connection.url", "jdbc:mysql://rm-bp10ju74719fp6g4emo.mysql.rds.aliyuncs.com:3306/hibernatedb?serverTimezone=GMT%2B8&useSSL=false") .setProperty("hibernate.connection.username", "yiyi1333") .setProperty("hibernate.connection.password", "zzy@15712651279") .setProperty("hibernate.dialect", "org.hibernate.dialect.MySQLDialect") .setProperty("hibernate.show_sql", "true") .setProperty("hibernate.format_sql", "true") .setProperty("hibernate.use_sql_comments", "true") .setProperty("hibernate.connection.autocommit", "true") .setProperty("hibernate.c3p0.max_size", "20") .setProperty("hibernate.c3p0.min_size", "1") .setProperty("hibernate.c3p0.timeout", "2000") .setProperty("hibernate.c3p0.max_statements", "50") //通过addResource 方法添加映射文件 .addResource("cn/edu/zjut/po/Customer.hbm.xml") .addResource("cn/edu/zjut/po/Item.hbm.xml"); sessionFactory = configuration.buildSessionFactory(); }catch (Exception e){ System.err.println("%%% Error Creating SessionFactory %%%"); e.printStackTrace(); } }
-
重新部署到Tomcat服务器运行:
图6-3-3 删除hibernate.cfg.xml改用Configuration对象方式
-
删除hibernatedb中的customer数据表;
-
在HibernateUtil.java中增加hibernate.hbm2ddl.auto配置属性.使得能根据映射文件自动建立数据库表:
configuration ...... .setProperty("hibernate.hbm2ddl.auto", "create-drop") //通过addResource 方法添加映射文件 .addResource("cn/edu/zjut/po/Customer.hbm.xml") .addResource("cn/edu/zjut/po/Item.hbm.xml");
-
重新部署到Tomcat服务器上运行:
图6-3-4 注册数据
<center>图6-3-5 创建数据表失败</center>
-
修改hibernate方言:
.setProperty("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect")
-
重新运行:
图6-3-6 数据表创建成功
(四)实验总结
-
配置属性作用:
- hibernate.connection.driver_class:数据库驱动类
- hibernate.connection.url:数据库url
- hibernate.connection.username:数据库账号
- hibernate.connection.password:数据库密码
- hibernate.show_sql:控制台显示sql语句
- hibernate.format_sql:格式化显示sql语句
- hibernate.use_sql_comments:生成有助于调试的注释信息
- hibernate.c3p0.max_size:最大连接数
- hibernate.c3p0.min_size:最小连接数
- hibernate.c3p0.timeout:连接超时时间
-
hibernate.hbm2ddl.auto配置属性及其取值作用:
- create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
- create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
- update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
- validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
-
编程方式创建Configuration:通过setProperty设置参数,通过addResource增加数据库映射文件
-
通过编程的方式创建Configuration是通过动态的方式,其参数可以比较自由变动,而通过配置文件创建则是静态方式。
-
关于hibernate.hbm2ddl.auto创建时的失败:
hibernate的三个默认方言(MySQL):
- org.hibernate.dialect.MySQLDialect
- org.hibernate.dialect.MySQLInnoDBDialect
- org.hibernate.dialect.MySQLMyISAMDialect
因为使用的是mysql8.0,所以以上的方言会失败,需要使用以下方言:
- org.hibernate.dialect.MySQL5Dialect
- org.hibernate.dialect.MySQL5InnoDBDialect
MySQL5Dialect方言默认使用MylSAM引擎建表,MySQL5LnnoDBDialect使用InnoDB引擎建表。