一、结构

二、代码

1.

 package org.jpwh.model.advanced;

 import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Currency; /*
This value-typed class should be <code>java.io.Serializable</code>: When Hibernate stores entity
instance data in the shared second-level cache (see <a href="#Caching"/>), it <em>disassembles</em>
the entity's state. If an entity has a <code>MonetaryAmount</code> property, the serialized
representation of the property value will be stored in the second-level cache region. When entity
data is retrieved from the cache region, the property value will be deserialized and reassembled.
*/
public class MonetaryAmount implements Serializable { /*
The class does not need a special constructor, you can make it immutable, even with
<code>final</code> fields, as your code will be the only place an instance is created.
*/
protected final BigDecimal value;
protected final Currency currency; public MonetaryAmount(BigDecimal value, Currency currency) {
this.value = value;
this.currency = currency;
} public BigDecimal getValue() {
return value;
} public Currency getCurrency() {
return currency;
} /*
You should implement the <code>equals()</code> and <code>hashCode()</code>
methods, and compare monetary amounts "by value".
*/
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MonetaryAmount)) return false; final MonetaryAmount monetaryAmount = (MonetaryAmount) o; if (!value.equals(monetaryAmount.value)) return false;
if (!currency.equals(monetaryAmount.currency)) return false; return true;
} public int hashCode() {
int result;
result = value.hashCode();
result = 29 * result + currency.hashCode();
return result;
} /*
You will need a <code>String</code> representation of a monetary
amount. Implement the <code>toString()</code> method and a static method to
create an instance from a <code>String</code>.
*/
public String toString() {
return getValue() + " " + getCurrency();
} public static MonetaryAmount fromString(String s) {
String[] split = s.split(" ");
return new MonetaryAmount(
new BigDecimal(split[0]),
Currency.getInstance(split[1])
);
}
}

2.

 package org.jpwh.converter;

 import org.jpwh.model.advanced.MonetaryAmount;

 import javax.persistence.AttributeConverter;
import javax.persistence.Converter; @Converter(autoApply = true) // Default for MonetaryAmount properties
public class MonetaryAmountConverter
implements AttributeConverter<MonetaryAmount, String> { @Override
public String convertToDatabaseColumn(MonetaryAmount monetaryAmount) {
return monetaryAmount.toString();
} @Override
public MonetaryAmount convertToEntityAttribute(String s) {
return MonetaryAmount.fromString(s);
}
}

3.

 package org.jpwh.model.advanced.converter;

 import org.jpwh.converter.MonetaryAmountConverter;
import org.jpwh.model.advanced.MonetaryAmount; import javax.persistence.Column;
import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.validation.constraints.NotNull;
import java.util.Date; @Entity
public class Item { @Id
@GeneratedValue(generator = "ID_GENERATOR")
protected Long id; @NotNull
protected String name; @NotNull
@Convert( // Optional, autoApply is enabled
converter = MonetaryAmountConverter.class,
disableConversion = false)
@Column(name = "PRICE", length = 63)
protected MonetaryAmount buyNowPrice; @NotNull
protected Date createdOn = new Date(); public Long getId() {
return id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public MonetaryAmount getBuyNowPrice() {
return buyNowPrice;
} public void setBuyNowPrice(MonetaryAmount buyNowPrice) {
this.buyNowPrice = buyNowPrice;
} // ...
}

4.

 package org.jpwh.model.advanced.converter;

 abstract public class Zipcode {

     protected String value;

     public Zipcode(String value) {
this.value = value;
} public String getValue() {
return value;
} @Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Zipcode zipcode = (Zipcode) o;
return value.equals(zipcode.value);
} @Override
public int hashCode() {
return value.hashCode();
}
}

5.

 package org.jpwh.converter;

 import org.jpwh.model.advanced.converter.GermanZipcode;
import org.jpwh.model.advanced.converter.SwissZipcode;
import org.jpwh.model.advanced.converter.Zipcode; import javax.persistence.AttributeConverter;
import javax.persistence.Converter; @Converter
public class ZipcodeConverter
implements AttributeConverter<Zipcode, String> { @Override
public String convertToDatabaseColumn(Zipcode attribute) {
return attribute.getValue();
} @Override
public Zipcode convertToEntityAttribute(String s) {
if (s.length() == 5)
return new GermanZipcode(s);
else if (s.length() == 4)
return new SwissZipcode(s); // If you get to this point, you should consider
// cleaning up your database... or you can create
// an InvalidZipCode subclass and return it here. throw new IllegalArgumentException(
"Unsupported zipcode in database: " + s
);
}
}

