扩展您的JPA POJO

可扩展性是许多体系结构的重要特征。 它衡量是否容易(或困难)
它是在不影响现有核心系统功能的情况下添加或更改功能。

让我们举一个简单的例子。 假设您的公司拥有一个核心产品来跟踪体育俱乐部中的所有用户。 在您的产品体系结构中,您有一个由JPA POJO表示的域模型。 域模型包含许多POJO,当然包括用户POJO。

package com.alex.staveley.persistence
/*** User entity.  Represents Users in the Sports Club. * * Note: The SQL to generate a table for this in MySQL is:** CREATE TABLE USER (ID INT NOT NULL auto_increment, NAME varchar(255) NOT NULL, *  PRIMARY KEY (ID)) ENGINE=InnoDB;*/ 
@Entity
public class User {/* Surrogate Key - automatically generated by DB. */ @GeneratedValue(strategy=GenerationType.IDENTITY) @Idprivate int id;private String name;public int getId() {return id;}public void setName(String name) {this.name=name;}public String getName() {return name;}
}

现在,一些客户喜欢您的产品,但是他们需要在购买之前进行一些定制。 例如,
一位客户希望将属性出生地添加到用户,并希望此属性持续存在。 当然,此属性的逻辑位置是在用户POJO中,但是没有其他客户想要此属性。 所以你会怎么做?

您是否仅为此客户创建了特定的User类,然后才为他们交换了该类? 怎么了
当您更改产品用户类别时呢? 如果另一个客户想要另一个定制怎么办? 还是改变主意? 您是否感觉事情会变得混乱?

幸运的是,JPA的一种实现:Eclipselink在这里提供了帮助。 2.3版本 (自2011年6月开始提供,最新版本是2011年12月9日最近发布的2.3.2维护)包括一些非常好的功能,可以解决这种情况。 让我们详细说明。 通过将@VirtualAccessmethods Eclipselink注释简单地添加到POJO,我们向Eclipselink发出信号,表明POJO可能具有一些额外的( 也称为虚拟 )属性。 您不必在代码中指定任何这些额外的属性, 否则它们将不是非常虚拟的 ! 您只需要指定一个通用的getter和setter来满足他们的获取和设置。 您还必须在某个地方将它们存储在内存中,就像一个很好的旧哈希图-当然这应该是暂时的,因为我们不持久保存哈希图本身。 注意:它们不必存储在HashMap中,这只是一个流行的选择!

让我们看一下我们现在可以扩展的用户。

@Entity
@VirtualAccessMethods
public class User {/* Surrogate Key - automatically generated by DB. */@GeneratedValue(strategy=GenerationType.IDENTITY) @Idprivate int id;private String name;@Transientprivate Map<String, Object> extensions = new HashMap();public int getId() {return id;}public void setName(String name) {this.name=name;}public String getName() {return name;}public <t> T get(String name) {return (T) extensions.get(name);}public Object set(String name, Object value) {return extensions.put(name, value);} 
}

那是吗? 好吧,还有更多的魔术。 您必须告诉eclipselink您的其他属性。 更具体地说:它们的名称和数据类型是什么。
您可以通过更新eclipselink-orm.xml来做到这一点,该文件位于persistent.xml所在的同一META-INF文件夹中。

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="http://www.eclipse.org/eclipselink/xsds/persistence/orm"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.eclipse.org/eclipselink/xsds/persistence/orm http://www.eclipse.org/eclipselink/xsds/eclipselink_orm_2_1.xsd"version="2.1"><entity class="com.alex.staveley.persistence.User"><attributes><basic name="thebirthplace" attribute-type="String" access="VIRTUAL"><column name="birthplace"/><access-methods get-method="get" set-method="set"/></basic></attributes></entity> 
</entity-mappings>

现在,此配置简单说明,用户实体具有一个附加属性,在Java中,该属性是“ thebirthplace”,并且是虚拟的。 这意味着它不是在POJO中明确定义的,但是如果我们要调试东西,我们会在内存中看到该属性的名称为“出生地”。

此配置还指出该属性的相应数据库列是出生地。
eclipselink可以使用通用的get / set方法来获取和设置此方法。

你想测试吗?

将列添加到数据库表中。 在MySql中,这将是:

alter table用户添加列的出生地varchar(64)

然后运行以下简单测试:

@Test
public void testCreateUser() {User user = new User();user.setName("User1Name");user.set("thebirthplace", "donabate");entitymanager.getTransaction().begin();entitymanager.persist(user);entitymanager.getTransaction().commit();entitymanager.close();
}

