Kodo EJB:实现类和类之间的关联关系

  对象和对象之间除了继承关系之外,还存在着关联关系:包括分作一对一、一对多、多对一和多对多,由于这几种关系在Kodo EJB中的实现原理基本类似,因此本文中主要就一对一类关联关系进行深入的讲述,同时通过简单例子的分析和实践详细的说明如何使用Kodo EJB中提供的注释来定义类和类之间的关联关系,剩下的一对多、多对一和多对多三种关系将只在文章最后进行说明,请读者参考一对一关系的实现过程。

  面向对象的世界里,类A和类B之间的一对一关系必须满足如下条件:

  1. 对象A1引用了对象B1
  2. 类A其他对象An不可能应用同样的对象B1

  在关系数据库中,我们通常使用唯一外键的方式来实现一对一关系,下面这个图说明了这种的情况。

  下面开始介绍一下Kodo EJB中和一对一关系实现相关的知识,为了说明的需要,我们首先定义一个虚拟的场景。

  模拟场景

  我们假定要完成一个图书馆管理系统,该系统中需要管理很多书,我们需要记录书的基本信息如编号、书名、出版日期等基本信息,还需要记录书的前言,序等信息。

  假设我们根据上面的需求,将书设计成一个类(Book),包括了书的编号和名称两个属性,同时将书的前言信息设计成另外一个类(BookExtend),它包括了书的编号和前言信息两个属性。由于一本书有前言而且也不可能有其他的书前言部分会和他一样,所以类Book和BookExtend之间很自然的形成了一对一的关系。这两个类的属性以及类之间的关系如下图所示。

  [注]

  1、为了说明的简单,例子设计时每个对象仅仅选择了必要的属性。

  2、上面的设计仅仅为了演示的要求而特意采用,不代表设计合理。

  Kodo EJB中和一对一关系实现相关的内容

  在Kodo EJB中,我们可以使用简单的OneToOne注释来声明类和类之间的一对一关系,另外可选的,我们可以使用JoinColumn注释来声明两个类对应的表之间使用什么字段来进行关联。

  OneToOne

  OneToOne注释提供了5个属性供开发者定义类和类之间一对一关系的细节内容。

  1. targetEntity

    Class类型的属性。

    定义关系类的类型,默认是该成员属性对应的类类型,所以通常不需要提供定义。

  2. mappedBy

    String类型的属性。

    定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义,否则可能引起数据一致性的问题。比如上面的演示场景中,我们只是定义Book类有BookExtend属性,而BookExtend并没有Book属性,那么他们是单向关系,如何BookExtend中也定义了Book属性,那么Book和BookExtend之间就构成了双向关系。

  3. cascade

    CascadeType[]类型。

    该属性定义类和类之间的级联关系。定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。举个例子:Book和BookExtend有级联关系,那么删除Book时将同时删除它所对应的BookExtend对象。而如果BookExtend还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。

    cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个选择是使用CascadeType.ALL,表示选择全部四项。

  4. fatch

    FetchType类型的属性。

    可选择项包括:FetchType.EAGER和FetchType.LAZY。前者表示关系类在主类加载的时候同时加载,后者表示关系类在被访问时才加载。默认值是FetchType.EAGER。

  5. optional

    boolean类型的属性。

    定义该关联类对是否必须存在。如果设置为false,那么该属性就不能设置为null。默认值是true。

  OneToOne用法举例

public class Book{ // 其他内容… @OneToOne(optional=true,cascade=CascadeType.ALL) public BookExtend bookExtend; } 

  JoinColumn

  JoinColumn注释用于定义主类在数据库中对应的表通过什么字段和关系类的主键进行关联,这个注释是可选的,如果不提供该注释,Kodo在使用”对象名_ID”和关联表进行关联(简单情况下),比如演示场景中类Book的bookExtend没有使用JoinColumn注释进行声明,我们使用Kodo EJB提供的Mapping Tool工具生成表格的时候,Book类对应的表Book中将自动加入列bookExtend_ID,它的类型将和BookExtend对应表的主键字段id类型保持一致。

