JavaEE第六次实验

实验六 Hibernate的体系结构——登录用户信息的增删改查

一、基础实验——Hibernate常用API

(一)实验目的

  1. 进一步掌握Hibernate 应用的开发方法,理解Hibernate 配置文件中主要元素的作用,会开发持久化类,并进行相应的Hibernate 映射文件配置;
  2. 学习并掌握Hibernate 框架的常用API,掌握利用Hibernate 基本API 载入配置文件、建立数据库连接的基本步骤;
  3. 理解Hibernate 基本API 中Session 的主要作用,掌握利用Session 进行数据库操作的基本步骤。

(二)基本知识与原理

  1. Hibernate 进行持久化操作,通常有如下操作步骤:
    1. 开发持久化类和映射文件;
    2. 获取Configuration;
    3. 获取SessionFactory;
    4. 获取Session,打开事务;
    5. 用面向对象的方式操作数据库;
    6. 关闭事务,关闭Session。
  2. 对PO 的操作必须在Session 管理下才能同步到数据库,Session 是应用程序与持久储存层之间交互操作的一个单线程对象,它底层封装了JDBC 连接,主要用来对PO 进行创建、读取、删除等操作;
  3. Session 由SessionFactory 工厂产生,SessionFactory 是数据库编译后的内存镜像,通常一个应用对应一个SessionFactory 对象;
  4. SessionFactory 对象由Configuration 对象生成,Configuration 对象负责加载Hibernate 配置文件,每个Hibernate 配置文件对应一个Configuration 对象。

(三)实验过程与记录

  1. 在阿里云RDS云数据库服务器上创建名为hibernatedb的数据库,并在数据库中创建名为customer的数据表,结构如表6-1-1所示:

    表6-1-1 customer数据表
    字段名称类型中文含义
    customeridINTEGER(11),Primart key, Not Null用户编号
    accountVARCHAR(20)用户名
    passwordVARCHAR(20)密码
    nameVARCHAR(20)真实姓名
    sexBOOLeAN(1)性别
    birthdayDATE出生日期
    phoneVARCHAR(20)联系电话
    emailVARCHAR(100)电子邮箱
    addressVARCHAR(20)联系地址
    zipcodeVARCHAR(10)邮政编码
    faxVARCHAR(20)传真号码
  2. IntelliJ IDEA新建Webhibernate-proj2,添加MySQL驱动陈旭库文件、commons-logging-1.2.jar、Struts2核心包和Hibernate核心包到工程中;

    图6-1-2 核心jar包

image-20211030232031692

  1. 新建配置文件hibernate.cfg.xml;

  2. 创建cn.edu.zjut.po包,创建持久化类Customer.java以及配置文件hibernate.cfg.xml;

  3. 修改hibernate.cfg.xml文件,增加Customer.hbm.xml映射文件声明;

  4. 新建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();
            }
        }
    }
    
    
  5. 完善辅助类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();
            }
        }
    
  6. 在cn.edu.zjut.dao包中创建BasehibernateDAO.java,作为数据库操作基础类:

    package cn.edu.zjut.dao;
    
    import org.hibernate.Session;
    
    public class BaseHibernateDAO {
        public Session getSession(){
            return HibernateUtil.getSession();
        }
    }
    
    
  7. 在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;
            }
        }
    }
    
  8. 创建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();
            }
        }
    }
    
    
  9. 新建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";
            }
        }
    }
    
    
  10. 新建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>
    
    
  11. 新建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>
    
    
  12. 新建register.jsp页面,作为用户注册视图;

  13. 新建registerSuccess.jsp页面,作为注册成功视图;

  14. 新建CURDFail.jsp页面,作为”修改个人信息和删除个人信息“操作失败视图;

  15. 配置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>
    
  16. 编辑web.xml文件,增加Struts2核心Filter配置;

  17. 部署到Tomcat服务器运行:

    图6-1-3 注册页面图

image-20211027220153236

<center>
    图6-1-4 注册成功页面图
</center>

image-20211027212357201

<center>图6-1-5 数据库表</center>

image-20211027220316600

<center>图6-1-6 登录</center>

image-20211027213352631

<center>图6-1-7 登录成功</center>

image-20211027220257043

<center>图6-1-8 修改个人信息</center>

image-20211027220424777

