慕课网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中一对多的映射

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

3、如何创建Session对象

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

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

4、Hibernate如何使用增删改查

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

二、实例代码

1、数据库配置文件: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>
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">1314</property>
<property name="hibernate.connection.url">
<![CDATA[
jdbc:mysql://localhost:3306/Hibernate2?useUnicode=true&characterEncoding=utf8
]]>
</property> <property name="show_sql">true</property>
<property name="hbm2ddl.auto">update</property> <!-- 指定映射文件的路径 -->
<mapping resource="Grade.hbm.xml" />
<mapping resource="Student.hbm.xml" /> </session-factory>
</hibernate-configuration>

2、实体类一Student.java

 package com.imooc.entity;

 import java.io.Serializable;

 public class Student implements Serializable {
private int sid; //学生id
private String sname; //学生姓名
private String sex; //性别 //构造函数 public Student() {
super();
} public Student(String sname, String sex) {
super();
this.sname = sname;
this.sex = sex;
} public int getSid() {
return sid;
} public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
} }

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

 <?xml version="1.0"?>

 <!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <!-- 配置的是学生到班级的单向的一对多 -->
<hibernate-mapping>
<class name="com.imooc.entity.Student" table="student">
<!-- name是类名,table是那么对应的类对应的数据库中的表名 -->
<!-- id是主键 -->
<id name="sid" type="java.lang.Integer">
<column name="sid"></column>
<generator class="increment"></generator>
<!-- generator是主键生成策略 increment查找主键最大值,并且在最大值的基础上加1 -->
</id>
<property name="sname" type="java.lang.String">
<column name="sname" length="20" not-null="true"></column>
</property>
<property name="sex">
<column name="sex"></column>
</property> </class> </hibernate-mapping>

4、班级实体类 Grade.java

 package com.imooc.entity;

 import java.io.Serializable;
import java.util.HashSet;
import java.util.Set; //班级类
//添加集合表示一对多的关系
public class Grade implements Serializable {
private int gid; //班级id
private String gname; //班级名
private String gdesc; //班级描述 //在一方(班级)去定义一个多方(学生)的集合来表示一对多的关系
//set集合元素不能重复
private Set<Student> students = new HashSet<Student>();
/*
* 总结:
* 一对多映射的核心:
* 通过在grade中添加student的集合来实现
* 1、grade里面的这个集合类,需要映射的时候给这个类里面加学生
* 2、grade这个类对应的映射文件中的
* <!-- 配置单向的一对多关联关系 -->
<set name="students" table="students">
<!-- 指定关联的外键列 -->
<key >
<column name="gid"></column>
</key>
<!-- 指定一对多的类名 -->
<one-to-many class="com.imooc.entity.Student" />
</set>
*/ //构造方法
public Grade(int gid, String gname, String gdesc, Set<Student> students) {
super();
this.gid = gid;
this.gname = gname;
this.gdesc = gdesc;
this.students = students;
} public Grade(String gname, String gdesc) {
super();
this.gname = gname;
this.gdesc = gdesc;
} public Grade() {
super();
} public int getGid() {
return gid;
} public void setGid(int gid) {
this.gid = gid;
} public String getGname() {
return gname;
} public void setGname(String gname) {
this.gname = gname;
} public String getGdesc() {
return gdesc;
} public void setGdesc(String gdesc) {
this.gdesc = gdesc;
} public Set<Student> getStudents() {
return students;
} public void setStudents(Set<Student> students) {
this.students = students;
} }

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

 <?xml version="1.0"?>

 <!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <class name="com.imooc.entity.Grade" table="grade">