  JoinColumn注释中有两个属性:name和referencedColumnName属性。

  1. name

    String类型。

    它用于指定主类对应的表中和关系类的主键进行关联的字段的名称,比如上例中,我们不希望使用默认的bookExtend_ID字段名进行关联,我们可以在Book类中使用JoinColumn注释bookExtend属性,设置JoinColumn注释为自己想要的名字比如extendID或者其他。

  2. referencedColumnName

    String类型。

    指定关联表中与主表形成关联关系的字段名。主要用于设置区别于主键字段的情况。比如BookExtend表中默认使用Id进行关联,但现在需要使用其他字段进行关联,我们就可以提供该属性。

  JoinColumn用法举例

public class Book{ // 其他内容… @OneToOne(optional=true,cascade=CascadeType.ALL) @JoinColumn(name="extendID",referencedColumnName="ID") public BookExtend bookExtend; } 

  编写符合要求的持久化类

  现在我们开始根据上面章节中介绍的内容编写符合模拟场景中要求的Book类和BookExtend类,下面是作者编写的两个类的全部代码,代码中加入了比较多的注释方便大家理解。

  Book类

package org.vivianj.kodo.examples.beans; import javax.persistence.Basic; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; import javax.persistence.OneToOne; /**  * Book 用于表征系统中的书籍对象,他有三个属性  * id - 书籍编号,书籍编号将由MySQL数据库自动生成  * name - 书名  * bookExtend – 书的扩展信息,和BookExtend是一对一(OneToOne)关系  */ /* Entity注释表示该类是持久化类,的name属性是该实体在查询中对应的唯一名称,默认是类名 */ @Entity(name = "Book") /* Table注释的name属性指定该持久化类对应的数据表的名称,默认数据表名和类名保持一致,为了  * 增强代码的可移植性,建议大家在name属性中使用大写英文字母 */ /* Inheritance注释的strategy确定了持久化对象和数据表之间的关系,可选择项包括SINGLE_TABLE、JOINED和TABLE_PER_CLASS,我们这里采用JOINED   */  /* TABLE_PER_CLASS : strategy 设置为该选项表示每个类使用一个表,也就是上面所说的第一种情况*/  /* SINGLE_TABLE : strategy 设置为该选项表示所有类及其子类共用一个表,也就是上面所说的第二种情况*/  /* JOINED : strategy 设置为该选项表示每个类使用子表保存子类比父类多出的属性,也就是上面所说的第三种情况*/ @Inheritance(strategy = InheritanceType.JOINED) public class Book {  /* Id注释表示该字段是标识字段 */  @Id  /* GeneratedValue注释定义了该标识字段的产生方式,我们的演示系统中id由MySQL数据库字段自动生成,因此选择GenerationType.IDENTITY */  @GeneratedValue(strategy = GenerationType.IDENTITY)  /* Column注释的name属性定义了该类属性对应的数据字段的名称,为了最大限度保持系统和数据库之前的独立性,建议使用大写字符 */  @Column(name = "ID")  public int id;  /* Basic注释表示该属性是基本属性 */  @Basic  /* Column注释的name属性定义了该类属性对应的数据字段的名称,为了最大限度保持系统和数据库之前的独立性,建议使用大写字符 */  @Column(name = "NAME")  public String name = null;   /* 使用OneToOne注释表示该属性和Book类形成一对一关系,OneToOne注释的option属性设为True表示该对象可以不存在,cascade属性设置为CascadeType.ALL,表示Book和BookExtend对象级联新建、更新、删除、刷新 */  @OneToOne(optional=true,cascade=CascadeType.ALL)  /* 使用JoinColumn注释设置两个对象对应数据库表之间的关联字段 */  @JoinColumn(name="extendID",referencedColumnName="ID")  public BookExtend bookExtend; } 

