如果您想了解使用JPA存储Map和jpamappedby的知识,那么本篇文章将是您的不二之选。我们将深入剖析使用JPA存储Map的各个方面,并为您解答jpamappedby的疑在这篇文章中,我们将为您
如果您想了解使用JPA存储Map
- 使用JPA存储Map
(jpa mappedby) - HashMap
是否应该重构为Enum? - Java Core 中的String,StringBuilder,StringBuffer三者的区别
- Java 中 List 转换 String,String 转换 List,Map 转换 String,Stri...
- Java 中的 String,StringBuilder,StringBuffer 三者的区别
使用JPA存储Map (jpa mappedby)
我想知道是否可以使用批注attributes
使用JPA2 将地图持久化到以下类中
public class Example { long id; // .... Map<String, String> attributes = new HashMap<String, String>(); // ....}
由于我们已经有一个现有的生产数据库,因此理想情况下,值attributes
可以映射到以下现有表:
create table example_attributes { example_id bigint, name varchar(100), value varchar(100));
答案1
小编典典JPA 2.0通过@ElementCollection
注释可以支持原语集合,你可以将其与java.util.Map
集合支持一起使用。这样的事情应该起作用:
@Entitypublic class Example { @Id long id; // .... @ElementCollection @MapKeyColumn(name="name") @Column(name="value") @CollectionTable(name="example_attributes", joinColumns=@JoinColumn(name="example_id")) Map<String, String> attributes = new HashMap<String, String>(); // maps from attribute name to value}
另请参见(在JPA 2.0规范中)
- 2.6 - Collections of Embeddable Classes and Basic Types
- 2.7 Map Collections
- 10.1.11 - ElementCollection Annotation
- 11.1.29 MapKeyColumn Annotation
HashMap 是否应该重构为Enum?
没有“应该”。这取决于您想要的。
- 如果这些值在编译时是已知的,并且不更改,则枚举可能更好。您仍然可以使用地图。
- 如果仅在运行时知道这些值,或者在程序运行时更改它们,请使用Map。
最好只依赖于枚举值,这样您就不必依赖在代码的两个位置维护映射值了-特别重要的是,以后再添加或删除某些值。
此解决方案通过迭代查找组->序列:
public static SequenceName forGroup(String g) {
for (SequenceName value : values()) {
if(value.groupPrefix.equals(g)) { // or equalsIgnoreCase
return value;
}
}
throw new IllegalArgumentException("No sequence with group: "+g);
}
// Call as:
SequenceName.forGroup("GRP-SMM-SRV-").toString()
或者只是根据地图中查找值构建地图:
private static HashMap<String,SequenceName> prefixSequenceNameMap = new HashMap<>();
static {
for (SequenceName value : values()) {
prefixSequenceNameMap.put(value.groupPrefix,value);
}
}
private static HashMap<String,SequenceName> getPrefixSequenceNameMap() {
return prefixSequenceNameMap;
}
// Call as:
SequenceName.getPrefixSequenceNameMap().get("GRP-SMM-SRV-").toString()
Java Core 中的String,StringBuilder,StringBuffer三者的区别
最近在学习Java的时候,遇到了这样一个问题,就是String,StringBuilder以及StringBuffer这三个类之间有什么区别呢,自己从网上搜索了一些资料,有所了解了之后在这里整理一下,便于大家观看,也便于加深自己学习过程中对这些知识点的记忆,如果哪里有误,恳请指正。
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
- 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String最慢的原因:
String为字符串常量,而StringBuilder和StringBuffer均为字符串变量,即String对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:
1 String str="abc"; 2 System.out.println(str); 3 str=str+"de"; 4 System.out.println(str);
如果运行这段代码会发现先输出“abc”,然后又输出“abcde”,好像是str这个对象被更改了,其实,这只是一种假象罢了,JVM对于这几行代码是这样处理的,首先创建一个String对象str,并把“abc”赋值给str,然后在第三行中,其实JVM又创建了一个新的对象也名为str,然后再把原来的str的值和“de”加起来再赋值给新的str,而原来的str就会被JVM的垃圾回收机制(GC)给回收掉了,所以,str实际上并没有被更改,也就是前面说的String对象一旦创建之后就不可更改了。所以,Java中对String对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而StringBuilder和StringBuffer的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比String快很多。
另外,有时候我们会这样对字符串进行赋值
1 String str="abc"+"de"; 2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de"); 3 System.out.println(str); 4 System.out.println(stringBuilder.toString());
这样输出结果也是“abcde”和“abcde”,但是String的速度却比StringBuilder的反应速度要快很多,这是因为第1行中的操作和
String str="abcde";
是完全一样的,所以会很快,而如果写成下面这种形式
1 String str1="abc"; 2 String str2="de"; 3 String str=str1+str2;
那么JVM就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。
2. 再来说线程安全
在线程安全上,StringBuilder是线程不安全的,而StringBuffer是线程安全的
如果一个StringBuffer对象在字符串缓冲区被多个线程使用时,StringBuffer中很多方法可以带有synchronized关键字,所以可以保证线程是安全的,但StringBuilder的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的StringBuilder。
3. 总结一下
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
Java 中 List 转换 String,String 转换 List,Map 转换 String,Stri...
import java.io.IOException;import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Utils {
/**
* 定义分割常量 (# 在集合中的含义是每个元素的分割,| 主要用于 map 类型的集合用于 key 与 value 中的分割)
*/
private static final String SEP1 = "#";
private static final String SEP2 = "|";
/**
* List 转换 String
*
* @param list : 需要转换的 List
* @return String 转换后的字符串
*/
public static String ListToString(List<?> list) {
StringBuffer sb = new StringBuffer();
if (list != null && list.size() > 0) {
for (int i = 0; i < list.size(); i++) {
if (list.get(i) == null || list.get(i) == "") {
continue;
}
// 如果值是 list 类型则调用自己
if (list.get(i) instanceof List) {
sb.append(ListToString((List<?>) list.get(i)));
sb.append(SEP1);
} else if (list.get(i) instanceof Map) {
sb.append(MapToString((Map<?, ?>) list.get(i)));
sb.append(SEP1);
} else {
sb.append(list.get(i));
sb.append(SEP1);
}
}
}
return "L" + encodeBase64(sb.toString());
}
/**
* Map 转换 String
*
* @param map : 需要转换的 Map
* @return String 转换后的字符串
*/
public static String MapToString(Map<?, ?> map) {
StringBuffer sb = new StringBuffer();
// 遍历 map
for (Object obj : map.keySet()) {
if (obj == null) {
continue;
}
Object key = obj;
Object value = map.get(key);
if (value instanceof List<?>) {
sb.append(key.toString() + SEP1 + ListToString((List<?>) value));
sb.append(SEP2);
} else if (value instanceof Map<?, ?>) {
sb.append(key.toString() + SEP1
+ MapToString((Map<?, ?>) value));
sb.append(SEP2);
} else {
sb.append(key.toString() + SEP1 + value.toString());
sb.append(SEP2);
}
}
return "M" + encodeBase64(sb.toString());
}
/**
* String 转换 Map
*
* @param mapText : 需要转换的字符串
* @return Map<?,?>
*/
public static Map<String, Object> StringToMap(String mapText) {
if (mapText == null || mapText.equals("")) {
return null;
}
mapText = mapText.substring(1);
mapText = decodeBase64(mapText);
Map<String, Object> map = new HashMap<String, Object>();
String [] text = mapText.split ("\\" + SEP2); // 转换为数组
for (String str : text) {
String [] keyText = str.split (SEP1); // 转换 key 与 value 的数组
if (keyText.length <= 1) {
continue;
}
String key = keyText[0]; // key
String value = keyText[1]; // value
if (value.charAt(0) == ''M'') {
Map<?, ?> map1 = StringToMap(value);
map.put(key, map1);
} else if (value.charAt(0) == ''L'') {
List<?> list = StringToList(value);
map.put(key, list);
} else {
map.put(key, value);
}
}
return map;
}
/**
* String 转换 List
*
* @param listText : 需要转换的文本
* @return List<?>
*/
public static List<Object> StringToList(String listText) {
if (listText == null || listText.equals("")) {
return null;
}
listText = listText.substring(1);
listText = decodeBase64(listText);
List<Object> list = new ArrayList<Object>();
String[] text = listText.split(SEP1);
for (String str : text) {
if (str.charAt(0) == ''M'') {
Map<?, ?> map = StringToMap(str);
list.add(map);
} else if (str.charAt(0) == ''L'') {
List<?> lists = StringToList(str);
list.add(lists);
} else {
list.add(str);
}
}
return list;
}
/**
* 编码
* @param str
* @return String
*/
public static String encodeBase64(String str){
if (str == null || str.isEmpty()) {
return str;
}
return new sun.misc.BASE64Encoder().encode(str.getBytes());
}
/**
* 解码
* @param str
* @return
*/
public static String decodeBase64(String str) {
byte[] bt = null;
try {
sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
bt = decoder.decodeBuffer( str );
} catch (IOException e) {
e.printStackTrace();
} finally {
if (bt != null) {
return new String(bt);
} else {
return null;
}
}
}
}
Java 中的 String,StringBuilder,StringBuffer 三者的区别
这三个类之间的区别主要是在两个方面,即运行速度和线程安全这两方面。
- 首先说运行速度,或者说是执行速度,在这方面运行速度快慢为:StringBuilder > StringBuffer > String
String 最慢的原因:
String 为字符串常量,而 StringBuilder 和 StringBuffer 均为字符串变量,即 String 对象一旦创建之后该对象是不可更改的,但后两者的对象是变量,是可以更改的。以下面一段代码为例:
1 String str="abc";
2 System.out.println(str);
3 str=str+"de";
4 System.out.println(str);
如果运行这段代码会发现先输出 “abc”,然后又输出 “abcde”,好像是 str 这个对象被更改了,其实,这只是一种假象罢了,JVM 对于这几行代码是这样处理的,首先创建一个 String 对象 str,并把 “abc” 赋值给 str,然后在第三行中,其实 JVM 又创建了一个新的对象也名为 str,然后再把原来的 str 的值和 “de” 加起来再赋值给新的 str,而原来的 str 就会被 JVM 的垃圾回收机制(GC)给回收掉了,所以,str 实际上并没有被更改,也就是前面说的 String 对象一旦创建之后就不可更改了。所以,Java 中对 String 对象进行的操作实际上是一个不断创建新的对象并且将旧的对象回收的一个过程,所以执行速度很慢。
而 StringBuilder 和 StringBuffer 的对象是变量,对变量进行操作就是直接对该对象进行更改,而不进行创建和回收的操作,所以速度要比 String 快很多。
另外,有时候我们会这样对字符串进行赋值
1 String str="abc"+"de";
2 StringBuilder stringBuilder=new StringBuilder().append("abc").append("de");
3 System.out.println(str);
4 System.out.println(stringBuilder.toString());
这样输出结果也是 “abcde” 和 “abcde”,但是 String 的速度却比 StringBuilder 的反应速度要快很多,这是因为第 1 行中的操作和
String str="abcde";
是完全一样的,所以会很快,而如果写成下面这种形式
1 String str1="abc";
2 String str2="de";
3 String str=str1+str2;
那么 JVM 就会像上面说的那样,不断的创建、回收对象来进行这个操作了。速度就会很慢。
2. 再来说线程安全
在线程安全上,StringBuilder 是线程不安全的,而 StringBuffer 是线程安全的
如果一个 StringBuffer 对象在字符串缓冲区被多个线程使用时,StringBuffer 中很多方法可以带有 synchronized 关键字,所以可以保证线程是安全的,但 StringBuilder 的方法则没有该关键字,所以不能保证线程安全,有可能会出现一些错误的操作。所以如果要进行的操作是多线程的,那么就要使用 StringBuffer,但是在单线程的情况下,还是建议使用速度比较快的 StringBuilder。
3. 总结一下
String:适用于少量的字符串操作的情况
StringBuilder:适用于单线程下在字符缓冲区进行大量操作的情况
StringBuffer:适用多线程下在字符缓冲区进行大量操作的情况
关于使用JPA存储Map
本文标签: