<二>重温Hibernate one to one 映射

原创 2015年07月08日 16:18:47

用户表:

CREATE TABLE `tbl_user` 

(`id` INT(32) NOT NULL AUTO_INCREMENT,`user_name` VARCHAR(20) NULL DEFAULT NULL,

`password` VARCHAR(20) NULL DEFAULT NULL,PRIMARY KEY (`id`)

)

用户会员表:

CREATE TABLE `tbl_member` 

(`id` INT(10) NOT NULL AUTO_INCREMENT,`card_no` VARCHAR(50) NULL DEFAULT NULL,

`user_id` INT(11) NULL DEFAULT NULL,PRIMARY KEY (`id`),

INDEX `FK_tbl_member_tbl_user` (`user_id`),

CONSTRAINT `FK_tbl_member_tbl_user` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON UPDATE CASCADE ON DELETE CASCADE

)

一对一关联分为主键关联与外键关联。

主键关联:不必加额外的字段,只是主表和辅表的主键相关联,即这两个主键的值是一样的。

外键关联:辅表有一个额外的字段和主表相关联,或者两个表都有额外的字段与对应表的相关联。

 

public class Users {

private int id;

private String userName;

private String password;

private Account account;

//getter and setter

}

public class Account {

private int id;

private String cardNo;

private Users users;

//getter and setter

}

Main方法:

Session session=null;

Transaction tran=null;

try {

session=HibernateSessionFactory.getSession();

tran=session.beginTransaction();

Users users=new Users();

users.setUserName("zhangsan");

users.setPassword("123456");

Member member=new Member();

member.setCardNo("002568853369_lisi");

member.setUsers(users);

session.save(member);

tran.commit();

} catch (HibernateException e) {

tran.rollback();

e.printStackTrace();

}finally{

session.flush();

session.close();

}

1.单方外键关联

这种关联member是用many-to-one然后用unique="true"做限制,限制成一对一的关系。所以,一对一的外键关联其实就是多对一关联的一种特例。

Member xml

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetoone.bean.Member" table="tbl_member">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="cardNo" type="java.lang.String" column="card_no"/>

<many-to-one name="users" column="user_id" unique="true" cascade="all"></many-to-one>

</class>

</hibernate-mapping>

User xml

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetoone.bean.Users" table="tbl_user">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="userName" type="java.lang.String" column="user_name"/>

<property name="password" type="java.lang.String" column="password"/>

<!-- 

property-ref属性为user,property-ref:表明从Users(users属性)建立了从Users(member属性)对象到Member对象的关联,

只要调用user持久化对象的getMember()方法,就能导航到member对象,

 -->

<one-to-one name="member" class="wb.wk.review.mapping.onetoone.bean.Member" 

property-ref="users" cascade="all">

</one-to-one>

</class>

</hibernate-mapping>

运行main方法:

出现异常org.hibernate.MappingException: Unknown entity: wb.wk.review.mapping.onetoone.byForeignKey.Member

原因:hibernate.cfg.xml忘记导入相应的xml

再次运行,出现异常:

Caused by: java.sql.BatchUpdateException: Cannot add or update a child row: a foreign key constraint fails (`ppi`.`tbl_member`, CONSTRAINT `FK_tbl_member_tbl_user` FOREIGN KEY (`user_id`) REFERENCES `tbl_user` (`id`) ON DELETE CASCADE ON UPDATE CASCADE)

原因是在id属性里必须设置generator 主键生成策略属性,我当时设置了assigned结果出现此异常。

注意:我使用的mysql,所以设置成”identity”,不同的数据库要设置不同的属性类别。具体的参照转载的一篇文章:http://blog.csdn.net/u013803303/article/details/46813249

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

最后运行成功,双表均插入成功。

总结:member表的外键use_id和user表的主键id对应,这没啥好说的。

 

2.主键关联

user xml

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetoone.bean.Users" table="tbl_user">

<id name="id" column="id" type="java.lang.Integer">

<generator class="identity"></generator>

</id>

<property name="userName" type="java.lang.String" column="user_name"/>

<property name="password" type="java.lang.String" column="password"/>

<one-to-one name="member" class="wb.wk.review.mapping.onetoone.bean.Member" cascade="all" >

</one-to-one>

</class>

</hibernate-mapping>

Member xml:

<hibernate-mapping>

<class name="wb.wk.review.mapping.onetoone.bean.Member" table="tbl_member">

<id name="id" column="id">

         <generator class="foreign">

            <param name="property">users</param>

         </generator>

      </id>

<property name="cardNo" type="java.lang.String" column="card_no"/>

<one-to-one name="users" class="wb.wk.review.mapping.onetoone.bean.Users" constrained="true">

</one-to-one>