  BookExtend类

package org.vivianj.kodo.examples.beans; import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.InheritanceType; import javax.persistence.JoinColumn; /**  * BookExtend 用于表征系统中书的扩展信息,他有两个属性:  * id - 扩展信息编号,扩展信息编号将由MySQL数据库自动生成  * name - 书的前言信息  */ /* Entity注释表示该类是持久化类,的name属性是该实体在查询中对应的唯一名称,默认是类名 */ @Entity /* Table注释的name属性指定该持久化类对应的数据表的名称,默认数据表名和类名保持一致,为了  * 增强代码的可移植性,建议大家在name属性中使用大写英文字母 */ /* Inheritance注释的strategy确定了持久化对象和数据表之间的关系,可选择项包括  * SINGLE_TABLE、JOINED和TABLE_PER_CLASS,我们这里采用JOINED   */  /* TABLE_PER_CLASS : strategy 设置为该选项表示每个类使用一个表,也就是上面所说的第一种情况*/  /* SINGLE_TABLE : strategy 设置为该选项表示所有类及其子类共用一个表,也就是上面所说的第二种情况*/  /* JOINED : strategy 设置为该选项表示每个类使用子表保存子类比父类多出的属性,也就是上面所说的第三种情况*/ @Inheritance(strategy = InheritanceType.JOINED) public class BookExtend {  /* Id注释表示该字段是标识字段 */  @Id  /* GeneratedValue注释定义了该标识字段的产生方式,我们的演示系统中id由MySQL数据库字段自动生成,因此选择GenerationType.IDENTITY */  @GeneratedValue(strategy = GenerationType.IDENTITY)  /* Column注释的name属性定义了该类属性对应的数据字段的名称,为了最大限度保持系统和数据库之前的独立性,建议使用大写字符 */  @Column(name = "ID")  public int id;  /* Basic注释表示该属性是基本属性 */  @Basic  /* Column注释的name属性定义了该类属性对应的数据字段的名称,为了最大限度保持系统和数据库之前的独立性,建议使用大写字符 */  @Column(name = "NAME")  public String name = null; } 

  调用代码

  上面的代码中,我们已经准备好了符合要求的持久化类,下面我们看看Kodo EJB中如何调用这两个类完成Book类和BookExtend类的创建、修改、删除工作。

  由于篇幅的关系,这些没有讲述如何编译、加强这些类并且准备相应的配置文件来完成整个项目开发环境的建立,这部分的内容请参考我的另外一篇文章《Kodo EJB:符合EJB3规范的持久层框架

  级联新建对象

  下面的这段代码演示了只需要调用Book类的persist方法就同时持久化Book类对象和BookExtend类对象的情况。请注意其中用粗体标识出的部分。

/* 获得EJB的实体管理器 */ EntityManagerFactory emf = Persistence.createEntityManagerFactory(null); EntityManager em = emf     .createEntityManager(PersistenceContextType.EXTENDED); /* 开始事务 */ em.getTransaction().begin();    /* 创建新的Book对象 */ Book book = new Book(); /* 设置Book对象的name属性 */ book.name = "Kodo入门"; /* 创建新的BookExtend对象 */ BookExtend bookExtend = new BookExtend(); /* 设置对象属性 */ bookExtend.name = "Spring is a very good book that ..."; /* 建立对象之间的关系 */ book.bookExtend = bookExtend; /* 持久化对象,只需要持久化Book对象,不需要单独持久化bookExtend对象 */ em.persist(book); /* 结束事务 */ em.getTransaction().commit(); em.close(); emf.close(); 

  级联更新对象状态