6.

 package org.jpwh.model.advanced.converter;

 public class GermanZipcode extends Zipcode {

     public GermanZipcode(String value) {
super(value);
}
}

7.

 package org.jpwh.model.advanced.converter;

 public class SwissZipcode extends Zipcode {

     public SwissZipcode(String value) {
super(value);
}
}

8.

 package org.jpwh.model.advanced.converter;

 import org.jpwh.converter.ZipcodeConverter;
import org.jpwh.model.Constants; import javax.persistence.Convert;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import java.io.Serializable; @Entity
@Table(name = "USERS")
public class User implements Serializable { @Id
@GeneratedValue(generator = Constants.ID_GENERATOR)
protected Long id; @NotNull
protected String username; // Group multiple attribute conversions with @Converts
@Convert(
converter = ZipcodeConverter.class,
attributeName = "zipcode" // Or "city.zipcode" for nested embeddables
)
protected Address homeAddress; public Long getId() {
return id;
}
public String getUsername() {
return username;
} public void setUsername(String username) {
this.username = username;
} public Address getHomeAddress() {
return homeAddress;
} public void setHomeAddress(Address homeAddress) {
this.homeAddress = homeAddress;
} // ...
}

9.

 package org.jpwh.model.advanced.converter;

 import javax.persistence.Column;
import javax.persistence.Embeddable;
import javax.validation.constraints.NotNull; @Embeddable
public class Address { @NotNull
@Column(nullable = false)
protected String street; @NotNull
@Column(nullable = false, length = 5)
protected Zipcode zipcode; @NotNull
@Column(nullable = false)
protected String city; protected Address() {
} public Address(String street, Zipcode zipcode, String city) {
this.street = street;
this.zipcode = zipcode;
this.city = city;
} public String getStreet() {
return street;
} public void setStreet(String street) {
this.street = street;
} public Zipcode getZipcode() {
return zipcode;
} public void setZipcode(Zipcode zipcode) {
this.zipcode = zipcode;
} public String getCity() {
return city;
} public void setCity(String city) {
this.city = city;
}
}

也可以转换集合,If several @Convert annotations are required on a single embedded property, to convert several attributes of the Address , for example, you can group them within an @Converts annotation. You can also apply converters to values of collections and maps, if their values and/or keys are of basic or embeddable type. For example, you can add the @Convert annotation on a persistent Set<Zipcode> . We’ll show you how

to map persistent collections later, with @ElementCollection , in chapter 7.
For persistent maps, the attributeName option of the @Convert annotation has some special syntax:

 On a persistent Map<Address, String> , you can apply a converter for the zipcode property of each map key with the attribute name key.zipcode .
 On a persistent Map<String, Address> , you can apply a converter for the zipcode property of each map value with the attribute name value.zipcode .
 On a persistent Map<Zipcode, String> , you can apply a converter for the key of each map entry with the attribute name key .
 On a persistent Map<String, Zipcode> , you can apply a converter for the value of each map entry by not setting any attributeName .
As before, the attribute name can be a dot-separated path if your embeddable classes are nested; you can write key.city.zipcode to reference the zipcode property of the City class, in a composition with the Address class.
Some limitations of the JPA converters are as follows:
 You can’t apply them to identifier or version properties of an entity.
 You shouldn’t apply a converter on a property mapped with @Enumerated or @Temporal , because these annotations already declare what kind of conversion has to occur. If you want to apply a custom converter for enums or date/time properties, don’t annotate them with @Enumerated or @Temporal .
 You can apply a converter to a property mapping in an hbm.xml file, but you have to prefix the name: type="converter:qualified.ConverterName" .

JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-006类型转换器( @Converter(autoApply = true) 、type="converter:qualified.ConverterName" )的更多相关文章

  1. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-001Mapping basic properties(@Basic、@Access、access="noop"、@Formula、@ColumnTransformer、@Generated、 @ColumnDefaul、@Temporal、@Enumerated)

    一.简介 在JPA中,默认所有属性都会persist,属性要属于以下3种情况,Hibernate在启动时会报错 1.java基本类型或包装类 2.有注解 @Embedded 3.有实现java.io. ...

  2. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-007UserTypes的用法(@org.hibernate.annotations.Type、@org.hibernate.annotations.TypeDefs、CompositeUserType、DynamicParameterizedType、、、)

    一.结构 二.Hibernate支持的UserTypes接口  UserType —You can transform values by interacting with the plain JD ...

  3. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-005控制类型映射(Nationalized、@LOB、@org.hibernate.annotations.Type)

    一.简介 1. 2. 3. 4. to override this default mapping. The JPA specification has a convenient shortcut a ...

  4. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-004嵌套组件的注解AttributeOverrides

    一.数据库 二.代码 1. package org.jpwh.model.advanced; import javax.persistence.AttributeOverride; import ja ...

  5. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-003使用@AttributeOverrides

    Each @AttributeOverride for a component property is “complete”: any JPA or Hibernate annotation on t ...

  6. JavaPersistenceWithHibernate第二版笔记-第五章-Mapping value types-002使用@Embeddable

    一.数据库 二.代码 1. package org.jpwh.model.simple; import javax.persistence.Column; import javax.persisten ...

  7. JavaPersistenceWithHibernate第二版笔记-第四章-Mapping persistent classes-003映射实体时的可选操作(<delimited-identifiers/>、PhysicalNamingStrategy、PhysicalNamingStrategyStandardImpl、、、)

    一.自定义映射的表名 1. @Entity @Table(name = "USERS") public class User implements Serializable { / ...

  8. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-003Table per concrete class with unions(@Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)、<union-subclass>)

    一.代码 1. package org.jpwh.model.inheritance.tableperclass; import org.jpwh.model.Constants; import ja ...

  9. JavaPersistenceWithHibernate第二版笔记-第六章-Mapping inheritance-002Table per concrete class with implicit polymorphism(@MappedSuperclass、@AttributeOverride)

    一.结构 二.代码 1. package org.jpwh.model.inheritance.mappedsuperclass; import javax.persistence.MappedSup ...

随机推荐

  1. 霍夫变换(hough transform)

    x-y轴坐标:y=kx+b k-b轴坐标:b=-xk+y θ-r轴坐标:

  2. Ubuntu系统安装配置Pintos和Bochs

    Ubuntu系统安装配置 Pintos 和 Bochs 安装过程 首先是UEFI启动模式下Win8.1安装Ubuntu14.04双系统,由于篇幅过长,就不在这里详写.可见博主的另一篇博客http:// ...

  3. 硬件相关-JTAG接口

    JTAG(Joint Test Action Group,联合测试行动小组)是一种国际标准测试协议,用于系统仿真.调试及芯片内部测试.它通过访问芯片内部封装好的测试电路TAP(Test Access ...

  4. 三、freemarker数据、模版指令

    数据类型 1.         直接指定值(字符串.数值.布尔值.集合.Map对象) 2.         字符串:直接指定字符串使用单引号.双引号,字符中间可以使用转义符“\”,如果字符内有大量特殊 ...

  5. android 通过httpclient下载文件并保存

    代码:(主要针对图片.gif下载无问题) /** * 下载网络文件 * @param url 请求的文件链接 * @param IsMD5Name 是否MD5加密URL来命名文件名 * @param ...

  6. 【反射】——Autofac 类型注册

    Autofac是.net界一款轻量化的IOC组件,使用Autofac可以帮助完成代码中很多依赖注入工作.在以前文章中,介绍过Autofac的配置过程(http://www.cnblogs.com/Jn ...

  7. KMP算法原理

    前几天在看数据结构与算法,里面提到过kmp算法,一个超级经典的字符串匹配算法.虽然网上有一大堆关于kmp算法的介绍文章,但是我看过之后还是“不明觉厉”.所以打算自己写写,大家一起学习吧. 一.关于KM ...

  8. ZeroMQ 在 centos 6.5_x86_64 下的安装

    ZeroMQ 在 centos 6.5_x86_64 下的安装 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs 一.ZeroMQ介绍 ZeroMQ是一个开 ...

  9. 亚马逊 在线测试题目 amazon (变种的)三叉树的最近公共祖先问题

    题目意思就是找一棵按上面链接所示的树对应的上面的两个点的最小公共祖先(LCP,Least Common Father),按照比较大小来依次返回自己的父亲节点就行了.具体看代码:getfather(a) ...

  10. WinHex分析PE格式(2)&& 如何手动添加区段并运行区段

    由于这次文章内容比较多 所以写成DOC文档 为了复习所学的知识,我在原本的软件里试者手动加入区段 ,并写给大家分享,还试试者用LordPE加区段发现竟然失败了, 还是自己动手比较实在,完美运行. 利用 ...