<center>图6-1-9 修改完成</center>

image-20211027220455026

<center>图6-1-10 删除个人信息</center>

image-20211027220607243

<center>图6-1-11 删除后数据表图</center>

image-20211027220535922

(四)实验总结

  1. 总结Hibernate基本AI载入配置文件、建立数据库连接并进行数据库操作的基本步骤:

    1. 先通过configuration.configure(configFile)读取到配置文件生产Configuration对象;
    2. configFile文件中填写了数据库连接的配置信息;
    3. 由Configuration对象创建SessionFactory()对象;
    4. 再由SessionFactory创建Session对象;
    5. 通过Session进行数据库操作;
  2. 总结Session中的主要方法:

    1. createQuery()通过HQL语言对数据库进行操作;
    2. save()保存数据,可以通过映射的对象进行;
    3. update()更新数据,可以通过映射的对象进行;
    4. delete()删除数据,可以通过映射的对象进行;
    5. close()关闭Session对象;
    6. isopen()判断session是否开启;
  3. Service与DAO之间的调用关系:

    在Service中创建DAO对象,获取DAO对象的Session对象,开启事务之后,进行事务内逻辑,完成之后关闭事务。

    事务操作应位于Service中,DAO层应该专注于封装需要的数据库操作,在业务层可能会涉及复杂的事务逻辑,事务逻辑因交由Service层处理;

  4. 表达域中value值写法:value="%{OGNL表达式}"

  5. 按照实验要求将sex属性设置成了布尔类型,这样不论如何前端提交的数据始终是false,应该需要在注入数据之前转换数据类型。

二、基础实验——HQL语言

(一)实验目的

  1. 学习HQL 的使用方法,掌握select 子句、from 子句、where 子句、order by子句、聚合函数、group by 子句、子查询等基本语法并能正确运用;
  2. 理解HQL 语言是一种面向对象的查询语言,能正确区分HQL 语言与SQL 语言的差别。

(二)基本知识与原理

  1. HQL(Hibernate Query Language)语言是Hibernate 框架定义的查询语言;
  2. HQL 语言的语法结构与SQL 语言非常类似,但HQL 是面向对象的查询语言,HQL 语句中使用的是Java 类名和属性名,大小写敏感;
  3. HQL 语言包括select 子句、from 子句、where 子句、order by 子句、聚合函数、group by 子句、子查询、连接查询等。

(三)实验过程与记录

  1. 在hibernatedb数据库中创建名为item的数据表,结构如下:

    表6-2-1 item数据表
    字段名称类型中文含义
    isbnVARCHAR(20),Primary key,Not NullISBN号
    titleVARCHAR(30)书名
    descriptionVARCHAR(100)说明
    costFLOAT单价
    imageBLOB图片
  2. 在表item中添加2条记录,具体如表所示:

    表6-2-2 item中的记录
    ISBN号书名说明单价
    978-7-121-12345-1JAVAEE技术实验指导教程WEB程序设计知识回顾、轻量级JAVAEE应用框架、企业级EJB组件编程技术、JAVAEE综合应用开发.19.95
    978-7-121-12345-2JAVAEE技术Struts框架、Hibernate框架、Spring框架、会话Bean、实体Bean、消息驱动Bean29.95
  3. 在cn.edu.zjut.po包中创建持久化类Item.java及其Hibernate映射文件Item.hbm.xml;

  4. 修改hibernate.cfg.xml,增加Item.hbm.xml映射文件的声明;

  5. 在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;
            }
        }
    
    }
    
    
  6. 在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;
        }
    }
    
    
  7. 在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";
        }
    }
    
    
  8. 创建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>
    
    
  9. 修改loginSuccess.jsp页面,增加超链接查看商品信息:

    <a href="findItems.action">查看商品信息</a>
    
  10. 修改struts2的struts.xml文件,增加ItemAction的配置并设置页面导航;

  11. 部署到Tomcat服务器运行:

    图6-2-3 查询所有Item

image-20211028164204010

  1. 修改ItemService.java,将hql语句替换成"form Item":

    String hql = "from Item";
    
  2. 重新部署到Tomcat服务器运行:

    图6-2-4 修改hql之后

