Hibernate高级映射技术(二)自定义数据类型StringMap(转)

核心提示:上一篇文章介绍了数据库中用;分隔的字段的一种方便的高级映射自定义数据类型StringList。这次是我做的另一种自定义数据类型StringMap。在商品和属性的对应关系中,一个商品对应多个属性,例如一个数码相机型号对应有:像素:1000万,焦距:35-200mm,感光度

上一篇文章介绍了数据库中用;分隔的字段的一种方便的高级映射自定义数据类型StringList。这次是我做的另一种自定义数据类型StringMap。

在商品和属性的对应关系中,一个商品对应多个属性,例如一个数码相机型号对应有:像素:1000万,焦距:35-200mm,感光度:ISO100-1600,非常多而且还需要能适应随时增加新的属性,快速读取显示特别是可以检索。如果设计一个Attribute表(主键attriId,attrKey,attrValue,商品表的外键itemId)的一对多,不仅读取显示很慢,而且难以维护,特别是很难做检索,想搜ISO1600并且焦距200mm的1000万像素的相机,SQL就非常繁琐。所以一般使用将这些属性统一放到商品表的一个specification字段里,结构自已定义,我设置的结构是{key:value};{key:value1,value2}的字符串数组。这样再做刚才的检索时只要在一个表的一个字段里查询,就非常简单了!

幸好Hibernate有自定义数据类型的支持,只要实现UserType或CompositeUserType接口。不过这两个接口的内容比较复杂,有很多方法需要实现,不能偷懒哦:-)

下面是我对于用{key:value};{key:value1,value2}的字符串数组的自定义数据类型的实现。

1.packagecom.willishz.framework.dao.usertype;

2.

3.importjava.io.Serializable;

4.importjava.sql.PreparedStatement;

5.importjava.sql.ResultSet;

6.importjava.sql.SQLException;

7.importjava.sql.Types;

8.importjava.util.ArrayList;

9.importjava.util.Collections;

10.importjava.util.HashMap;

11.importjava.util.Iterator;

12.importjava.util.List;

13.importjava.util.Map;

14.

15.importorg.apache.commons.collections.map.LinkedMap;

16.importorg.hibernate.Hibernate;

17.importorg.hibernate.HibernateException;

18.importorg.hibernate.usertype.UserType;

19.

20./**

21.*格式为{key:value};{key:value1,value2}的字符串数组.

22.*@authorwillishz

23.*/