因此,现在,我们可以在产品代码中添加一个可扩展的用户POJO。 每个客户都可以根据需要将自己的属性添加到用户。 当然,每个客户都与
仅通过确保每个客户的扩展都驻留在特定的eclipslink-orm.xml中,即可非常轻松地实现所有其他客户。 请记住,您可以根据需要随意命名这些文件,如果不使用默认名称,则只需更新persistence.xml文件以声明正在使用的名称

这种方法意味着,当我们想要更新产品中的User时,我们只需要更新一个,并且仅更新User POJO( 因为我们确保只有一个 )。 但是,当必须为特定客户添加特定属性时,我们无需触摸用户POJO代码。 我们简单地对XML进行更改,而不必重新编译核心产品中的任何内容。 当然,在任何时候,只要查看适当的eclipselink-orm.file,就可以轻松了解针对任何客户的定制。

是的 快乐扩展!

参考文献:

  1. 在都柏林的技术博客上,从我们的JCG合作伙伴 Alex Staveley 扩展您的JPA POJO
  2. http://wiki.eclipse.org/EclipseLink/UserGuide/JPA/Advanced_JPA_Development/Extensible_Entities
  3. http://www.eclipse.org/eclipselink/

相关文章 :

  • Spring Data JPA的持久层
  • 具有GlassFish和一致性的高性能JPA –第1部分
  • 避免延迟的JPA集合
  • JBoss 4.2.x Spring 3 JPA Hibernate教程
  • Java Persistence API:快速入门

翻译自: https://www.javacodegeeks.com/2012/01/extending-your-jpa-pojos.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/373280.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

web框架--flask

flask介绍Flask是一个基于Python开发并且依赖jinja2模板和Werkzeug WSGI服务的一个微型框架&#xff0c;对于Werkzeug本质是Socket服务端&#xff0c;其用于接收http请求并对请求进行预处理&#xff0c;然后触发Flask框架&#xff0c;开发人员基于Flask框架提供的功能对请求进行…

php spider shell,ScrapyShell使用

Scrapy ShellScrapy终端是一个交互终端&#xff0c;我们可以在未启动spider的情况下尝试及调试代码&#xff0c;也可以用来测试XPath或CSS表达式&#xff0c;查看他们的工作方式&#xff0c;方便我们爬取的网页中提取的数据。如果安装了 IPython &#xff0c;Scrapy终端将使用 …

69 个经典 Spring 面试题和答案

Spring 概述 什么是spring?Spring 是个java企业级应用的开源开发框架。Spring主要用来开发Java应用&#xff0c;但是有些扩展是针对构建J2EE平台的web应用。Spring 框架目标是简化Java企业级应用开发&#xff0c;并通过POJO为基础的编程模型促进良好的编程习惯。使用Spring框架…

高性能MySql

1、索引是对DB优化最有效的方式 varchar(10)定义的是字符的个数&#xff0c;如果是utf-8的话&#xff0c;最大是3X10个字节 二、索引类型 1、MySql的索引是在存储引擎层实现的&#xff0c;各个存储引擎的的索引方式也是不同的 2、B-Tree索引 MyISAM索引通过数据的物理位置引用被…

Java Swing井字游戏

大家好&#xff01; 哇&#xff0c;自从我在这里发布了东西以来已经有一段时间了&#xff01; 我必须说我真的很想写东西&#xff0c;而且我保证我不会再陷入“作家的障碍”。 希望 ..最近两个月发生了很多事情&#xff0c;我有很多话要说。 但是在这篇文章中&#xff0c;我只是…

Java小青蛙跳台街,算法-青蛙跳台阶详解