  下面的这段代码演示了只需要调用Book类的merge方法就同时更新Book类对象和BookExtend类对象状态的情况。请注意其中用粗体标识出的部分。

/* 获得EJB的实体管理器 */ EntityManagerFactory emf = Persistence.createEntityManagerFactory(null); EntityManager em = emf     .createEntityManager(PersistenceContextType.EXTENDED); /* 开始事务 */ em.getTransaction().begin();    /* 创建新的Book对象 */ Book book = new Book(); /* 设置Book对象的id属性 */ book.id= 1; book.name = “Kodo 入门”; /* 创建新的BookExtend对象 */ BookExtend bookExtend = new BookExtend(); /* 设置对象属性 */ bookExtend.id=1; bookExtend.name = "Kodo 分为Kodo EJB和Kodo JDO ..."; /* 建立对象之间的关系 */ book.bookExtend = bookExtend; /* 持久化对象,只需要调用Book对象的merge方法,不需要单独处理bookExtend对象 */ em.merge(book); /* 结束事务 */ em.getTransaction().commit(); em.close();  emf.close(); 

  级联删除对象

/* 获得EJB的实体管理器 */ EntityManagerFactory emf = Persistence.createEntityManagerFactory(null); EntityManager em = emf     .createEntityManager(PersistenceContextType.EXTENDED); /* 开始事务 */ em.getTransaction().begin(); /* 使用查询删除对象,可以不必将对象加入到内存中,提高效率 */ Query q = entityManager     .createQuery("delete from Book c WHERE c.id=:id"); int id = book.id; /* 设置被删除Book对象的主键值 */ q.setParameter("id", id); /* 当方法被调用时,Book对象对应的BookExtend对象会同时被删除 */ q.executeUpdate(); /* 结束事务 */ em.getTransaction().commit(); em.close();  emf.close(); 

  其他几种关联关系

  一对多

  我们可以使用OneToMany注释来描述类和类之间的一对多关系,OneToMany注释有四个属性:targetEntity、mappedBy、cascade和fetch,这四个属性的具体含义和OneToOne注释注释的同名属性一一对应,请大家参考前面章节中的内容。

  多对一

  我们可以使用ManyToOne注释来描述类和类之间的多对一关系,ManyToOne注释有四个属性:targetEntity、cascade、fetch和optional,这四个属性的具体含义和OneToOne注释注释的同名属性一一对应,请大家参考前面章节中的内容。

  多对多

  我们可以使用ManyToMany注释来描述类和类之间的多对多关系,ManyToMany注释有四个属性:targetEntity、mappedBy、cascade和fetch,这四个属性的具体含义和OneToOne注释注释的同名属性一一对应,请大家参考前面章节中的内容。

  总结