24.publicclassStringMapimplementsUserType,Serializable{

25.

26.publicStringMap(){

27.super();

28.}

29.

30.publicStringMap(MapattributeMap){

31.super();

32.this.attributeMap=attributeMap;

33.}

34.

35.privateMapattributeMap;

36.

37.publicstaticfinalStringSPLITTER=";";

38.

39.publicstaticfinalStringSEPARATOR=":";

40.

41.publicstaticfinalStringVALUE_BREAK=",";

42.

43.publicstaticfinalcharBRACKET_LEFT='{';

44.

45.publicstaticfinalcharBRACKET_RIGHT='}';

46.

47.publicstaticfinalint[]SQLTYPES=newint[]{Types.VARCHAR};

48.

49.publicbooleanisMutable(){

50.returnfalse;

51.}

52.

53.publicint[]sqlTypes(){

54.returnSQLTYPES;

55.}

56.

57.publicObjectassemble(Serializableid,Objectobj)throwsHibernateException{

58.returnnull;

59.}

60.

61./**

62.*将Map类型的属性拼接成字符串

63.*@paramattributeList

64.*@return

65.*@throwsHibernateException

66.*/

67.publicObjectassemble(MapattributeMap)throwsHibernateException{

68.if(attributeMap==null){

69.returnnull;

70.}

71.StringBufferasbl=newStringBuffer();

72.Iteratoritr=attributeMap.keySet().iterator();

73.String_key=null;

74.while(itr.hasNext()){

75._key=(String)itr.next();

76.asbl.append(SPLITTER).append(BRACKET_LEFT).append(_key).append(SEPARATOR).append(attributeMap.get(_key)).append(BRACKET_RIGHT);

77.}

78.returnasbl.toString().replaceFirst(SPLITTER,"");

79.}

80.

81./**

82.*自定义类型的完全复制方法,返回一个和原自定义数据相同的新对象

83.*

84.*@paramvaluetheobjecttobecloned,whichmaybenull

85.*@returnObjectacopy

86.*@seeorg.hibernate.usertype.UserType#deepCopy(java.lang.Object)

87.*/

88.publicObjectdeepCopy(Objectvalue)throwsHibernateException{

89.if(value==null){

90.returnnull;

91.}

92.MapsourceMap=(Map)value;

93.MaptargetMap=newHashMap();

94.targetMap.putAll(sourceMap);

95.returntargetMap;

96.}

97.

98./**

99.*自定义数据类型的比较方法

100.*

101.*@paramx

102.*@paramy

103.*@returnboolean

104.*@seeorg.hibernate.usertype.UserType#equals(java.lang.Object,java.lang.Object)

105.*/

106.publicbooleanequals(Objectx,Objecty)throwsHibernateException{

107.if(x==y){

108.returntrue;

109.}

110.if(x!=null&&y!=null){

111.MapxMap=(Map)x;

112.MapyMap=(Map)y;

113.if(xMap.size()!=yMap.size()){

114.returnfalse;

115.}

116.List<String>_xList=newArrayList(xMap.keySet());

117.List<String>_yList=newArrayList(xMap.keySet());

118.Collections.sort(_xList);

119.Collections.sort(_yList);

120.for(inti=0;i<xMap.size();i++){

121.if(!_xList.get(i).equals(_yList.get(i))){

122.returnfalse;

123.}

124.if(!xMap.get(_xList.get(i)).equals(yMap.get(_yList.get(i)))){

125.returnfalse;

126.}

127.}

128.returntrue;

129.}

130.returnfalse;

131.}

132.

133.publicinthashCode(Objectarg0)throwsHibernateException{

134.returnattributeMap.hashCode();

135.}

136.

137./**

138.*将以格式为{key:value};{key:value1,value2}的字符串数组解析成一个Map

139.*

140.*@paramvalue

141.*@return

142.*/

143.publicMapparse(Stringvalue){

144.if(value==null){

145.returnnull;

146.}

147.String[]strs=org.apache.commons.lang.StringUtils.split(value.trim(),SPLITTER);

148.MapattributeMap=newLinkedMap();

149.String_temp=null;

150.for(inti=0;i<strs.length;i++){

151._temp=strs[i].substring(1,strs[i].length()-1);

152.attributeMap.put(_temp.split(SEPARATOR,2)[0],_temp.split(SEPARATOR,2)[1]);

153.}

154.returnattributeMap;

155.}

156.

157./**

158.*从JDBC的ResultSet中读取数据,并将其转换为自定义类型后返回。

159.*此方法要求对可能出现null的情况做处理。

160.*names中包含了当前自定义类型的映射字段名称。

161.*

162.*@paramrsaJDBCresultset

163.*@paramnamesthecolumnnames

164.*@paramownerthecontainingentity

165.*@returnObject

166.*@throwsHibernateException

167.*@throwsSQLException

168.*@seeorg.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,java.lang.String[],java.lang.Object)

169.*/

170.publicObjectnullSafeGet(ResultSetrs,String[]names,Objectowner)

171.throwsHibernateException,SQLException{

172.Stringvalue=(String)Hibernate.STRING.nullSafeGet(rs,names[0]);

173.if(value!=null){

174.attributeMap=parse(value);

175.returnattributeMap;

176.}

177.returnnull;

178.}

179.

180./**

181.*在Hibernate进行数据保存时被调用

182.*可以通过PreparedStatement将自定义数据写入对应的数据库字段中

183.*names中包含了当前自定义类型的映射字段名称。

184.*

185.*@paramstaJDBCpreparedstatement

186.*@paramvaluetheobjecttowrite

187.*@paramindexstatementparameterindex

188.*@throwsHibernateException

189.*@throwsSQLException

190.*@seeorg.hibernate.usertype.UserType#nullSafeGet(java.sql.ResultSet,java.lang.String[],java.lang.Object)

191.*/

192.publicvoidnullSafeSet(PreparedStatementpst,Objectvalue,intindex)

193.throwsHibernateException,SQLException{

194.if(value!=null){

195.Hibernate.STRING.nullSafeSet(pst,assemble((Map)value),index);

196.}else{

197.Hibernate.STRING.nullSafeSet(pst,value,index);

198.}

199.}

200.

201.publicClassreturnedClass(){

202.returnStringMap.class;

203.}

204.

205.publicObjectreplace(Objectarg0,Objectarg1,Objectarg2)throwsHibernateException{

206.returnnull;

207.}

208.

209.publicSerializabledisassemble(Objectarg0)throwsHibernateException{

210.returnnull;

211.}

212.

213.publicMapgetAttributeMap(){

214.returnattributeMap;

215.}

216.

217.publicvoidsetAttributeMap(MapattributeMap){

218.this.attributeMap=attributeMap;

219.}

220.}

221.

222.

Hibernate配置文件的相关内容如下:

1.<?xmlversion="1.0"?>

2.<!DOCTYPEhibernate-mappingPUBLIC

3."-//Hibernate/HibernateMappingDTD//EN"

4."http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

5.

6.<hibernate-mappingpackage="com.willishz.apocalypse.ebid.domain">

7.<class

8.name="Merchandise"

9.table="t_merchandise"

10.lazy="false"

11.>

12..................

13.<property

14.name="specification"

15.column="specification"

16.type="com.willishz.framework.dao.usertype.StringMap"

17.not-null="false"

18./>

19..................

20.</class>

21.</hibernate-mapping>

Hibernate映射实体文件的相关内容:

1.packagecom.willishz.apocalypse.ebid.domain.base;

2.

3.importjava.io.Serializable;

4.

5.publicabstractclassUserimplementsSerializable{

6..................

7.

8.privatejava.util.Mapspecification;

9.

10./**

11.*Returnthevalueassociatedwiththecolumn:specification

12.*/

13.publicjava.util.MapgetSpecification(){

14.returnspecification;

15.}

16.

17./**

18.*Setthevaluerelatedtothecolumn:specification

19.*@paramspecificationthespecificationvalue

20.*/

21.publicvoidsetSpecification(java.util.Mapspecification){

22.this.specification=specification;

23.}

24.

25..................

26.}

相关推荐