擴展您的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.pswp.cn/news/373280.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/373280.shtml
英文地址,請注明出處:http://en.pswp.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…