/*[跳台阶][题目]一只青蛙一次可以跳上1级台阶&#xff0c;也可以跳上2级。求该青蛙跳上一个n级的台阶总共有多少种跳法。[解析]与斐波那契数列的求解过程类似。典型的动态规划问题。对于第 n 级台阶&#xff0c;我们可以从第 n-1 级台阶一步到达&#xff0c;也可以从第 n-2 级…

apache服务器配置Net的实践

前置&#xff1a; 在xp系统中&#xff0c;打补丁之类或啥子操作引起或多或少的问题&#xff0c;最终导致iis不能使用&#xff1b; 不想装系统...忍着... 最近突发事件导致&#xff0c;需要摸一下apache服务器处理&#xff0c;好吧&#xff0c;那就搜索下吧..... 目标&#xff1…

TestNG或JUnit

多年以来&#xff0c;无论何时使用Java代码进行单元测试&#xff0c;我始终会回到TestNG。 每当我拿起TestNG时&#xff0c;人们都问我为什么要继续使用TestNG&#xff0c;尤其是默认开发环境&#xff08;例如Eclipse或Maven&#xff09;提供的JUnit时。 继续进行同样的战斗&am…

event php,PHP event 事件机制

/** PHP 事件机制*/class baseClass{private $_e;public function __set($name,$value){if( strncasecmp($name,"on",2) 0 ){if(!isset($this->_e[$name]))$this->_e[$name] array();return array_push($this->_e[$name] , $value);}}public function __g…

Android JNI编程(五)——C语言的静态内存分配、动态内存分配、动态创建数组...

版权声明&#xff1a;本文出自阿钟的博客&#xff0c;转载请注明出处:http://blog.csdn.net/a_zhon/。 目录(?)[] 一&#xff1a;什么是静态内存什么又是动态内存呢&#xff1f; 静态内存&#xff1a;是指在程序开始运行时由编译器分配的内存&#xff0c;它的分配是在程序开始…

Visual Studio-C#-20160411

函数的四个要素包括&#xff1a;名称&#xff0c;输入&#xff0c;输出&#xff0c;加工 注释的方式&#xff1a;//只注释一行&#xff1b;/**/注释一段区域&#xff1b; namespace ConsoleApplication6 ---------//命名空间{ class Program ---------------------------//类…

配置MyBatis 3

MyBatis是一个非常流行且也是最有效的SQL映射框架。 MyBatis可用于Java和.net语言。 MyBatis并不是Hibernate的真正替代品&#xff0c;但是我们可以使用该框架来减少MyBatis提供的高效和高性能的数据库相关代码。 本教程将向您展示使用数据库配置MyBatis 3的步骤。 MyBatis 3支…

php获取src,PHP读取文件

本文概述PHP提供了各种功能来从文件读取数据。有多种功能允许你读取所有文件数据, 逐行读取数据以及逐字符读取数据。下面提供了可用的PHP文件读取功能。fread()fgets()fgetc()PHP读取文件-fread()PHP fread()函数用于读取文件的数据。它需要两个参数&#xff1a;文件资源和文件…

HDOJ(HDU) 1406 完数

Problem Description 完数的定义&#xff1a;如果一个大于1的正整数的所有因子之和等于它的本身&#xff0c;则称这个数是完数&#xff0c;比如6&#xff0c;28都是完数&#xff1a;6123&#xff1b;28124714。 本题的任务是判断两个正整数之间完数的个数。 Input 输入数据包…

Allegro padstack

在ALLEGRO中&#xff0c;建立PCB封装是一件挺复杂的事&#xff0c;而要建立FOOTPRINT&#xff0c;首先要有一个PAD&#xff0c;所以就要新建PADSTACK。 焊盘可以分两种&#xff0c;表贴焊盘和通孔焊盘&#xff0c;表贴焊盘结构相对简单&#xff0c;下面首先分析表贴焊盘的成分&…

java中datetime类型转换,Java中日期格式和其他类型转换详解

涉及的核心类&#xff1a;Date类、SimpleDateFormat类、Calendar类一、Date型与long型Date型转换为long型Date date new Date();//取得当前时间Date类型long date2long date.getTime();//Date转longlong型转换为Date型long cur System.currentTimeMills();//取得当前时间lon…

GWT MVP变得简单

GWT Model-View-Presenter是用于大规模应用程序开发的设计模式。 它源于MVC&#xff0c;它在视图和逻辑之间进行划分&#xff0c;并有助于创建结构良好&#xff0c;易于测试的代码。 为了帮助像我这样的懒惰开发人员&#xff0c;我研究了如何减少使用声明式UI时要编写的类和接口…

php如何编写通信协议,定制通讯协议

## 如何定制协议实际上制定自己的协议是比较简单的事情。简单的协议一般包含两部分:* 区分数据边界的标识* 数据格式定义## 一个例子### 协议定义这里假设区分数据边界的标识为换行符"\n"(注意请求数据本身内部不能包含换行符)&#xff0c;数据格式为Json&#xff0c…

今年计划要看的书全部备齐

上个月购买的书《今年计划看的书其中几本》 http://www.cnblogs.com/insus/p/5325513.html 昨天购买的书回来了&#xff0c;今年计划要看的书全部备齐。《MongoDB》&#xff0c;《深入理解Bootstarp》和《ASP.NETSignalR编程实践》…… 转载于:https://www.cnblogs.com/in…

Codevs 2756 树上的路径

2756 树上的路径 时间限制: 3 s    空间限制: 128000 KB    题目等级 : 大师 Master题目描述 Description给出一棵树&#xff0c;求出最小的k&#xff0c;使得&#xff0c;且在树中存在路径P&#xff0c;使得k> S 且 k <E. &#xff08;k为路径P上的边的权值和&a…