<!-- constrained属性为true,代表user表的主键id同时作为外键,id必须为foreign生成策略 -->

</class>

</hibernate-mapping>

 

运行后出现下面异常:

org.hibernate.exception.GenericJDBCException: Could not execute JDBC batch update

.......

Caused by: java.sql.BatchUpdateException: Field 'user_id' doesn't have a default value

发现是数据库没有设置自动增长。设置好运行,又出现:

 

org.hibernate.PropertyValueException: not-null property references a null or transient value: wb.wk.review.mapping.onetoone.bean.Users.member.

调试后发现是因为外检表(member表)的constrained属性忘记设置了。不设置此属性,member表的外键就为null,出现此异常

再次运行成功。

总结:插入后查询数据库发现,member表的id和user表的id是一一对应的,这应该就能很好的解释了什么是主键关联。但是member表外键user_id为null,由此看来主键关联适用于没有外键关联的,双表关联。

 

3. 双方外键关联

如果关联双方都是外键关联,那可以两边都用many-to-one。

   <many-to-one name="member" cascade="all" unique="true"

         column="member_id" />

    Account配置(类不变)

<many-to-one name="user" unique="true" column="user_id"

         cascade="all" />

这个就不写测试了。

 

最后网上找了个官方的配置介绍:

<one-to-one name="propertyName" (1) class="ClassName" (2)cascade="cascade_style"(3) constrained="true|false"(4)fetch="join|select"  (5)property-ref="propertyNameFromAssociatedClass" (6)access="field|property|ClassName"  (7)formula="anySQLexpression" (8)

lazy="proxy|no-proxy|false" (9) entity-name="EntityName"(10)

 node="element-name|@attribute-name|element/@attribute|."

 mbed-xml="true|false"foreign-key="foreign_key_name"/>

  (1) name: 属性的名字。

    (2) class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。

  (3) cascade(级联) (可选):表明操作是否从父对象级联到被关联的对象。

    (4) constrained(约束) (可选):表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。 这个选项影响save()和delete()在级联执行时的先后顺序以及 决定该关联能否被委托(也在schema export tool中被使用).

  (5) fetch (可选 - 默认设置为选择): 在外连接抓取或者序列选择抓取选择其一.

  (6) property-ref (可选):指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。

  (7) access (可选 - 默认是 property): Hibernate用来访问属性的策略。

  (8) formula (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中, 你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。 (可以在org.hibernate.test.onetooneformula找到例子)

  (9) lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。 lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate会采取预先抓取!

(10) entity-name (可选): 被关联的类的实体名。

 

版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

Hibernate的配置文件的映射many-to-one错误

先看一下错误 虽然,这么多错误挺吓人的,还有SessionFactory为空,但是其实就一个错误文件是这样的Customer.javapackage ch06.pojo;import jav...

使用注解的Hibernate one-to-many映射

One to many映射关系指的是两个实体间一个实体可以和多个实体有关联关系,但是多的这一端只能和一的这一端的一个实例有关系。它是一个1 到 n的关系。例如在任何的公司员工可以注册多个银行账户,一个...

hibernate映射文件many-to-one元素属性

many-to-one 元素 属性:   name:映射类属性的名字column:关联的字段class:关联类的名字cascade:设置操作中的级联策略 可选值为 all所有操作情况均进...

hibernate映射文件many-to-one元素属性

many-to-one 元素属性:name:映射类属性的名字column:关联的字段class:关联类的名字cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操...

Hibernate One-to-Many Mappings 一对多关系映射

Hibernate One-to-Many Mappings 一对多关系映射 关键点:一对多关系使用 Set 实现, 例子:一个员工可以有多个学证书。 Hibernate框架的使用步骤: ...

Hibernate基于注解的双向one-to-many映射关系的实现

在项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码捣鼓了基于注解的一对多的映射关系实现。 背景: 一的一端:Qing...

Hibernate基于注解的双向one-to-many映射关系的实现

2、Hibernate基于注解的双向one-to-many映射关系的实现项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码...

hibernate映射文件many-to-one 元素属性

name:映射类属性的名字 column:关联的字段 class:关联类的名字 cascade:设置操作中的级联策略 可选值为 all所有操作情况均进行级联、none所有操作情况均不进行级联、s...

hibernate映射技巧one-to-many(单项一对多)

一对多关系在系统实现中也很常见。典型的例子就是父亲与孩子的关系。 而在我们现在的这个示例中,每个用户(TUser)都关联到多个地址(TAddress),如一个用户可能拥有办公室地址、家庭地址等多个地址...

hibernate集合映射,one-to-many,删除集合成员

1、one方映射文件  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">     Mapping file a...
  • joyyq
  • joyyq
  • 2012-03-15 23:37
  • 1484
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)