我真是受够了没有外键关联的Hibernate多表查询!-- 反射 通过example查询列表

HIbernate 中,没有外键关联,Criteria 不能关联查询!所以就不能findByExample,通过一个条件对象来获取数据。

只能我们自己搞了!

AbstractClass:

    /**
     * 设置查询条件
     * @param t
     * @param whereHQL
     * @return
     */
    protected <T> List<Object> setParams(T t, StringBuilder whereHQL) {
        String aliasDot = getClassAlias(t) + ".";
        List<Object> params = new ArrayList<>();
        Field[] fields = t.getClass().getDeclaredFields();
        try {
            for(Field field : fields) {
                // 这个变量是没有get方法的,如果你有其他的变量也是这样,那需要过滤掉,否则抛异常
               if(field.getName().equals("serialVersionUID")) {
                    continue;
                }
                PropertyDescriptor pd = new PropertyDescriptor(field.getName(), t.getClass());
                Method getMethod = pd.getReadMethod();
                if(isTransient(getMethod)) {
           continue;
         }
               Object o = getMethod.invoke(t);
                if(o != null) {
                    Class<?> returnType =getMethod.getReturnType();
                    if(returnType.getName().equals("java.lang.Number")) {
                        whereHQL.append(" AND " + aliasDot + field.getName() +" LIKE ?");
                        params.add(BigDecimal.valueOf((double)o));
                    } else if(returnType.getName().equals("java.lang.String")) {
                        whereHQL.append(" AND " + aliasDot   + field.getName() +" LIKE ?");
                        params.add("%" + o.toString() + "%");
                    } else if (returnType.getName().equals("java.util.Date")) {
                        whereHQL.append(" AND " + aliasDot + field.getName() +" LIKE ?");
                        params.add("%" + (Date)o + "%");
                    }
                }
            }
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        } catch (IntrospectionException e) {
            e.printStackTrace();
        }
        // 将这个方法定义为抽象方法,让继承这个类的后代进行实现,可以针对每个业务的不同而增加一些自定义条件 ---- 模板模式
        setCustomParams(aliasDot, whereHQL, params);
        return params;
    }

    // 别名怎么约束,按自己的来,我这边是类名大写字母
    protected <T> String getClassAlias(T t) {
        String clazz = t.getClass().getSimpleName();
        StringBuilder alias = new StringBuilder();
        for(int i = 0; i < clazz.length();i++) {
            if(Character.isUpperCase(clazz.charAt(i))) {
                alias.append(Character.toLowerCase(clazz.charAt(i)));
            }
        }
        return alias.toString();
    }
        /**
     * 判断该字段在数据库中是否存在
     * @param getMethod
     * @return
     */
    private boolean isTransient(Method getMethod) {
        Annotation[] annotations = getMethod.getAnnotations();
        for(Annotation annotation : annotations) {
            Class<?>[] interfaces = annotation.getClass().getInterfaces();
            for(Class<?> interfaceTmp : interfaces) {
                if(interfaceTmp.getName().equals("javax.persistence.Transient")){
                    return true;
                }
            }

        }
        return false;
    }


你可能感兴趣的:(java,spring,spring,mvc,Hibernate,对象)