  对象和对象之间除了继承关系之外,还存在着关联关系,包括一对一、一对多、多对一和多对多的关系,本文中,作者以一对一关系为例,结合简单的例子,详细地描述了如何在Kodo EJB框架下通过注释简单的描述类和类之间的关系,并且实现类操作的级联特性。文章的最后简单的说明了Kodo EJB中实现一对多、多对一和多对多时需要用到的注释,具体的实现请大家参考文档中的内容自行完成。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索对象
, 注释
, 类关系
, 属性
, 对应关系
, 字段
, persistence
, 多对一保存
, 递归删除级联关系表
, 之间
, 可持久化类
, 类属性
, 删除EM
数据库类
kodi、kodo什么意思、kodo可多、kodo 马自达、kodu,以便于您获取更多的相关知识。

时间: 2024-11-01 16:29:18

Kodo EJB:实现类和类之间的关联关系的相关文章

Kodo EJB:符合EJB3规范的持久层框架

规范 Kodo是BEA公司收购SolarMetric公司后获得的持久层框架项目,以前只是支持JDO标准,2006年2月13日,BEA公司宣布发布Kodo项目的最新版本--Kodo 4.0.0 Early Access 4,Kodo 4.0.0 EA4支持EJB3和JDO2两个标准,本文中,我们将首先学习和了解KODO EJB,了解如何使用Kodo EJB完成开发工作. 我们将按照两种不同的情况讲述如何使用Kodo EJB进行开发,一种是通过命令行工具,另外一种是在Eclipse中使用Ant任务.

类与类之间的几种关系

一.继承关系      继承指的是一个类(称为子类.子接口)继承另外的一个类(称为父类.父接口)的功能,并可以增加它自己的新功能的能力.在Java中继承关系通过关键字 extends明确标识,在设计时一般没有争议性.在UML类图设计中,继承用一条带空心三角箭头的实线表示,从子类指向父类,或者子接口指向父接口.  二.实现关系      实现指的是一个class类实现interface接口(可以是多个)的功能,实现是类与接口之间最常见的关系.在Java中此类关系通过关键字 implements明确

java-JAVA类和类之间的赋值问题

问题描述 JAVA类和类之间的赋值问题 建立下三个类(文件那种)public class Dto { public String hehe;public String getHehe() { return hehe;}public void setHehe(String hehe) { this.hehe = hehe;} }2.R.javapublic class R { public void hehe() { String test = ""test""; D

简单谈谈Java类与类之间的关系_java

类与类之间最常见的关系主要有三种:依赖(uses-a).聚合(has-a)和继承(is-a). 下面以在线书店订单系统为例,来详细的讲述这三种关系的概念. 在线书店订单系统的主要功能是:注册用户可以登录到网上书店选购图书,在线填写订单,并支付购书款.书店确认已经收到购书款时,按用户留下的地址邮寄图书.可以在这个系统中建立几个类,有图书(book).账户(account).订单(order).地址(address)等,如下图所示: 依赖(uses-a) 依赖关系是类中最常见的关系,例如订单类(or

图解UML类与类之间的六中关系

大话设计模式上的一个图,我用EA画出来的:  UML中的6大关系相关英文及音标:  依赖关系   dependency   [di'pendənsi]  关联关系   association    [ə,səuʃi'eiʃən]  聚合关系   aggregation    [ˌægrɪˈgeɪʃən]  组合关系 composition  [,kɔmpə'ziʃən]  实现   realization    [,ri:əlɪ'zeɪʃən]  泛化   generalization    [

类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类

 常量的基本类型转换,例如:int num(10.8),这种方式是隐式转换. 通过函数的构造函数实现转换. 类类转换函数,当构造函数不能将类型转换成基本类型时.所以就有了类类转换函数,通过这种方式. 案例: #include <iostream> class fushu { public: //通过加explicit的这种方式避免隐式转换,避免引发歧义 explicit fushu(int num) { x = num; y = num; } void print() { std::cou

组件,控件,类这三者之间的区别

问题描述 各位大侠:初学.NET,想问下组件,控件,类这三者之间的区别? 解决方案 解决方案二:控件:在ide中左边工具条中出现的东东,可以直接拖到界面上使用的组件:编译后的实体.比如在一个解决方案中有一个项目是对数据库操作的,如果写得比较好,以后可以继续在其他解决方案中使用,那么可以将其编译成组件,可以提高效率(webcast中mordenc#第9讲有简单介绍,可以看看)类:一种数据结构,可以包含数据成员,函数成员等等,通俗点说,你可以定义一个公共类,那么一个公共变量.公共方法可以放在这个类中

在Java EE环境下使用Kodo EJB

Kodo EJB是一个支持对象/关系映射的框架,根据EJB3规范的要求,Kodo EJB除了支持在普通Java应用中提供轻量级的持久层框架之外,也支持在JAVA EE容器中使用满足重量级企业应用的需求,充分利用JAVA EE容器中提供的优越特性如容器管理事务.远程(Remote)访问. 基于Kodo EJB开发的应用支持使用EJB或者JCA标准接入到JAVA EE环境中: JCA Kodo EJB支持JCA1.0标准,因此基于Kodo EJB开发的应用可以和其他JCA资源一样轻松的发布到JAVA

【C/C++学院】0817-递归汉诺塔 双层递归 /CPP结构体 /面向过程与面向对象的编程模式/类的常识共用体实现一个类的特征/QT应用于类以及类的常识

递归汉诺塔 双层递归 #include <iostream> void han(int n, char A, char B, char C) { static int num = 1; std::cout << "第" << num << "次"; num++; if (n<1) { return; } else { han(n - 1, A, C, B); std::cout << A <&l