楼主: jieforest

扩展JPA注释

[复制链接]
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
11#
 楼主| 发表于 2010-1-30 23:55 | 只看该作者
清单 5. @MaximiumValue 和 @MinimiumValue 的定义                               
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MaximumValue {
    String value();
}

@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface MinimumValue {
    String value();
}

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
12#
 楼主| 发表于 2010-1-30 23:55 | 只看该作者
清单 6. 应用 @Maximium 和 @Minimium                               
@Entity
@EntityListeners(value = { TestMaxMinListener.class })
public class TestMaxMin {

    @Basic
    @MinimumValue("1")
    @MaximumValue("100")
    public Integer value;

}

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
13#
 楼主| 发表于 2010-1-30 23:56 | 只看该作者
@MaximiumValue 和 @MinimiumValue 被应用于 Java 类的域中。

与 3.1 类似,在这里设置了回调函数所在的类 TestMaxMinListener,函数如清单 7 所示:

清单 7. 处理 @ MaximiumValue 和 @MinimiumValue 的回调函数                               
public class TestMaxMinListener {

    @PrePersist
    public void prePersist(Object obj) throws Exception {
               
        TestMaxMin tmm = (TestMaxMin)obj;
        Field value = tmm.getClass().getDeclaredField("value");
        MaximumValue max = value.getAnnotation(MaximumValue.class);
        MinimumValue min = value.getAnnotation(MinimumValue.class);
               
        if (tmm.value > max.value() || tmm.value < min.value()){
            System.out.println("The value property is invalid.");
            throw new Exception();
        }
    }
}

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
14#
 楼主| 发表于 2010-1-30 23:56 | 只看该作者
这个 TestMaxMinListener 的作用就是检测相应的属性值是否在规定的范围内,如果超出了规定的范围,那么就会抛出异常,从而防止将错误的数据存入数据库中。

@Unsigned

与上面的情况相同,对于某些属性的值,我们希望它是一个无符号整形数。而在 OpenJPA 中也没有相关的 Annotation 来指定。可以自定义一个 Annottation:@Unsigned 用来表示某个属性的值是无符号数。

清单 8. @Unsigned 的定义                               
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Unsigned {

}

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
15#
 楼主| 发表于 2010-1-30 23:56 | 只看该作者
在 Entity Class 当中可以直接把 @Unsigned 设置在相应的属性前面 , 如清单 9 所示:

清单 9. 应用 @Unsigned                               
@Unsigned
@Basic
private Integer value;



@Unsigned 的处理方式和 @MaximiumnValue 类似,这里就不再一一赘述。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
16#
 楼主| 发表于 2010-1-30 23:56 | 只看该作者
@Required

数据库对表中的各项字段可以定义限制条件,如某些字段不能为空,某些字段为主键等。OpenJPA 定义的 @Column 中提供了字段以限制条件的映射,参考清单 11 中 @Column,将 nullable 设置为 false 来控制字段不能为空。

但是在图 1 所示的应用中,OnlineGame.ServiceProvider 不能为 null,同时必须 SINGLE_TABLE 的继承策略(参照表 1)来映射这一组类,如果仅仅应用 @Column 的 nullable 属性,我们将不得不面临这样一个问题:当试图持久化一个 PCGame 的实例到数据库中时,数据库系统将会提示该数据不能插入,因为数据系统对插入表 1 中的数据要求 ServiceProvider 不能为空。

image001.gif (7.44 KB, 下载次数: 5)

image001.gif

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
17#
 楼主| 发表于 2010-1-30 23:57 | 只看该作者
表 1 . 用 SINGLE_TABLE 在 DB 中存储 Game,OnlineGame 和 PCGameGame 的属性         OnlineGame 的属性         PCGame 的属性
Name         Version         Type         ServiceProvider         …         …



难道为了应用 SINGLE_TABLE 就不得不丢弃字段的约束条件么? @Required 就应运而生了,定义如清单 10。@Required 被用来标记 p1,p2 不能为 null。

就需要在我们自己的程序里面检测 @Required,并对相应的属性值进行判断。这一步通常可以放在 EntityListener 中的 PrePersist 这个回调(Callback)函数中进行检测。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
18#
 楼主| 发表于 2010-1-30 23:57 | 只看该作者
清单 10. @Required 的定义                               
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
public @interface Required {

}

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
19#
 楼主| 发表于 2010-1-30 23:57 | 只看该作者
在 OnlineGame Class 中,可以通过如下清单 11 所示方式设置属性 ServiceProvider:

清单 11. 应用 @Required                               
@Column(name="",nullable=true)
@Basic
@Required
private String ServiceProvider;



数据库不再对 ServiceProvider 是否为空做出约束,但是通过实现标记为 @prePresist 的回调函数,函数中检测是否有 @Required,如果有 @Required,该字段就不能为空。如此 ServiceProvider 的约束条件就不会再成为约束类 PCGame 的条件。

使用道具 举报

回复
论坛徽章:
277
马上加薪
日期:2014-02-19 11:55:14马上有对象
日期:2014-02-19 11:55:14马上有钱
日期:2014-02-19 11:55:14马上有房
日期:2014-02-19 11:55:14马上有车
日期:2014-02-19 11:55:14马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:11版主9段
日期:2012-11-25 02:21:03ITPUB年度最佳版主
日期:2014-02-19 10:05:27现任管理团队成员
日期:2011-05-07 01:45:08
20#
 楼主| 发表于 2010-1-30 23:58 | 只看该作者
@RelationshipMetaData

在 OpenJPA 中,有四个 Annotation 可以用来标识一个实体之间的关系,它们分别是:@OneToOne,@OneToMany,@ManyToOne 和 @ManyToMany。其中每一个 Annotation 都有以下几个属性:targetEntity,mappedBy,cascade,fetch 和 optional。

图 2. 实体 Employee 和 SoftwareLicense 的 ER 图

image002.gif (3.48 KB, 下载次数: 4)

image002.gif

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表