编程开发 > JSP > 文章内容

JSP中Hibernate实现映射枚举类型

2017-4-30编辑:ljnbset

JSP 中Hibernate实现映射枚举类型

问题:

Java BO类Gender是枚举类型,想在数据库中存成字符串格式,如何编写hbm.xml?

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

public enum Gender{ 

 UNKNOWN("Unknown"), 

 MALE("Male"), 

 FEMALE("Female");

    

 private String key;

 private Gender(final String key) {

  this.key = key;

 }

 public getGender(String key) {

  for (Gender gender : Gender.values()) {

   if (key.euqals(gender.getKey()))

    return gender;      

  }

  throw new NoSuchElementException(key);

 }

}

使用UserType:

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

83

84

85

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

public class GenderUserType implements UserType { 

  

  private static int[] typeList = { Types.VARCHAR}; 

  

 /*

  * Return the SQL type codes for the columns mapped by this type.

  * The codes are defined on java.sql.Types. */

 /**设置和Gender类的sex属性对应的字段的SQL类型 */ 

 public int[] sqlTypes() {

   return typeList;

 }

  

 /*The class returned by nullSafeGet().*/

 /** 设置GenderUserType所映射的Java类:Gender类 */

 public Class returnedClass() {

   return Gender.class; 

 

  

 /** 指明Gender类是不可变类 */ 

 public boolean isMutable() {

   return false;

 }

  

 /*

 * Return a deep copy of the persistent state, stopping at entities and at

 * collections. It is not necessary to copy immutable objects, or null

 * values, in which case it is safe to simply return the argument.

 */

 /** 返回Gender对象的快照,由于Gender类是不可变类, 因此直接将参数代表的Gender对象返回 */ 

 public Object deepCopy(Object value) { 

  return (Gender)value; 

 

  

 /** 比较一个Gender对象是否和它的快照相同 */

 public boolean equals(Object x, Object y) {

  //由于内存中只可能有两个静态常量Gender实例, 

  //因此可以直接按内存地址比较 

  return (x == y); 

 

 public int hashCode(Object x){ 

   return x.hashCode(); 

 

  

 /*

 * Retrieve an instance of the mapped class from a JDBC resultset. Implementors

 * should handle possibility of null values.

 */

 /** 从JDBC ResultSet中读取key,然后返回相应的Gender实例 */

 public Object nullSafeGet(ResultSet rs, String[] names, Object owner)

               throws HibernateException, SQLException{ 

   //从ResultSet中读取key

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

   if (sex == null) { return null; } 

   //按照性别查找匹配的Gender实例 

   try { 

    return Gender.getGender(sex); 

   }catch (java.util.NoSuchElementException e) { 

    throw new HibernateException("Bad Gender value: " + sex, e); 

   

 }

  

 /*

 * Write an instance of the mapped class to a prepared statement. Implementors

 * should handle possibility of null values.

 * A multi-column type should be written to parameters starting from index.

 */

 /** 把Gender对象的key属性添加到JDBC PreparedStatement中 */

 public void nullSafeSet(PreparedStatement st, Object value, int index) 

                throws HibernateException, SQLException{ 

  String sex = null; 

  if (value != null) 

    sex = ((Gender)value).getKey(); 

  Hibernate.String.nullSafeSet(st, sex, index); 

 

  

 /*

 * Reconstruct an object from the cacheable representation. At the very least this

 * method should perform a deep copy if the type is mutable. (optional operation)

 */

 public Object assemble(Serializable cached, Object owner){

   return cached;

 

   

 /*

   * Transform the object into its cacheable representation. At the very least this

   * method should perform a deep copy if the type is mutable. That may not be enough

   * for some implementations, however; for example, associations must be cached as

   * identifier values. (optional operation)

  */

  public Serializable disassemble(Object value) {

     return (Serializable)value; 

  

  

 /*

 * During merge, replace the existing (target) value in the entity we are merging to

 * with a new (original) value from the detached entity we are merging. For immutable

 * objects, or null values, it is safe to simply return the first parameter. For

 * mutable objects, it is safe to return a copy of the first parameter. For objects

 * with component values, it might make sense to recursively replace component values.

 */

 public Object replace(Object original, Object target, Object owner){

    return original; 

 

}

然后再hbm.xml中定义映射关系:

?

1

2

3

4

5

6

<hibernate-mapping package="" default-lazy="true" default-cascade="save-update,merge,persist">

  <typedef name="Gender" class="com.alpha.hibernate.GenderUserType">

    <property name="gender" type="Gender">

        <column name="GENDER" not-null="true">

        column>

    property>

延伸:

为每个枚举类型定义一个UserType是比较麻烦的,可以定义一个抽象类。

例如扩展下例即可适用于所有保存为index的枚举类型

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

public abstract class OrdinalEnumUserTypeextends Enum> implements UserType { 

  

  protected Class clazz;

    

  protected OrdinalEnumUserType(Class clazz) {

    this.clazz = clazz;

  

   

  private static final int[] SQL_TYPES = {Types.NUMERIC}; 

  public int[] sqlTypes() { 

    return SQL_TYPES; 

  

   

  public Class returnedClass() { 

    return clazz; 

  

   

  public E nullSafeGet(ResultSet resultSet, String[] names, Object owner) 

               throws HibernateException, SQLException {    

  

    //Hibernate.STRING.nullSafeGet(rs, names[0])

    int index = resultSet.getInt(names[0]);

    E result = null

    if (!resultSet.wasNull()) { 

      result = clazz.getEnumConstants()[index]; 

    

    return result; 

  

   

  public void nullSafeSet(PreparedStatement preparedStatement,

     Object value,int index) throws HibernateException, SQLException { 

    if (null == value) { 

      preparedStatement.setNull(index, Types.NUMERIC); 

    } else

      //Hibernate.String.nullSafeSet(st, sex, index);

      preparedStatement.setInt(index, ((E)value).ordinal()); 

    

  

   

  public Object deepCopy(Object value) throws HibernateException{ 

    return value; 

  

   

  public boolean isMutable() { 

    return false

  

   

  public Object assemble(Serializable cached, Object owner) 

throws HibernateException {

     return cached;

  

  

  public Serializable disassemble(Object value) throws HibernateException { 

    return (Serializable)value; 

  

   

  public Object replace(Object original, Object target, Object owner)

throws HibernateException { 

    return original; 

  

  public int hashCode(Object x) throws HibernateException { 

    return x.hashCode(); 

  

  public boolean equals(Object x, Object y) throws HibernateException { 

    if (x == y) 

      return true

    if (null == x || null == y) 

      return false

    return x.equals(y); 

  

Hibernate使用中防止SQL注入的几种方案

热点推荐

登录注册
触屏版电脑版网站地图