<!-- name是类名,table是那么对应的类对应的数据库中的表名 -->
<!-- id是主键 -->
<id name="gid" type="java.lang.Integer">
<column name="gid"></column>
<generator class="increment"></generator>
<!-- generator是主键生成策略 increment查找主键最大值,并且在最大值的基础上加1 -->
</id>
<property name="gname" type="java.lang.String">
<column name="gname" length="20" not-null="true"></column>
</property>
<property name="gdesc">
<column name="gdesc"></column>
</property>
<!-- 配置单向的一对多关联关系 -->
<set name="students" table="students">
<!-- 指定关联的外键列 -->
<key >
<column name="gid"></column>
</key>
<!-- 指定一对多的类名 -->
<one-to-many class="com.imooc.entity.Student" />
</set> </class> </hibernate-mapping>

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

 package com.imooc.util;

 /*
* 总结:
* 创建会话,四步:
* 1、建立配置文件对象,处理我们写的那些配置文件,包括数据库配置文件和映射文件
* 2、开启Hibernate服务,就像我们生活中用什么东西要开启什么样的服务一样,而且要注册
* 3、创建会话工厂
* 4、创建会话
*/
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry; //工具类,用来进行会话的获取和关闭
public class HibernateUtil {
private static SessionFactory sessionFactory;
private static Session session; //通过静态代码块来加载
static{
//创建Configuration对象,读取hibernate.cfg.xml文件,完成初始化
// Configuration config = new Configuration().configure();
// StandardServiceRegistryBuilder ssrb = new StandardServiceRegistryBuilder().
// applySettings(config.getProperties());
// StandardServiceRegistry ssr = ssrb.build();
// sessionFactory=config.buildSessionFactory(ssr);
//创建配置对象
Configuration config = new Configuration().configure();
//创建服务注册对象
ServiceRegistry serviceRegistry = new
StandardServiceRegistryBuilder().applySettings(config.getProperties()).configure().build();//这里有点不一样
//创建会话工厂对象
sessionFactory = config.buildSessionFactory(serviceRegistry); /*
* 总结:
* 创建会话,四步:
* 1、建立配置文件对象,处理我们写的那些配置文件,包括数据库配置文件和映射文件
* 2、开启Hibernate服务,就像我们生活中用什么东西要开启什么样的服务一样,而且要注册
* 3、创建会话工厂
* 4、创建会话
*/
} //获取sessionFactory
public static SessionFactory getSessionFactory(){
return sessionFactory;
} //获取Session
public static Session getSession(){
session = sessionFactory.openSession();
return session;
} //关闭Session
public static void closeSession(Session session){
if (session!=null) {
session.close();
}
} }

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

 /*
* 一定要主要总结啊,要把学到的东西变成自己的东西
* 其实Hibernate说难也难,说简单也简单,两步:
* 1、成功获取Session对象的环境搭建
* 2、Session使用:save():(增) delete():(删) update():(改) get()/load():(查)
*
* 这一次课的核心:
* 1、如何在MyEclipse中使用Hibernate
* 2、如何实现Hibernate中一对多的映射
* 3、如何创建Session对象
* 4、如何使用增删改查
*
*/
package com.imooc.entity;
/*
* 错误一:
* 出现错误:Dialect不对
* 解决方法:把配置文件方言改成org.hibernate.dialect.MySQL5InnoDBDialect就好
* 错误二:
* 出现错误:org.hibernate.MappingException: Unknown entity: com.imooc.entity.Grade
* 错误分析:映射文件错误,根本就没有成功读取Grade的映射文件
* 将配置文件中的添加实体映射删掉,报的错误一样,说明错误是这里或之前
* 修改这之前的,出现新的错误,说明错误就在这里
* 既然是报错找不到com.imooc.entity.Grade,我把所有出现这个的地方都改下,查到底是那里错句
* 错误提示session.save(g);这一句是错的,注释掉之后出现没有学生实体类的错误
* 说明两个映射文件根本都没有加进去
* com.imooc.entity.Grade这个包名是我在test里面引包,其实就是session没有找到Grade实体
* 待会去用eclipse试一下
* 解决方法:还是生产session会话那里有问题,用之前的eclipse里面hibernate生成会话的方式就解决了
* 还是因为hibernate的版本和他的版本不一样,用的hibernate里面的required也不一样
* 解决心得:其实这种看视频,真的要用的软件、包、工具和他一模一样才好
* 仔细分析,找错还是挺好找的
*/ import java.util.Set; import org.hibernate.Hibernate;
import org.hibernate.Session;
import org.hibernate.Transaction; import com.imooc.util.HibernateUtil; /*
* 单向一对多关系
* (班级--->学生)
* 建立关联关系后,可以方便的从一个对象导航到另一个对象
* 注意关联的关系
*/
public class Test {
public static void main(String[] args){
//add();
//findStudentsByGrade();
//update();
delete();
} //将学生添加到班级
/*
* 方法测试对应的输出结果:
*
Hibernate: select max(gid) from grade
Hibernate: select max(sid) from student
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: insert into student (sname, sex, sid) values (?, ?, ?)
Hibernate: insert into student (sname, sex, sid) values (?, ?, ?)
Hibernate: update student set gid=? where sid=?
Hibernate: update student set gid=? where sid=?
*
*
*/
public static void add(){
Grade g = new Grade("Java一班","Java软件开发一班");
Student stu1 = new Student("张三","男");
Student stu2 = new Student("穆女神","女"); //将这两个学生添加到班级中
//如果希望在学生表中添加对应的班级编号,需要在班级中添加学生,建立关联关系
g.getStudents().add(stu1); //set集合students集合汇总添加,是Grade中的属性
g.getStudents().add(stu2); //得到会话
Session session = HibernateUtil.getSession();
//开启事务
Transaction tx = (Transaction) session.beginTransaction();
//保存班级,学生
session.save(g);
session.save(stu1);
session.save(stu2);
//提交事务
tx.commit();
//关闭session
HibernateUtil.closeSession(session);
/*
* 总结:
* 1、新建班级对象和学生对象
* 2、将学生对象加入班级对象属性中的学生集合中
* 3、调用Session对象保存班级对象和学生对象
* save学生对象是把学生信息添加到学生表中
* save班级对象是把班级信息添加到班级表中
* 将学生对象加入班级对象属性中的学生集合中:其实是为了和映射文件一起完成主外键的连接
*
*/
} //查询班级中包含的学生,根据班级获取对应的信息
/*
* 方法测试对应的输出结果:
* 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=?
* Java一班,Java软件开发一班
* 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=?
* 穆女神,女
* 张三,男
*/
public static void findStudentsByGrade(){
//1、建立会话
Session session=HibernateUtil.getSession();
//2、通过session从数据库取出班级消息
Grade grade= session.get(Grade.class, 1);
System.out.println(grade.getGname()+","+grade.getGdesc());
//3、从班级消息中取出学生消息,其实就已经达到目的了
Set<Student> students=grade.getStudents();
//4、for遍历输出学生的消息
for (Student student : students) {
System.out.println(student.getSname()+","+student.getSex());
}
/*
* 总结:
* 1、
* 其实核心语句就是Session的get方法,因为这个本事就是一个查询啊
* get里面的一个参数是类,那么另一个参数就是主键,类对应的表的主键
* 同理,后面的改就是先get,然后update
* 删就直接delete对应的类对象就好
* 2、
* 通过session给对象发送sql,连接数据库,返回数据库消息,这些都是session给对象来完成的
* 我们只用享受胜利的果实即可
*
*/
} //修改学生信息
//这里将学生信息添加到一个新的班级
/*
* 心得:
* 前面总结和一下之后,他这里说啥我能接上下面的
*
* 方法测试对应的输出结果:
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=?
Hibernate: select max(gid) from grade
Hibernate: insert into grade (gname, gdesc, gid) values (?, ?, ?)
Hibernate: update student set gid=? where sid=?
*
*/
public static void update(){
//这里数据库的结果是班级表里面多了下面的这一条记录
//并且对应的学生也修改到了这个班级
Grade grade = new Grade("Java二班","Java软件开发二班");
//开启事务
Session session=HibernateUtil.getSession();
//因为是进行的数据库的更新,所以必须开启事务
Transaction transaction= session.beginTransaction();
//这里是Session得到的是学生表中的信息
Student student=session.get(Student.class, 1);
grade.getStudents().add(student);
session.save(grade);
transaction.commit();
HibernateUtil.closeSession(session); /*
* 总结:
* 1、不管对数据库的什么操作,首先肯定要先打开Session
* 2、更新就是先get,后update,但是在这里是save,
* 3、但凡修改数据库的,加上事务,事务开了肯定也要关闭
* 4、因为这里是映射,所以这里还要在班级中加入学生对象
*
*/ } //删除学生信息
/*
* 总结:
* 得益于前面的总结,这里是自己写的,而且和他写的一样
* 自己写的时候还是犹豫了一下要不要开transaction
* 但是对数据库的修改肯定是要开session的
*
* 方法测试对应的输出结果:
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=?
Hibernate: delete from student where sid=?
* 在数据库的表中成功的删除了主键为4的学生
*/
public static void delete(){ Session session = HibernateUtil.getSession();
//因为是进行的数据库的改变的操作,所以必须开启事务
Transaction transaction= session.beginTransaction();
Student student = session.get(Student.class, 4);
session.delete(student);
transaction.commit();
HibernateUtil.closeSession(session);
} }

