Hibernate(三)—多表操作
来源:互联网 发布:海岛奇兵神像升级数据 编辑:程序博客网 时间:2024/05/17 08:28
1.一对多映射
一对多映射是常见的映射关系,也是用的最广泛的数据库多表关系。
现在有两个表,students和article,一个学生可以写很多的文章,而一篇文章只有一个学生作者。因此students和article是一对多的关系。
其中article的student_id是外键,映射students中的id。
1.1 POJO类
Student:
public class Student { private Integer id; private String name; private String sex; private Integer age; private String tel; //学生可以发表多篇文章(Hibernate使用HashSet解决一对多,HIbernate默认使用hashset集合,并且Hashset必须实例化) private Set<Article> articleList=new HashSet<Article>(); public Set<Article> getArticleList() { return articleList; } public Student() { super(); } public Student(String name, String sex, Integer age, String tel) { super(); this.name = name; this.sex = sex; this.age = age; this.tel = tel; } public void setArticleList(Set<Article> articleList) { this.articleList = articleList; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getTel() { return tel; } public void setTel(String tel) { this.tel = tel; } @Override public String toString() { return "Student [id=" + id + ", name=" + name + ", sex=" + sex + ", age=" + age + ", tel=" + tel + "]"; }}
注意:一对多关系中的一表中,必须有一个HashSet集合,并且必须实例化。
Article:
public class Article { private Integer id; private String title; private String content; private Integer student_id; //文章关联的作者对象 private Student student; public Student getStudent() { return student; } public Article() { super(); } public Article(String title, String content) { super(); this.title = title; this.content = content; } public void setStudent(Student student) { this.student = student; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } public String getContent() { return content; } public void setContent(String content) { this.content = content; } public Integer getStudent_id() { return student_id; } public void setStudent_id(Integer student_id) { this.student_id = student_id; } @Override public String toString() { return "Article [id=" + id + ", title=" + title + ", content=" + content + ", student_id=" + student_id + ", student=" + student + "]"; }}
注意:一对多关系中的多表中,必须有一个要关联对象。
1.2 映射文件
Student.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!--Pojo类和表名之间的映射关系 --> <class name="com.mq.pojo.Student" table="students"> <!--用来将类中的id属性与表中的主键建立映射,id标签就是用来配置主键的 --> <id name="id" column="id"> <generator class="native"/> </id> <!-- 用来将类中的普通属性与表中的字段建立映射 --> <property name="name" column="name"/> <property name="sex" column="sex"/> <property name="age" column="age"/> <property name="tel" column="tel"/> <!-- set属性:多的一方的集合的属性名称. --> <set name="articleList"> <!-- column属性:多的一方的外键的名称. --> <key column="student_id"/> <!--one-to-many标签: class属性:多的一方的类全路径 --> <one-to-many class="com.mq.pojo.Article"/> </set> </class> </hibernate-mapping>
注意,有HashSet集合的类的映射文件需要配置set集合标签。
Article.hbm.xml:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!--Pojo类和表名之间的映射关系 --> <class name="com.mq.pojo.Article" table="article"> <!--用来将类中的id属性与表中的主键建立映射,id标签就是用来配置主键的 --> <id name="id" column="id"> <generator class="native"/> </id> <!-- 用来将类中的普通属性与表中的字段建立映射 --> <property name="title" column="title"/> <property name="content" column="content"/> <property name="student_id" column="student_id" /> <!--many-to-one:标签.代表多对一. name:一的一方的对象的名称 class:一的一方的类的全路径. column:表中的外键的名称 --> <many-to-one name="student" class="com.mq.pojo.Student" column="student_id"/> </class> </hibernate-mapping>
1.3 插入数据
public class One2ManyTest { private SessionFactory factory; @Before public void first(){ // 先加载配置文件 Configuration config = new Configuration(); // 默认加载src目录下的配置文件 config.configure(); // 创建SessionFactory对象 factory = config.buildSessionFactory(); } //保存 @Test public void insert(){ Session session = factory.openSession(); // 开启事务 Transaction tr = session.beginTransaction(); Student student=new Student("郭嘉","男",23,"3289328"); Article article=new Article("官渡之战","统一北方"); Article article2=new Article("赤壁之战","开启了三国鼎立"); //将两篇文章添加到student中。 student.getArticleList().add(article); student.getArticleList().add(article2); //给两篇文章设置student中。 article.setStudent(student); article2.setStudent(student); session.save(student); session.save(article); session.save(article2); tr.commit(); } }
1.4 级联保存
级联保存就是操作一个对象的时候,将关联对象一并操作。对于保存来说,只要保存一个对象,关联的其他对象自动就会保存。
保存学生同时级联保存文章:
需要在配置文件中的set集合上添加cascade=”save-update”
注意使用级联操作必须使用sql语句显式的确定各个表之间的关系。
//级联保存 @Test public void insert(){ Session session = factory.openSession(); // 开启事务 Transaction tr = session.beginTransaction(); Student student=new Student("郭嘉","男",23,"3289328"); Article article=new Article("官渡之战","统一北方"); Article article2=new Article("赤壁之战","开启了三国鼎立"); //将两篇文章添加到student中。 student.getArticleList().add(article); student.getArticleList().add(article2); //给两篇文章设置student中。 article.setStudent(student); article2.setStudent(student); //只保存学生,会级联保存文章 session.save(student);//student变为持久态,article和article2还是瞬时态 tr.commit(); }
如果是保存文章的同时级联保存学生,那么需要在在many-to-one上配置cascade=”save-update”其他操作一样。
级联保存有方向性,在映射文件中配置以后才能使用。
1.5 级联删除
级联删除的操作和级联保存基本一样,在映射文件中配置关联后,只要删除一方,关联的那一方也会被自动删除。
删除学生的时候 删除其写得文章:
需要在Student.hbm.xml中set标签上配置cascade=”delete”
删除文章的时候,级联删除其作者,
需要在Article.hbm.xml中many-to-one标签上配置cascade=”delete”
1.6 多表查询
//多表查询 @Test public void query(){ Session session = factory.openSession(); List list1=session.createQuery("select s.name,a.name from Student s,Article a where s.id=a.student_id").list(); System.out.println(list1); /** * 左外连接: * select * from Student s left join Article a on s.id=a.student_id; * * 右外连接: * select * from Student s right join Article a on s.id=a.student_id; */ }
2.多对多映射
以User和Role为例,一个人可以扮演多个角色,而一个角色可以有多个人扮演。因此User和Role是多对多的关系。
2.1 POJO类
用户的JavaBean代码如下
public class User { private Long user_id; private String user_name; private String user_state; private Set<Role> roles = new HashSet<Role>(); //在此省略set和get方法 }
角色的JavaBean代码如下
public class Role { private Long role_id; private String role_name; private String role_memo; private Set<User> users = new HashSet<User>(); //在此省略set和get方法 }
2.2 映射文件
用户的映射文件:
<class name="com.itheima.domain.User" table="sys_user"> <id name="user_id" column="user_id"> <generator class="native"/> </id> <property name="user_name" column="user_name"/> <property name="user_state" column="user_state"/> <set name="roles" table="sys_user_role"> <key column="user_id"/> <many-to-many class="com.itheima.domain.Role" column="role_id"/> </set> </class>
角色的映射文件:
<class name="com.itheima.domain.Role" table="sys_role"> <id name="role_id" column="role_id"> <generator class="native"/> </id> <property name="role_name" column="role_name"/> <property name="role_memo" column="role_memo"/> <set name="users" table="sys_user_role"> <key column="role_id"/> <many-to-many class="com.itheima.domain.User" column="user_id"/> </set> </class>
级联保存和级联删除的用法同一对多。
3. 延迟加载
延迟加载先获取到代理对象,当真正使用到该对象中的属性的时候,才会发送SQL语句,是Hibernate框架提升性能的方式。
Session对象的load方法默认就是延迟加载
Student s = session.load(Student.class, 1);没有发送SQL语句,当使用该对象的属性时,才发送SQL语句。
- Hibernate(三)—多表操作
- Hibernate单表操作(三)——对象类型
- Hibernate(三)入门操作
- Hibernate-day04 Hibernate 多表操作 Hibernate优化 检索策略
- 【Hibernate】(4)Hibernate的多表操作、级联操作与延迟加载
- Hibernate多表关联操作
- Hibernate中的多表操作
- hibernate多表操作详解
- MySQL进阶(三)——多表操作
- Hibernate课堂小结三 (级联操作)
- 初识Hibernate(三)之查询操作
- Hibernate(三)——Hibernate给表和字段设置前后缀及分隔符
- hibernate学习 hibernate-tutorials(三)——entitymanager
- hibernate 一对多关联(三)
- Hibernate框架 表设计(三范式)
- Hibernate单独使用 (三)表关联
- 传智播客——hibernate细节(三)
- 【Hibernate学习】 ——ORM(三)
- 关于MatConvNet
- 解决- SecureCRT上运行 linux vim 命令中文出现乱码
- Java使用poi读取excel数据(excel可能很大,先转换为csv再读取)
- [计算机网络]:DNSSEC原理
- cmake
- Hibernate(三)—多表操作
- heartbeat
- 原生javascript实现选项卡切换效果
- android setVisibility(GONE)不及时刷新的问题
- LightOJ
- 一个完整的包含server,admin,client,其中server使用express搭建,admin和client基于vue开发。
- Qml应用程序的性能考虑与建议
- js判断安卓还是ios之后连接跳转
- 服务器端应用安全