image-20211028193042080

  1. 修改ItemService.java,将hql语句替换成"from Item as item",以便在其它地方使用;

    String hql = "from Item as item";
    
  2. 重新部署到Tomcat服务器运行:

    图6-2-4 用as取名之后

image-20211028193316341

  1. 修改ItemService.java中的hql语句,使用select子句查询商品名称:

    String hql = "select item.ipk.title from Item as item";
    
  2. 因为通过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>
    
  3. 重新部署到Tomcat服务器上运行:

    图6-2-5 只返回title属性

image-20211028195303184

  1. 修改ItemService.java中的hql语句,使用select子句查询商品名称和商品价格:

    String hql = "select item.ipk.title, item.cost from Item as item";
    
  2. 若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>
    
  3. 重新部署到Tomcat服务器上运行:

    图6-2-6 select子句返回多个属性值

image-20211028195955720

  1. 使用order属性,按照单价降序:

    String hql = "select item.ipk.title, item.cost from Item as item order by cost desc";
    
  2. 重新部署到Tomcat服务器上运行:

    图6-2-7 按照单价降序

image-20211028201659828

(四)实验总结

HQL常用语法及语法规则:

  1. from子句:从持久化类中选出全部实例;
  2. select子句: 选择需要筛选出的列;
  3. 聚集函数:可以如sql一般使用avg、count、min、max、sum等函数;
  4. where子句:如sql一般定义查询条件;
  5. order by子句:按指定列升序或降序排列;
  6. group by子句:将查询结果分组;

遇到的问题总结:

  1. 没有加上标签库引入语句,导致标签无法正常获取数据;
  2. 因为采用了将isbn与title作为主键,需要修改路径才能正确访问;

三、基础实验——深入Hibernate配置文件

(一)实验目的

  1. 深入学习Hibernate 配置文件中的配置属性,了解数据库连接池配置等可选配置属性的作用;
  2. 深入学习Configuration 对象,能通过编程方式创建Configuration 实例并为该对象设置一系列属性。

(二)基本知识与原理

  1. Hibernate 配置文件中包括JDBC 连接属性、数据库方言、Hibernate 事务属性、二级缓存等配置属性;

  2. 一个Configuration 实例代表了一个应用程序中Java 类型到SQL 数据库映射的完整集合;

  3. 每个Hibernate 配置文件对应一个Configuration 对象,但在没有任何配置文件的情况下,也可以通过编程方式创建Configuration 对象;

  4. Configuration 对象提供了若干方法,如:

    (1)Configuration addResource(String resourceName):用于为Configuration 对象添加一个映射文件;

    (2)Configuration setProperty(String property, String value):用于为Configuration对象设置属性。

(三)实验过程与记录

  1. 修改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>
    
  2. 重新部署到Tomcat服务器,查看登录时候的SQL语句:

    图6-3-1 生产的SQL语句

image-20211028212413870

  1. 修改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>
    
  2. 重新部署到Tomcat服务器,登录时查看控制台的相关输出(INFO):

    图6-3-2 控制台相关输出

image-20211028212809539

  1. 删除Hibernate配置文件hibernate.cfg.xml;

  2. 修改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();
            }
        }
    
  3. 重新部署到Tomcat服务器运行:

    图6-3-3 删除hibernate.cfg.xml改用Configuration对象方式

image-20211028215403828

  1. 删除hibernatedb中的customer数据表;

  2. 在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");
    
  3. 重新部署到Tomcat服务器上运行:

    图6-3-4 注册数据

image-20211028220449457

<center>图6-3-5 创建数据表失败</center>

image-20211029001926960

  1. 修改hibernate方言:

                        .setProperty("hibernate.dialect",
                                "org.hibernate.dialect.MySQL5InnoDBDialect")
    
  2. 重新运行:

    图6-3-6 数据表创建成功

image-20211030230613769

(四)实验总结

  1. 配置属性作用:

    • 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:连接超时时间
  2. hibernate.hbm2ddl.auto配置属性及其取值作用:

    • create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。
    • create-drop:每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。
    • update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。
    • validate:每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。
  3. 编程方式创建Configuration:通过setProperty设置参数,通过addResource增加数据库映射文件

  4. 通过编程的方式创建Configuration是通过动态的方式,其参数可以比较自由变动,而通过配置文件创建则是静态方式。

  5. 关于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引擎建表。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yiyiqwq

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值