文件对应的目录结构如下

最新文章

  1. visual studio 2013快捷键与2012不同
  2. scrum阶段总结
  3. Hibernate入门4.核心技能
  4. 基于时间点恢复数据库stopat
  5. IE input X 去掉文本框的叉叉和密码输入框的眼睛图标
  6. C++隐式转换
  7. 转 如何高效使用和管理Bitmap--图片缓存管理模块的设计与实现
  8. AutoMapper 6.x 扩展
  9. java:凯撒密码及String的应用
  10. LeetCode OJ 之 Ugly Number II (丑数-二)
  11. eclipse汉化链接
  12. 笔记:Java虚拟机运行时数据区
  13. Javascrip 入门第三节课
  14. 【原创】MIPS相关
  15. 操作Linux系统环境变量的几种方法
  16. Android activity 周期图和fragment周期图
  17. oracle数据库的一个表中,怎么设置字段的默认值
  18. git开发过程的配置和使用
  19. python中Strip()函数的用法
  20. stm32初做项目心得

热门文章

  1. mysql参数配置文件
  2. UVM中的driver组件
  3. VS相关设置
  4. Windows10 64位下安装TensorFlow谷歌人工智能系统已官方原生支持
  5. javascript 的 事件类型(事件)
  6. Android查缺补漏(View篇)--布局文件中的“@+id”和“@id”有什么区别?
  7. MySQL数据库----多表查询
  8. shell字符串操作技巧
  9. 20144303石宇森《网络对抗》Web安全基础实践
  10. 解决Navicat Premium 12 连接oracle数据库出现ORA-28547的问题