`
jsczxy2
  • 浏览: 1277915 次
  • 性别: Icon_minigender_1
  • 来自: 常州
文章分类
社区版块
存档分类
最新评论

利用枚举反射替换hibernate的自定义类型UserType

阅读更多

因为hibernate枚举类型实在配置繁琐,所以直接用枚举换掉,以下是方法:

首先要2个工具类:

 

import java.beans.Introspector;
import java.lang.reflect.Array;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Set;
import java.util.logging.Logger;
import org.apache.commons.lang.ArrayUtils;

/**
 * 
 * 反射的工具类
 * 
 * 
 */
public abstract class ClassUtils {

	private static Logger logger = Logger.getLogger(ClassUtils.class.getName());

	public ClassUtils() {
	}

	/**
	 * 通过类加载机制返回类对象
	 * 
	 * @param name
	 * @param classLoader
	 * @return
	 * @throws ClassNotFoundException
	 */
	@SuppressWarnings("unchecked")
	public static Class forName(String name, ClassLoader classLoader)
			throws ClassNotFoundException {
		Class clazz = resolvePrimitiveClassName(name);
		if (clazz != null)
			return clazz;
		if (name.endsWith("[]")) {
			String elementClassName = name.substring(0, name.length()
					- "[]".length());
			Class elementClass = forName(elementClassName, classLoader);
			return Array.newInstance(elementClass, 0).getClass();
		} else {
			return Class.forName(name, true, classLoader);
		}
	}

	/**
	 * 解析原始数据类型
	 * 
	 * @param name
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class resolvePrimitiveClassName(String name) {
		if (name.length() <= 8) {
			for (int i = 0; i < PRIMITIVE_CLASSES.length; i++) {
				Class clazz = PRIMITIVE_CLASSES[i];
				if (clazz.getName().equals(name))
					return clazz;
			}
		}
		return null;
	}

	/**
	 * 
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String getShortNameAsProperty(Class clazz) {
		return Introspector.decapitalize(getShortName(clazz));
	}

	public static String getShortNameForField(Field field) {
		return Introspector.decapitalize(field.getName());
	}

	/**
	 * 获取方法的名称
	 * 
	 * @param method
	 * @return
	 */
	public static String getShortNameForMethod(Method method) {
		String name = method.getName();
		if (name.startsWith("is"))
			name = name.substring("is".length());
		else if (name.startsWith("get"))
			name = name.substring("get".length());
		else
			throw new IllegalArgumentException((new StringBuilder()).append(
					"Method [").append(method.getName()).append(
					"] is not formed as a JavaBean property").toString());
		return Introspector.decapitalize(name);
	}

	/**
	 * 获取一个类的ShortName 如:com.easyway.A 返回 A
	 * 
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static String getShortName(Class clazz) {
		return getShortName(clazz.getName());
	}

	/**
	 * 判断一个类是否为内部类并获取一个类的ShortName
	 * 
	 * @param className
	 * @return
	 */
	public static String getShortName(String className) {
		int lastDotIndex = className.lastIndexOf('.');
		int nameEndIndex = className.indexOf("$$");
		if (nameEndIndex == -1)
			nameEndIndex = className.length();
		String shortName = className.substring(lastDotIndex + 1, nameEndIndex);
		shortName = shortName.replace('$', '.');
		return shortName;
	}

	/**
	 * 获取一个方法所在类的全名
	 * 
	 * @param method
	 *            方法名称
	 * @return
	 */
	public static String getQualifiedMethodName(Method method) {
		return (new StringBuilder()).append(
				method.getDeclaringClass().getName()).append(".").append(
				method.getName()).toString();
	}

	/**
	 * 根据类,方法名称和参数查找方法
	 * 
	 * @param clazz
	 *            类名
	 * @param methodName
	 *            方法名称
	 * @param paramTypes
	 *            参数类型
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean hasMethod(Class clazz, String methodName,
			Class paramTypes[]) {
		try {
			clazz.getMethod(methodName, paramTypes);
			return true;
		} catch (NoSuchMethodException ex) {
			return false;
		}
	}

	/**
	 * 根据类和方法名返回方法的个数
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static int getMethodCountForName(Class clazz, String methodName) {
		int count = 0;
		do {
			for (int i = 0; i < clazz.getDeclaredMethods().length; i++) {
				Method method = clazz.getDeclaredMethods()[i];
				if (methodName.equals(method.getName()))
					count++;
			}
			clazz = clazz.getSuperclass();
		} while (clazz != null);
		return count;
	}

	/**
	 * 
	 * @param clazz
	 * @param methodName
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean hasAtLeastOneMethodWithName(Class clazz,
			String methodName) {
		do {
			for (int i = 0; i < clazz.getDeclaredMethods().length; i++) {
				Method method = clazz.getDeclaredMethods()[i];
				if (methodName.equals(method.getName()))
					return true;
			}
			clazz = clazz.getSuperclass();
		} while (clazz != null);
		return false;
	}

	/**
	 * 获取静态的方法的
	 * 
	 * @param clazz
	 * @param methodName
	 * @param args
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Method getStaticMethod(Class clazz, String methodName,
			Class args[]) {
		try {
			Method method = clazz.getDeclaredMethod(methodName, args);
			if ((method.getModifiers() & Modifier.STATIC) != 0)
				return method;
		} catch (NoSuchMethodException ex) {
		}
		return null;
	}

	@SuppressWarnings("unchecked")
	public static String addResourcePathToPackagePath(Class clazz,
			String resourceName) {
		if (!resourceName.startsWith("/"))
			return (new StringBuilder()).append(
					classPackageAsResourcePath(clazz)).append("/").append(
					resourceName).toString();
		else
			return (new StringBuilder()).append(
					classPackageAsResourcePath(clazz)).append(resourceName)
					.toString();
	}

	@SuppressWarnings("unchecked")
	public static String classPackageAsResourcePath(Class clazz) {
		if (clazz == null || clazz.getPackage() == null)
			return "";
		else
			return clazz.getPackage().getName().replace('.', '/');
	}

	/**
	 * 根据对象获取所有的接口
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class[] getAllInterfaces(Object object) {
		Set interfaces = getAllInterfacesAsSet(object);
		return (Class[]) (Class[]) interfaces.toArray(new Class[interfaces
				.size()]);
	}

	/**
	 * 根据类获取所有的接口
	 * 
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Class[] getAllInterfacesForClass(Class clazz) {
		Set interfaces = getAllInterfacesForClassAsSet(clazz);
		return (Class[]) (Class[]) interfaces.toArray(new Class[interfaces
				.size()]);
	}

	/**
	 * 根据对象获取所有的接口
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Set getAllInterfacesAsSet(Object object) {
		return getAllInterfacesForClassAsSet(object.getClass());
	}

	/**
	 * 根据类获取所有的接口
	 * 
	 * @param clazz
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Set getAllInterfacesForClassAsSet(Class clazz) {
		Set interfaces = new HashSet();
		for (; clazz != null; clazz = clazz.getSuperclass()) {
			for (int i = 0; i < clazz.getInterfaces().length; i++) {
				Class ifc = clazz.getInterfaces()[i];
				interfaces.add(ifc);
			}
		}
		return interfaces;
	}

	/**
	 * 检测一个方法或者一个属性是否为Public 修饰
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean isPublic(Class clazz, Member member) {
		return Modifier.isPublic(member.getModifiers())
				&& Modifier.isPublic(clazz.getModifiers());
	}

	/**
	 * 检测一个Class是否为Abstract 修饰
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static boolean isAbstractClass(Class clazz) {
		int modifier = clazz.getModifiers();
		return Modifier.isAbstract(modifier) || Modifier.isInterface(modifier);
	}

	/**
	 * 根据一个类获取一个默认的无参数的构造函数
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Constructor getDefaultConstructor(Class clazz) {
		if (isAbstractClass(clazz))
			return null;
		try {
			Constructor constructor = clazz
					.getDeclaredConstructor(EMPTY_CLASS_ARRAY);
			if (!isPublic(clazz, constructor))
				constructor.setAccessible(true);
			return constructor;
		} catch (NoSuchMethodException nme) {
			return null;
		}
	}

	/**
	 * 根据一个类和对应输入参数,获取一个对应参数的构造函数
	 * 
	 * @param object
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public static Constructor getConstructor(Class clazz,
			Class parameterTypes[]) {
		if (isAbstractClass(clazz))
			return null;
		try {
			Constructor constructor = clazz.getConstructor(parameterTypes);
			if (!isPublic(clazz, constructor))
				constructor.setAccessible(true);
			return constructor;
		} catch (NoSuchMethodException nme) {
			return null;
		}
	}

	/**
	 * 将一个完整的类名装换为资源名称路径
	 * 
	 * @param resourcePath
	 * @return
	 */
	public static String convertResourcePathToClassName(String resourcePath) {
		return resourcePath.replace('/', '.');
	}

	public static String convertClassNameToResourcePath(String className) {
		return className.replace('.', '/');
	}

	/**
	 * 获取一个对象的属性
	 * 
	 * @param <T>
	 * @param object
	 * @param propertyName
	 * @return
	 * @throws NoSuchFieldException
	 */
	@SuppressWarnings("unchecked")
	public static <T> T getDeclaredFieldValue(Object object, String propertyName)
			throws NoSuchFieldException {
		Field field = getDeclaredField(object.getClass(), propertyName);
		boolean accessible = field.isAccessible();
		Object result = null;
		synchronized (field) {
			field.setAccessible(true);
			try {
				result = field.get(object);
			} catch (IllegalAccessException e) {
				throw new NoSuchFieldException("No such field: "
						+ object.getClass() + '.' + propertyName);
			} finally {
				field.setAccessible(accessible);
			}
		}
		return (T) result;
	}

	/**
	 * 查找对应类的属性字段
	 * 
	 * @param clazz
	 * @param propertyName
	 * @return
	 * @throws NoSuchFieldException
	 */
	public static Field getDeclaredField(Class<?> clazz, String propertyName)
			throws NoSuchFieldException {
		for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass
				.getSuperclass()) {

			try {
				return superClass.getDeclaredField(propertyName);
			} catch (NoSuchFieldException e) {
				// Field不在当前类定义,继续向上转型
				e.printStackTrace();
			}
		}
		throw new NoSuchFieldException("No such field: " + clazz.getName()
				+ '.' + propertyName);
	}

	/**
	 * 获取一个类的所有的属性
	 * 
	 * @param clazz
	 * @return
	 */
	public static Field[] getDeclaredFields(Class<?> clazz) {
		Field[] fields = clazz.getDeclaredFields();
		for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass
				.getSuperclass()) {
			fields = (Field[]) ArrayUtils.addAll(fields, superClass
					.getDeclaredFields());
		}
		return fields;
	}

	public static final String ARRAY_SUFFIX = "[]";
	private static Class PRIMITIVE_CLASSES[];
	private static final Class EMPTY_CLASS_ARRAY[] = new Class[0];
	static {
		PRIMITIVE_CLASSES = (new Class[] { Boolean.TYPE, Byte.TYPE,
				Character.TYPE, Short.TYPE, Integer.TYPE, Long.TYPE,
				Float.TYPE, Double.TYPE });
	}
}

 

 

 

 

 

 

import org.apache.commons.lang.ObjectUtils;

/**
 * 
 * 枚举工具类
 */
public abstract class EnumUtils {
	
	public synchronized static <T extends Enum<T>> T getEnumFromValue(Class<T> enumClass,Object value){
		return fromEnumProperty(enumClass, "value", value);
	}
	
	
	/**
	 * 从指定的枚举类中根据property搜寻匹配指定值的枚举实例
	 * 
	 * @param <T>
	 * @param enumClass
	 * @param property
	 * @param propValue
	 * @return
	 */
	private static <T extends Enum<T>> T fromEnumProperty(Class<T> enumClass,
			String property, Object propValue) {

		T[] enumConstants = enumClass.getEnumConstants();

		for (T t : enumConstants) {
			Object constantPropValue;
			try {
				constantPropValue = ClassUtils.getDeclaredFieldValue(t,
						property);

				if (ObjectUtils.equals(constantPropValue, propValue)) {
					return t;
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
		return null;
	}

	/**
	 * 从指定的枚举类中根据名称匹配指定值
	 * 
	 * @param <T>
	 * @param enumClass
	 * @param constantName
	 * @return
	 */
	private static <T extends Enum<T>> T fromEnumConstantName(
			Class<T> enumClass, String constantName) {
		T[] enumConstants = enumClass.getEnumConstants();
		for (T t : enumConstants) {
			if (((Enum<?>) t).name().equals(constantName)) {
				return t;
			}
		}
		return null;
	}

}

 

 然后一个测试枚举:

 

 

public enum SexEnum {
	
	外星人(0) , 男(1) , 女(2);
	
	private int value;
	
	SexEnum(final int value){
		this.value = value;
	}

	public int getValue() {
		return value;
	}
	
	public String getName(){
		return this.name();
	}
}

 

 测试类:

 

import junit.framework.TestCase;

import com.myweb.util.EnumUtils;
public class MainTest extends TestCase{
	
	public void testEnum() throws Exception{
		SexEnum sexEnum = EnumUtils.getEnumFromValue(SexEnum.class,1);
		System.out.println(sexEnum.name());
		System.out.println(sexEnum.getName());
		System.out.println(SexEnum.男.getValue());
		System.out.println(SexEnum.valueOf("男").getValue());
	}
}

 

 最后如何运用到hibernate呢?只需要如下改动hibernate即可:

 

 

改动方式以前的POJO中sex的get方法:
public int getSex(
   return this.sex;
)

现在改为:
public SexEnum getSex(){
  return  EnumUtils.getEnumFromValue(SexEnum.class,this.sex);
}

页面获取为:
${sex.name}和${sex.value}
分享到:
评论

相关推荐

    简要分析Java的Hibernate框架中的自定义类型

    了解并掌握自定义类型,不仅可以帮助我们在实际开发中更好地利用Hibernate,还能提升我们对ORM框架的理解,以及如何设计可扩展和灵活的数据模型。同时,这也是对软件工程中“开闭原则”的实践,即对扩展开放,对修改...

    用Hibernate实现领域对象的自定义字段

    2. **实现Hibernate用户类型接口**:自定义类型需要实现`org.hibernate.usertype.UserType`接口。这个接口要求我们重写一些关键方法,如`nullSafeGet()`、`nullSafeSet()`、`equals()`、`hashCode()`等,以便...

    hibernate映射Oracle中LONG类型

    使用自定义类型映射 Oracle 中的 LONG 类型字段是解决 Hibernate 框架中 LONG 类型字段读写问题的一种有效方法。通过实现 UserType 接口,我们可以定制 LONG 类型字段的读写操作,并提高 Hibernate 框架的灵活性和可...

    JSP 中Hibernate实现映射枚举类型

    本文将详细介绍如何在Hibernate中实现枚举类型到数据库的映射,包括对应的枚举类的定义、自定义UserType以及在映射文件hbm.xml中的配置。 首先,定义一个枚举类型Gender,它包含了性别相关的几个枚举值,分别是...

    Hibernate3.2EnumTypeMapping-demo.zip

    在Java开发中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作与业务逻辑层解耦,提高代码的可...这将帮助你更好地利用Hibernate处理枚举类型,提高代码质量,减少潜在的运行时错误。

    枚举类型在switch语句中的用法

    例如,在提供的代码示例中,定义了一个名为`UserType`的枚举类型,该枚举包含了五个不同的用户类型:学生(`STUDENT`)、教师(`TEACHER`)、家长(`PARENT`)、学校管理员(`SCHOOL_ADMIN`)和未知类型(`UNKNOWN`...

    hibernate 杂谈

    一个更简洁的解决方案是将这些数据存储为JSON格式,并利用自定义的Hibernate类型进行转换。例如,在OrderModel类中,可以定义一个字段`favorableDescList`,使用`@Type(type = ...

    mysql 让hibernate支持text字段的方言

    例如,可以创建一个自定义的`UserType`实现,覆盖`sqlTypes()`方法,返回`TEXT`字段对应的SQL类型代码(如` Types.LONGVARCHAR`),并在`returnedClass()`方法中指定返回的Java类型(如`String`)。 3. **配置...

    qt自定义类型 Q_DECLARE_METATYPE与qRegisterMetaType

    如果要使自定义类型或其他非QMetaType内置类型在QVaiant中使用,必须使用该宏Q_DECLARE_METATYPE。 该类型必须有公有的 构造、析构、复制构造 函数 qRegisterMetaType 必须使用该函数的两种情况:1、如果非QMetaType...

    spring aop+自定义注解+反射实现统一校验脚手架

    工程介绍:SpringBoot项目脚手架,利用spring aop+java反射实现自定义注解校验参数 源码里有使用都例子在DemoContorller example1:校验userName参数必填 @CheckParams(notNull = true) private String userName;...

    Hibernate 配置跟数据库字段的对应关系

    最后,要注意的是,Hibernate还支持自定义类型映射,通过实现`org.hibernate.usertype.UserType`接口,可以自定义任何复杂的数据类型转换。 总结来说,配置Hibernate与数据库字段的对应关系主要包括以下几个步骤: ...

    hibernate-json:Json 用户类型Hibernate

    除了自定义用户类型,还可以利用Hibernate的`@GenericGenerator`和`@GeneratedValue`注解配合`Hibernate.generateValue`方法,生成JSON字段的值。此外,你还可以通过自定义函数或存储过程来处理更复杂的JSON操作。 ...

    05_JPA详解_日期_枚举等字段类型的JPA映射.zip

    Java中的枚举类型可以方便地与数据库中的字符串或整型字段进行映射。JPA提供了`@Enumerated`注解来处理枚举字段: - `@Enumerated(EnumType.STRING)`:将枚举值转换为字符串存储。 - `@Enumerated(EnumType.ORDINAL...

    hibernate4.1中文api

    - **使用org.hibernate.usertype.UserType**: 实现自定义用户类型。 - **使用org.hibernate.usertype.CompositeUserType**: 映射复合类型。 - **类型注册**: 注册自定义类型。 #### 7. 集合映射 - **持久化集合*...

    hibernate(api_介绍)

    此外,还可以通过实现UserType和CompositeUserType接口自定义数据映射。 5. **可扩展接口** - **Dialect**:这是Hibernate的方言抽象类,为不同的数据库系统(如Oracle、MSSQL、Sybase)提供了特定的方言实现,以...

    Hibernate的char问题.txt

    为了更精确地控制 `char` 类型的处理方式,可以考虑使用 Hibernate 提供的自定义类型,比如 `CharacterType` 或者自定义实现 `org.hibernate.usertype.UserType` 接口来创建自定义的类型转换器。 ##### 3. 参数绑定...

    hibernate(api 介绍).docx

    1. org.hibernate.usertype.UserType:可以自定义数据映射类型。 2. org.hibernate.dialect.Dialect abstract_class:Hibernate 对于每种数据库都定义了独有的方言,比如 Oracle、MSSQL、Sybase 等数据库系统都有...

    精通 Hibernate:Java 对象持久化技术详解(第2版).part2

     11.2.2 用UserType映射枚举类型  11.2.3 实现CompositeUserType接口  11.2.4 运行本节范例程序  11.3 操纵Blob和Clob类型数据  11.4 小结  11.5 思考题 第12章 映射继承关系  12.1 继承关系树的每个具体类...

    Hibernate实战(第2版 中文高清版)

     5.2 Hibernate类型系统   5.2.1 概述实体和值类型   5.2.2 内建的映射类型   5.2.3 使用映射类型   5.3 创建定制的映射类型   5.3.1 考虑定制的映射类型   5.3.2 扩展点   5.3.3 定制映射类型的案例...

Global site tag (gtag.js) - Google Analytics