• 慕课网Hibernate初探之一对多映射实验及总结


    慕课网Hibernate初探之一对多映射实验及总结

    一、本课核心

    * 1、如何在MyEclipse中使用Hibernate
    * 2、如何实现Hibernate中一对多的映射
    * 3、如何创建Session对象
    * 4、Hibernate如何使用增删改查

    1、如何在MyEclipse中使用Hibernate

    * Hibernat框架创建
    * MyEclipse2016 CI 7版本
    * Hibernate release-5.2.10.Final
    * 方法一:自动创建
    * 1、新建一个Java项目
    * 2、右击项目,选择myeclipse,选择hibernate支持Project Facets[Capabilities]
    * 3、然后点下一步就给你创建好了
    *
    * 方法二:手动创建
    * 1、将需要的hibernate包以及MySql的jdbc添加并创建好路径(hibernate中lib中的required文件夹中的所有包)
    * 2、在hebernate解压缩包下进行检索cfg.xml,找到配置文件
    * 3、修改配置文件
    * 4、在MyEclipse中创建sql文件
    * 5、创建持久化类,也就是对应的实体类
    * 6、创建映射文件,也可以在hebernate解压缩包下进行检索hbm.xml,拷到实体包下

    2、如何实现Hibernate中一对多的映射

     1     //在一方(班级)去定义一个多方(学生)的集合来表示一对多的关系
     2     //set集合元素不能重复
     3     private Set<Student> students = new HashSet<Student>();
     4     /*
     5      * 总结:
     6      * 一对多映射的核心:
     7      * 通过在grade中添加student的集合来实现
     8      * 1、grade里面的这个集合类,需要映射的时候给这个类里面加学生
     9      * 2、grade这个类对应的映射文件中的
    10      * <!-- 配置单向的一对多关联关系 -->
    11         <set name="students" table="students">
    12             <!-- 指定关联的外键列 -->
    13             <key > 
    14                 <column name="gid"></column>
    15             </key>
    16             <!-- 指定一对多的类名 -->
    17             <one-to-many class="com.imooc.entity.Student" />
    18         </set>
    19      */

    3、如何创建Session对象

    * 创建会话,四步:
    * 1、建立配置文件对象,处理我们写的那些配置文件,包括数据库配置文件和映射文件
    * 2、开启Hibernate服务,就像我们生活中用什么东西要开启什么样的服务一样,而且要注册
    * 3、创建会话工厂
    * 4、创建会话

    1         //创建配置对象
    2 Configuration config = new Configuration().configure();
    3         //创建服务注册对象
    4 ServiceRegistry serviceRegistry =  new 
    5                 StandardServiceRegistryBuilder().applySettings(config.getProperties()).configure().build();//这里有点不一样
    6         //创建会话工厂对象
    7 sessionFactory = config.buildSessionFactory(serviceRegistry);
    8 session = sessionFactory.openSession();

    4、Hibernate如何使用增删改查

    Session使用:save():(增) delete():(删) update():(改) get()/load():(查)

    二、实例代码

    1、数据库配置文件:hibernate.cfg.xml

     1 <!--
     2   ~ Hibernate, Relational Persistence for Idiomatic Java
     3   ~
     4   ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
     5   ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
     6   -->
     7 <!DOCTYPE hibernate-configuration PUBLIC
     8         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     9         "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    10 
    11 <hibernate-configuration>
    12     <session-factory>
    13         <property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
    14         <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
    15         <property name="hibernate.connection.username">root</property>
    16         <property name="hibernate.connection.password">1314</property>
    17         <property name="hibernate.connection.url">
    18             <![CDATA[
    19                 jdbc:mysql://localhost:3306/Hibernate2?useUnicode=true&characterEncoding=utf8
    20             ]]>
    21         </property>
    22         
    23         <property name="show_sql">true</property>
    24         <property name="hbm2ddl.auto">update</property>
    25         
    26         <!-- 指定映射文件的路径 -->
    27         <mapping resource="Grade.hbm.xml" />
    28         <mapping resource="Student.hbm.xml" />
    29         
    30         
    31     </session-factory>
    32 </hibernate-configuration>

    2、实体类一Student.java

     1 package com.imooc.entity;
     2 
     3 import java.io.Serializable;
     4 
     5 public class Student implements Serializable {
     6     private int sid; //学生id
     7     private String sname; //学生姓名
     8     private String sex; //性别
     9     
    10     //构造函数
    11     
    12     public Student() {
    13         super();
    14     }
    15     
    16     
    17     public Student(String sname, String sex) {
    18         super();
    19         this.sname = sname;
    20         this.sex = sex;
    21     }
    22 
    23 
    24     public int getSid() {
    25         return sid;
    26     }
    27     
    28     public void setSid(int sid) {
    29         this.sid = sid;
    30     }
    31     public String getSname() {
    32         return sname;
    33     }
    34     public void setSname(String sname) {
    35         this.sname = sname;
    36     }
    37     public String getSex() {
    38         return sex;
    39     }
    40     public void setSex(String sex) {
    41         this.sex = sex;
    42     }
    43     
    44     
    45 }

    3、Student类对应的映射文件 Student.hbm.xml

     1 <?xml version="1.0"?>
     2 
     3 <!DOCTYPE hibernate-mapping PUBLIC
     4     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     5     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     6     
     7 <!-- 配置的是学生到班级的单向的一对多 -->
     8 <hibernate-mapping>
     9     <class name="com.imooc.entity.Student" table="student">
    10     <!-- name是类名,table是那么对应的类对应的数据库中的表名 -->
    11     <!-- id是主键 -->
    12         <id name="sid" type="java.lang.Integer">
    13             <column name="sid"></column>
    14             <generator class="increment"></generator> 
    15             <!-- generator是主键生成策略 increment查找主键最大值,并且在最大值的基础上加1 -->
    16         </id>
    17         <property name="sname" type="java.lang.String">
    18             <column name="sname" length="20" not-null="true"></column>
    19         </property>
    20         <property name="sex">
    21             <column name="sex"></column>
    22         </property>
    23         
    24     </class>
    25     
    26 </hibernate-mapping>

    4、班级实体类 Grade.java

     1 package com.imooc.entity;
     2 
     3 import java.io.Serializable;
     4 import java.util.HashSet;
     5 import java.util.Set;
     6 
     7 //班级类
     8 //添加集合表示一对多的关系
     9 public class Grade implements Serializable {
    10     private int gid; //班级id
    11     private String gname; //班级名
    12     private String gdesc; //班级描述
    13     
    14     //在一方(班级)去定义一个多方(学生)的集合来表示一对多的关系
    15     //set集合元素不能重复
    16     private Set<Student> students = new HashSet<Student>();
    17     /*
    18      * 总结:
    19      * 一对多映射的核心:
    20      * 通过在grade中添加student的集合来实现
    21      * 1、grade里面的这个集合类,需要映射的时候给这个类里面加学生
    22      * 2、grade这个类对应的映射文件中的
    23      * <!-- 配置单向的一对多关联关系 -->
    24         <set name="students" table="students">
    25             <!-- 指定关联的外键列 -->
    26             <key > 
    27                 <column name="gid"></column>
    28             </key>
    29             <!-- 指定一对多的类名 -->
    30             <one-to-many class="com.imooc.entity.Student" />
    31         </set>
    32      */
    33     
    34     //构造方法
    35     public Grade(int gid, String gname, String gdesc, Set<Student> students) {
    36         super();
    37         this.gid = gid;
    38         this.gname = gname;
    39         this.gdesc = gdesc;
    40         this.students = students;
    41     }
    42 
    43     
    44     public Grade(String gname, String gdesc) {
    45         super();
    46         this.gname = gname;
    47         this.gdesc = gdesc;
    48     }
    49 
    50 
    51     public Grade() {
    52         super();
    53     }
    54     
    55     
    56     
    57 
    58     public int getGid() {
    59         return gid;
    60     }
    61 
    62 
    63 
    64     public void setGid(int gid) {
    65         this.gid = gid;
    66     }
    67 
    68     public String getGname() {
    69         return gname;
    70     }
    71 
    72     public void setGname(String gname) {
    73         this.gname = gname;
    74     }
    75 
    76     public String getGdesc() {
    77         return gdesc;
    78     }
    79 
    80     public void setGdesc(String gdesc) {
    81         this.gdesc = gdesc;
    82     }
    83 
    84     public Set<Student> getStudents() {
    85         return students;
    86     }
    87 
    88     public void setStudents(Set<Student> students) {
    89         this.students = students;
    90     }
    91     
    92     
    93 }

    5、班级实体类对应的映射文件 Grade.hbm.xml

     1 <?xml version="1.0"?>
     2 
     3 <!DOCTYPE hibernate-mapping PUBLIC
     4     "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     5     "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
     6     
     7 <hibernate-mapping>
     8 
     9     <class name="com.imooc.entity.Grade" table="grade">
    10     <!-- name是类名,table是那么对应的类对应的数据库中的表名 -->
    11     <!-- id是主键 -->
    12         <id name="gid"  type="java.lang.Integer">
    13             <column name="gid"></column>
    14             <generator class="increment"></generator> 
    15             <!-- generator是主键生成策略 increment查找主键最大值,并且在最大值的基础上加1 -->
    16         </id>
    17         <property name="gname" type="java.lang.String">
    18             <column name="gname" length="20" not-null="true"></column>
    19         </property>
    20         <property name="gdesc">
    21             <column name="gdesc"></column>
    22         </property>
    23         <!-- 配置单向的一对多关联关系 -->
    24         <set name="students" table="students">
    25             <!-- 指定关联的外键列 -->
    26             <key > 
    27                 <column name="gid"></column>
    28             </key>
    29             <!-- 指定一对多的类名 -->
    30             <one-to-many class="com.imooc.entity.Student" />
    31         </set>
    32         
    33     </class>
    34     
    35 </hibernate-mapping>

    6、获取session的工具类:HibernateUtil.java

     1 package com.imooc.util;
     2 
     3 /*
     4  * 总结:
     5  * 创建会话,四步:
     6  * 1、建立配置文件对象,处理我们写的那些配置文件,包括数据库配置文件和映射文件
     7  * 2、开启Hibernate服务,就像我们生活中用什么东西要开启什么样的服务一样,而且要注册
     8  * 3、创建会话工厂
     9  * 4、创建会话
    10  */
    11 import org.hibernate.Session;
    12 import org.hibernate.SessionFactory;
    13 import org.hibernate.boot.registry.StandardServiceRegistry;
    14 import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    15 import org.hibernate.cfg.Configuration;
    16 import org.hibernate.service.ServiceRegistry;
    17 
    18 //工具类,用来进行会话的获取和关闭
    19 public class HibernateUtil {
    20     private static SessionFactory sessionFactory;
    21     private static Session session;
    22 
    23     //通过静态代码块来加载
    24     static{
    25         //创建Configuration对象,读取hibernate.cfg.xml文件,完成初始化
    26         //        Configuration config = new Configuration().configure();
    27         //        StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().
    28         //                applySettings(config.getProperties());
    29         //        StandardServiceRegistry ssr = ssrb.build();
    30         //        sessionFactory=config.buildSessionFactory(ssr);
    31         //创建配置对象
    32         Configuration config = new Configuration().configure();
    33         //创建服务注册对象
    34         ServiceRegistry serviceRegistry =  new 
    35                 StandardServiceRegistryBuilder().applySettings(config.getProperties()).configure().build();//这里有点不一样
    36         //创建会话工厂对象
    37         sessionFactory = config.buildSessionFactory(serviceRegistry);
    38         
    39         /*
    40          * 总结:
    41          * 创建会话,四步:
    42          * 1、建立配置文件对象,处理我们写的那些配置文件,包括数据库配置文件和映射文件
    43          * 2、开启Hibernate服务,就像我们生活中用什么东西要开启什么样的服务一样,而且要注册
    44          * 3、创建会话工厂
    45          * 4、创建会话
    46          */
    47     }
    48 
    49     //获取sessionFactory
    50     public static SessionFactory getSessionFactory(){
    51         return sessionFactory;
    52     }
    53 
    54     //获取Session
    55     public static Session getSession(){
    56         session = sessionFactory.openSession();
    57         return session;
    58     }
    59 
    60     //关闭Session
    61     public static void closeSession(Session session){
    62         if (session!=null) {
    63             session.close();
    64         }
    65     }
    66 
    67 }

    7、测试功能类,测试增删改查:Test.java

      1 /*
      2  * 一定要主要总结啊,要把学到的东西变成自己的东西
      3  * 其实Hibernate说难也难,说简单也简单,两步:
      4  * 1、成功获取Session对象的环境搭建
      5  * 2、Session使用:save():(增) delete():(删) update():(改) get()/load():(查)
      6  * 
      7  * 这一次课的核心:
      8  * 1、如何在MyEclipse中使用Hibernate
      9  * 2、如何实现Hibernate中一对多的映射
     10  * 3、如何创建Session对象
     11  * 4、如何使用增删改查
     12  * 
     13  */
     14 package com.imooc.entity;
     15 /*
     16  * 错误一:
     17  * 出现错误:Dialect不对
     18  * 解决方法:把配置文件方言改成org.hibernate.dialect.MySQL5InnoDBDialect就好
     19  * 错误二:
     20  * 出现错误:org.hibernate.MappingException: Unknown entity: com.imooc.entity.Grade
     21  * 错误分析:映射文件错误,根本就没有成功读取Grade的映射文件
     22  *              将配置文件中的添加实体映射删掉,报的错误一样,说明错误是这里或之前
     23  *              修改这之前的,出现新的错误,说明错误就在这里
     24  *              既然是报错找不到com.imooc.entity.Grade,我把所有出现这个的地方都改下,查到底是那里错句
     25  *              错误提示session.save(g);这一句是错的,注释掉之后出现没有学生实体类的错误
     26  *              说明两个映射文件根本都没有加进去
     27  *              com.imooc.entity.Grade这个包名是我在test里面引包,其实就是session没有找到Grade实体
     28  *              待会去用eclipse试一下
     29  * 解决方法:还是生产session会话那里有问题,用之前的eclipse里面hibernate生成会话的方式就解决了
     30  *              还是因为hibernate的版本和他的版本不一样,用的hibernate里面的required也不一样
     31  * 解决心得:其实这种看视频,真的要用的软件、包、工具和他一模一样才好
     32  *              仔细分析,找错还是挺好找的
     33  */
     34 
     35 
     36 import java.util.Set;
     37 
     38 import org.hibernate.Hibernate;
     39 import org.hibernate.Session;
     40 import org.hibernate.Transaction;
     41 
     42 import com.imooc.util.HibernateUtil;
     43 
     44 /*
     45  * 单向一对多关系
     46  * (班级--->学生)
     47  * 建立关联关系后,可以方便的从一个对象导航到另一个对象
     48  * 注意关联的关系
     49  */
     50 public class Test {
     51     public static void main(String[] args){
     52         //add();
     53         //findStudentsByGrade();
     54         //update();
     55         delete();
     56     }
     57 
     58     //将学生添加到班级
     59     /*
     60      * 方法测试对应的输出结果:
     61      * 
     62 Hibernate: select max(gid) from grade
     63 Hibernate: select max(sid) from student
     64 Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
     65 Hibernate: insert into student (sname, sex, sid) values (?, ?, ?)
     66 Hibernate: insert into student (sname, sex, sid) values (?, ?, ?)
     67 Hibernate: update student set gid=? where sid=?
     68 Hibernate: update student set gid=? where sid=?
     69      *
     70      *
     71      */
     72     public static void add(){
     73         Grade g = new Grade("Java一班","Java软件开发一班");
     74         Student stu1 = new Student("张三","男");
     75         Student stu2 = new Student("穆女神","女");
     76 
     77         //将这两个学生添加到班级中
     78         //如果希望在学生表中添加对应的班级编号,需要在班级中添加学生,建立关联关系
     79         g.getStudents().add(stu1); //set集合students集合汇总添加,是Grade中的属性
     80         g.getStudents().add(stu2);
     81 
     82         //得到会话
     83         Session session = HibernateUtil.getSession();
     84         //开启事务
     85         Transaction tx = (Transaction) session.beginTransaction();
     86         //保存班级,学生
     87         session.save(g);
     88         session.save(stu1);
     89         session.save(stu2);
     90         //提交事务
     91         tx.commit();
     92         //关闭session
     93         HibernateUtil.closeSession(session);
     94         /*
     95          * 总结:
     96          * 1、新建班级对象和学生对象
     97          * 2、将学生对象加入班级对象属性中的学生集合中
     98          * 3、调用Session对象保存班级对象和学生对象
     99          * save学生对象是把学生信息添加到学生表中
    100          * save班级对象是把班级信息添加到班级表中
    101          * 将学生对象加入班级对象属性中的学生集合中:其实是为了和映射文件一起完成主外键的连接
    102          * 
    103          */
    104     }
    105 
    106     //查询班级中包含的学生,根据班级获取对应的信息
    107     /*
    108      * 方法测试对应的输出结果:
    109      * Hibernate: select grade0_.gid as gid1_0_0_, grade0_.gname as gname2_0_0_, grade0_.gdesc as gdesc3_0_0_ from grade grade0_ where grade0_.gid=?
    110      * Java一班,Java软件开发一班
    111      * Hibernate: select students0_.gid as gid4_1_0_, students0_.sid as sid1_1_0_, students0_.sid as sid1_1_1_, students0_.sname as sname2_1_1_, students0_.sex as sex3_1_1_ from student students0_ where students0_.gid=?
    112      * 穆女神,女
    113      * 张三,男
    114      */
    115     public static void findStudentsByGrade(){
    116         //1、建立会话
    117         Session session=HibernateUtil.getSession();
    118         //2、通过session从数据库取出班级消息
    119         Grade grade= session.get(Grade.class, 1);
    120         System.out.println(grade.getGname()+","+grade.getGdesc());
    121         //3、从班级消息中取出学生消息,其实就已经达到目的了
    122         Set<Student> students=grade.getStudents();
    123         //4、for遍历输出学生的消息
    124         for (Student student : students) {
    125             System.out.println(student.getSname()+","+student.getSex());
    126         }
    127         /*
    128          * 总结:
    129          * 1、
    130          * 其实核心语句就是Session的get方法,因为这个本事就是一个查询啊
    131          * get里面的一个参数是类,那么另一个参数就是主键,类对应的表的主键
    132          * 同理,后面的改就是先get,然后update
    133          * 删就直接delete对应的类对象就好
    134          * 2、
    135          * 通过session给对象发送sql,连接数据库,返回数据库消息,这些都是session给对象来完成的
    136          * 我们只用享受胜利的果实即可
    137          * 
    138          */
    139     }
    140 
    141     //修改学生信息
    142     //这里将学生信息添加到一个新的班级
    143     /*
    144      * 心得:
    145      * 前面总结和一下之后,他这里说啥我能接上下面的
    146      * 
    147      * 方法测试对应的输出结果:
    148 Hibernate: select student0_.sid as sid1_1_0_, student0_.sname as sname2_1_0_, student0_.sex as sex3_1_0_ from student student0_ where student0_.sid=?
    149 Hibernate: select max(gid) from grade
    150 Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
    151 Hibernate: update student set gid=? where sid=?
    152      * 
    153      */
    154     public static void update(){
    155         //这里数据库的结果是班级表里面多了下面的这一条记录
    156         //并且对应的学生也修改到了这个班级
    157         Grade grade = new Grade("Java二班","Java软件开发二班");
    158         //开启事务
    159         Session session=HibernateUtil.getSession();
    160         //因为是进行的数据库的更新,所以必须开启事务
    161         Transaction transaction= session.beginTransaction();
    162         //这里是Session得到的是学生表中的信息
    163         Student student=session.get(Student.class, 1);
    164         grade.getStudents().add(student);
    165         session.save(grade);
    166         transaction.commit();
    167         HibernateUtil.closeSession(session);
    168 
    169         /*
    170          * 总结:
    171          * 1、不管对数据库的什么操作,首先肯定要先打开Session
    172          * 2、更新就是先get,后update,但是在这里是save,
    173          * 3、但凡修改数据库的,加上事务,事务开了肯定也要关闭
    174          * 4、因为这里是映射,所以这里还要在班级中加入学生对象
    175          * 
    176          */
    177 
    178     }
    179 
    180     //删除学生信息
    181     /*
    182      * 总结:
    183      * 得益于前面的总结,这里是自己写的,而且和他写的一样
    184      * 自己写的时候还是犹豫了一下要不要开transaction
    185      * 但是对数据库的修改肯定是要开session的
    186      * 
    187      * 方法测试对应的输出结果:
    188 Hibernate: select student0_.sid as sid1_1_0_, student0_.sname as sname2_1_0_, student0_.sex as sex3_1_0_ from student student0_ where student0_.sid=?
    189 Hibernate: delete from student where sid=?
    190      * 在数据库的表中成功的删除了主键为4的学生
    191      */
    192     public static void delete(){
    193         
    194         Session session = HibernateUtil.getSession();
    195         //因为是进行的数据库的改变的操作,所以必须开启事务
    196         Transaction transaction= session.beginTransaction();
    197         Student student = session.get(Student.class, 4);
    198         session.delete(student);
    199         transaction.commit();
    200         HibernateUtil.closeSession(session);
    201     }
    202 
    203 }

    文件对应的目录结构如下

  • 相关阅读:
    《人月神话》阅读笔记2
    【个人作业】单词链
    【个人作业】找水王
    【团队】 冲刺一(10/10)
    【团队】 冲刺一(9/10)
    【个人作业】单词统计续
    【团队】 冲刺一(8/10)
    【团队】 冲刺一(7/10)
    【团队】 冲刺一(6/10)
    【团队】 冲刺一(5/10)
  • 原文地址:https://www.cnblogs.com/Renyi-Fan/p/6936076.html
Copyright © 2020-2023  润新知