`
zisefeiniao
  • 浏览: 171271 次
  • 性别: Icon_minigender_2
  • 来自: 成都
社区版块
存档分类
最新评论
阅读更多
容器映射完成pojo对象中出现的集合属性的映射
但与Java的一对多关系不同,这个集合属性中只能保存数据库中支持的基本类型(String,int,double,date)

由于属性为集合类型,有以下三种配置形式:
1、 Set
2、 List
3、 Map

一、Set集合
完成一个人和邮件地址的关系。
设计表:
人:userid,name,age,birthday
邮件地址表: userid、email,使用复合主键

使用容器映射的前提:
多的一方的表只能包含两个字段,并且为复合主键,其中一个字段为一的一方的外键,另一个为基本的数据类型,而在编写的pojo类中,集合中保存的数据,应该为多的一方表中另一个字段的基本类型。

所有对地址的操作都由人来完成,只建立一个 pojo类(人的类),为该类加入一个Set集合属性,该属性中保存了所有该人的邮件地址。

1、建立表
DROP TABLE user ;

DROP TABLE email ;

CREATE TABLE user (
userid varchar(18) primary key ,
name varchar(20) not null,
age int not null,
birthday date not null
);

CREATE TABLE email (
userid varchar(18) not null,
email varchar(50) not null,
primary key (userid,email)
);

2、生成映射
生成映射,只生成user的映射类。
在pojo中加入一个Set集合,该集合的泛型为String类型

package org.liky.pojo;

import java.util.Date;
import java.util.Set;
import java.util.TreeSet;

/**
* User generated by MyEclipse Persistence Tools
*/

public class User implements java.io.Serializable {

// Fields

private String userid;

private String name;

private Integer age;

private Date birthday;

private Set<String> emails = new TreeSet<String>();

// Constructors

/** default constructor */
public User() {
}

/** full constructor */
public User(String userid, String name, Integer age, Date birthday) {
this.userid = userid;
this.name = name;
this.age = age;
this.birthday = birthday;
}

// Property accessors

public String getUserid() {
return this.userid;
}

public void setUserid(String userid) {
this.userid = userid;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return this.age;
}

public void setAge(Integer age) {
this.age = age;
}

public Date getBirthday() {
return this.birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public Set<String> getEmails() {
return emails;
}

public void setEmails(Set<String> emails) {
this.emails = emails;
}

}


3、修改映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.liky.pojo.User" table="user" catalog="testdb">
<id name="userid" type="java.lang.String">
<column name="userid" length="18" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="10" not-null="true" />
</property>
<!-- 表示User中包含一个Set类型的属性,在该集合中保存的数据与email表有关系 -->
<set name="emails" table="email">
<!-- 在表email中通过userid与user表关联 -->
<key column="userid"></key>
<!-- 表示Set集合中保存的数据类型,和该数据所对应的表的字段,这里集合中所保存的数据对应表中的email列 -->
<element type="java.lang.String" column="email"></element>
</set>
</class>
</hibernate-mapping>

4、编写后台代码

5、测试
// 插入一个User,同时将该User的Email也插入
User user = new User();
user.setUserid("123456789123456789");
user.setName("MLDN");
user.setAge(33);
user.setBirthday(new Date());

user.getEmails().add("mldnqa@163.com");
user.getEmails().add("mldnkf@163.com");
user.getEmails().add("lxh@mldn.cn");
user.getEmails().add("lq@mldn.cn");

// 保存数据
try {
userdao.doCreate(user);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}


6、LazyInitializationException异常
完成修改:
先查询某个用户的全部邮件地址,列表显示
在显示邮件地址时,会出现以下异常

org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: org.liky.pojo.User.emails, no session or session was closed
该异常为延迟加载异常,在Hibernate使用过程中非常常见。

产生原因:
在Hibernate中,多表关联查询时,为了提高查询性能,设置了一个延迟加载机制(懒汉式)
也就是说,当用到另一个表的数据时,再去数据库中查询该表的数据。
但是这个查询还需要使用之前查询所使用的连接。

这里出现异常的原因是由于在执行了User的查询后,就将连接关闭了,再调用email查询时,无法找到之前打开的连接,因此出现了异常。

解决方法:
解决方法:
1、 不关闭Session连接(个人不推荐)
在代理类中不关闭连接
public User findById(String id) throws Exception {
// TODO Auto-generated method stub
User test = null;
try {
test =this.testdao.findById(id);
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {

}

return test;
}

2、修改延迟加载设置,不使用lazy
修改映射文件,为set加入一个lazy属性
<set name="emails" table="email" lazy="false">
这样使用不灵活,有时需要懒汉模式,有时不需要,而这样全部取消,也不好

3、在关闭前先查询出所要查询的内容
修改代理类中的内容,完成在关闭前的查询操作
public User findById(String id) throws Exception {
// TODO Auto-generated method stub
User test = null;
try {
test =this.testdao.findById(id);
test.getEmails().size();
} catch (RuntimeException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
this.instance.close();
}
return test;
}

7、完成只删除和修改Email的功能

要完成该功能,需要调用user的修改方法,而且只能使用session.update的修改方法。

补充:
两种修改与删除方法的最后一个区别:
Session方式的会同时对关联表起作用,而使用HQL无法影响到对方表
当数据库包含外键关系时,可以直接使用HQL进行删除,数据库会自动完成级联删除功能。
而如果不包含外键,则只能使用session.delete进行级联删除功能。
二、List集合

list:映射,可以允许重复,而且可以依据下标直接取得对象。
list映射和set映射的区别在于是否允许数据重复。
在表的设计上有区别
list方式映射时,表中包含三个字段,多一个下标的字段,用来区分内容相同的数据。
主键改为3主键

1、建立表
DROP TABLE user ;

DROP TABLE email ;

CREATE TABLE user (
userid varchar(18) primary key ,
name varchar(20) not null,
age int not null,
birthday date not null
);

CREATE TABLE email (
userid varchar(18) not null,
email varchar(50) not null,
indexid int not null,
primary key (userid,email,indexid)
);

2、生成映射
修改pojo类加入List集合
package org.liky.pojo;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
* User generated by MyEclipse Persistence Tools
*/

public class User implements java.io.Serializable {

// Fields

private String userid;

private String name;

private Integer age;

private Date birthday;

private List<String> emails = new ArrayList<String>();

// Constructors

/** default constructor */
public User() {
}

/** full constructor */
public User(String userid, String name, Integer age, Date birthday) {
this.userid = userid;
this.name = name;
this.age = age;
this.birthday = birthday;
}

// Property accessors

public String getUserid() {
return this.userid;
}

public void setUserid(String userid) {
this.userid = userid;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return this.age;
}

public void setAge(Integer age) {
this.age = age;
}

public Date getBirthday() {
return this.birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public List<String> getEmails() {
return emails;
}

public void setEmails(List<String> emails) {
this.emails = emails;
}

}

3、修改映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.liky.pojo.User" table="user" catalog="testdb">
<id name="userid" type="java.lang.String">
<column name="userid" length="18" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="10" not-null="true" />
</property>
<!-- 表示User中包含一个List类型的属性,在该集合中保存的数据与email表有关系 -->
<list name="emails" table="email">
<!-- 在表email中通过userid与user表关联 -->
<key column="userid"></key>
<!-- 需要包含一个索引号,表示indexid为索引列,类型为Integer -->
<index column="indexid" type="java.lang.Integer"></index>
<!-- 表示List集合中保存的数据类型,和该数据所对应的表的字段,这里集合中所保存的数据对应表中的email列 -->
<element type="java.lang.String" column="email"></element>
</list>
</class>
</hibernate-mapping>
其他操作参考Set


三、Map集合
Map:使用key与value的形式保存数据。
表需要修改,改为3个字段,修改为key与value的形式

1、建立表
DROP TABLE user ;

DROP TABLE email ;

CREATE TABLE user (
userid varchar(18) primary key ,
name varchar(20) not null,
age int not null,
birthday date not null
);

CREATE TABLE email (
userid varchar(18) not null,
email varchar(50) not null,
keyss varchar(20) not null,
primary key (userid,email,keyss)
);

2、修改pojo对象
package org.liky.pojo;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;

/**
* User generated by MyEclipse Persistence Tools
*/

public class User implements java.io.Serializable {

// Fields

private String userid;

private String name;

private Integer age;

private Date birthday;

private Map<String, String> emails = new TreeMap<String, String>();

// Constructors

/** default constructor */
public User() {
}

/** full constructor */
public User(String userid, String name, Integer age, Date birthday) {
this.userid = userid;
this.name = name;
this.age = age;
this.birthday = birthday;
}

// Property accessors

public String getUserid() {
return this.userid;
}

public void setUserid(String userid) {
this.userid = userid;
}

public String getName() {
return this.name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return this.age;
}

public void setAge(Integer age) {
this.age = age;
}

public Date getBirthday() {
return this.birthday;
}

public void setBirthday(Date birthday) {
this.birthday = birthday;
}

public Map<String, String> getEmails() {
return emails;
}

public void setEmails(Map<String, String> emails) {
this.emails = emails;
}

}

3、修改映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.liky.pojo.User" table="user" catalog="testdb">
<id name="userid" type="java.lang.String">
<column name="userid" length="18" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="name" length="20" not-null="true" />
</property>
<property name="age" type="java.lang.Integer">
<column name="age" not-null="true" />
</property>
<property name="birthday" type="java.util.Date">
<column name="birthday" length="10" not-null="true" />
</property>
<map name="emails" table="email">
<key column="userid"></key>
<index column="keyss" type="java.lang.String"></index>
<element type="java.lang.String" column="email"></element>
</map>
</class>
</hibernate-mapping>


其他操作参考Set
分享到:
评论

相关推荐

    Hibernate容器映射技术(Set、List、Map)

    Hibernate容器映射技术(Set、List、Map)

    hibernate中容器映射技术

    在Java持久化框架Hibernate中,容器映射技术是将Java集合类(如Set、Map、List等)与数据库中的关联关系进行映射的一种方法。这种技术使得对象之间的复杂关系能够被有效地存储和检索,增强了数据操作的灵活性。下面...

    Hibernate_容器映射技术笔记

    在Java的持久化框架Hibernate中,容器映射技术是一种用于管理对象关系的机制,它使得对象之间的关联可以方便地在数据库中表示。本篇笔记主要探讨了如何使用Hibernate进行容器映射,特别是针对集合类型的映射,如List...

    小容器映射出生活中的大智慧档.docx

    标题中的“小容器映射出生活中的大智慧”暗示了我们可以通过日常生活中的小物件来洞察深奥的生活哲理。在描述中,强调了设计对于提升生活质量的重要作用,无论是家具、灯具还是其他日常用品,它们都能通过独特的设计...

    动态添加docker映射端口python脚本

    本资源是动态添加docker容器映射端口的python脚本,在终端命令行里面只需要执行一下脚本,就能自动添加容器映射端口。

    Python库 | salt_container_map-0.2.0rc1-py2.7.egg

    盐容器映射(salt_container_map)是一个Python库,版本为0.2.0rc1,专为Python 2.7版本设计。这个库的核心功能是处理容器化应用程序的映射和管理,它可能是用于自动化部署、配置管理和基础设施即代码(IaC)场景的...

    hibernate(基于MVC的服务器架构技术)

    - **容器映射**:包括List、Set、Map等容器类型的映射,如元素类型、索引类型、集合的关联关系等。 在实际开发中,掌握这些基本概念后,还需要了解实体的状态管理(瞬时、持久化、托管、脱管),以及Criteria、HQL...

    Docker容器端口映射后突然无法连接的排查过程

    主要给大家介绍了关于Docker容器端口映射后突然无法连接的排查过程,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧

    修改已经运行的docker容器的端口映射.doc

    ### 修改已运行Docker容器的端口映射 在日常的开发与运维工作中,我们经常会遇到需要调整已部署Docker容器端口映射的情况。比如,当本地机器上安装了MySQL数据库并占用3306端口时,而之前通过Docker容器运行的MySQL...

    SDH原理讲座,符合搞通信的人读

    3. STM-1的基本元素和容器映射: STM-1可以承载各种较低等级的PDH信号,通过容器(C-12、C-3、C-4等)进行封装。容器是SDH中的数据传输单元,可以容纳不同速率的信号。映射过程是将PDH信号放入合适的容器,然后通过...

    详解如何解决docker容器无法通过IP访问宿主机问题

    在使用 docker 的过程中我不幸需要在 docker 容器中访问宿主机的 80 端口, 而这个 80 端口是另外一个容器 8080 端口映射出去的. 当我在容器里通过 docker 的网桥 172.17.0.1 访问宿主机时, 居然发现: curl: (7) ...

    J2EE核心框架代码2

    "21-Hibernate容器映射技术(Set、List、Map)(2)"和"22-Hibernate容器映射技术(Set、List、Map)(3)"进一步深化了这个主题,可能包括如何配置XML映射文件或使用注解来定义这些关系,以及如何在代码中操作这些集合,...

    域与domino目录同步功能的配置方法

    - 配置“Domino目录同步”的选项,包括Notes设置、域映射、容器映射等。 - **Notes 设置**:指定注册服务器,通常为Domino目录的管理服务器。 - **域映射**:定义AD字段与Domino个人及群组表单字段之间的映射关系...

    linux-获取ArukasDocker的容器的映射端口

    获取 Arukas Docker 的容器的映射端口,并把本机的某端口转发到此端口

    hibernate入门教程

    在这个入门教程中,我们将深入理解Hibernate的核心概念,包括实体层设计、实体映射以及容器映射。 ### 1. 实体层设计 在Hibernate中,实体代表数据库中的表。一个Java类可以被声明为一个实体,通过使用`@Entity`...

    AD与domino目录同步功能的配置方法.pdf

    12. **配置容器映射**: 容器映射部分标明了与对应Notes验证字及Notes策略对应的AD容器选择。默认情况下,用户注册到"user"容器下,除非另有修改需求。 13. **保存设置**: 单击“确定”。 14. **重启AD管理工具**: ...

    AUTOSAR_SRS_IPDUMultiplexer.pdf

    6. **容器映射**:文档描述了如何将多个IPDU映射到一个容器中,这是实现复用和解复用的关键机制。 7. **IpduMSelectorFieldLength扩展**:在R4.2.1版本中,这个字段的长度得到了扩展,可能提供了更大的灵活性来选择...

    Hibernate3.1_学习源码

    06 06Hibernate_Collection : Hibernate的容器映射技术,包括list、set和map等。用法大体一致,数据库中的两张表,在实体层设计和配置文件都只有一个 其中数据库用到级联删除。配置文件分别用list、set和map元素...

    AUTOSAR-SWS-IPDUMultiplexer原版文档

    此外,4.3.1版本引入了静态多PDU到容器映射的概念,允许更灵活的数据处理策略。 **3. 配置结构** 配置结构的修订旨在强化布局约束,确保在配置阶段就可预知通信行为。这意味着开发者可以更早地发现潜在的问题,...

Global site tag (gtag.js) - Google Analytics