美文网首页技术博客
JPA 复杂查询和MYSQL性能优化

JPA 复杂查询和MYSQL性能优化

作者: Lovealfy | 来源:发表于2020-12-01 14:33 被阅读0次

        实验室大佬选用 SpringData JPA 作为 项目的持久层框架,让对于我一个菜鸡来说苦苦挣扎了许久,踩了N多坑。现在项目基本完成了,终于松了口气,希望不要再出现bug。

    JPA 优点:

        对于单表操作是非常友好的,JPA框架给我们封装好了很多操作数据库的方法,这时候一般都只需要调用这些方法就能完成简单的增删改查操作,不需要自己手写sql,使用起来非常的方便。

     但是对于复杂多表关联查询返回自定义实体类时,返回前端数据时往往是需要多表关联查询组装成一个新的实体类,所以使用起来没有那么友好了。在这里操作往往还要使用JPA的分页插件,集成这些也容易出现bug。下面我在项目中用到多表查询返回自定义实体类的两种方式

    方式一: 自己定义一个实体类用来接受查询到的字段,然后通过new 全限定类名,使用的是hql语句

      方式二: 上面的情况不能满足需求,当数据量很大sql查询太慢,需要自己手写原生sql来优化查询速度,这时候也不能使用jpa中的分页插件,还需要自己手动实现分页。注意,使用原生sql多表查询得到的是object型的数据,需要进行转换

    下面是将object型数组转成所需实体类类型的数组

    package com.grid.monitor.base.utils;

    import org.slf4j.Logger;

    import org.slf4j.LoggerFactory;

    import java.lang.reflect.Constructor;

    import java.lang.reflect.Field;

    import java.lang.reflect.Method;

    import java.util.ArrayList;

    import java.util.HashMap;

    import java.util.List;

    import java.util.Map;

    /**

    * @Author AflyStart

    * @Description:

    * @Date: Created in 15:02 2020/11/30

    */

    public class EntityUtils {

    private static Loggerlogger = LoggerFactory.getLogger(EntityUtils.class);

        /**

        * 将数组数据转换为实体类

        * 此处数组元素的顺序必须与实体类构造函数中的属性顺序一致

        *

        * @param list          数组对象集合

        * @param clazz          实体类

        * @param <T>            实体类

        * @param model          实例化的实体类

        * @return 实体类集合

        */

        public static ListcastEntity(List list, Class clazz, Object model) {

    List returnList =new ArrayList();

            if (list.isEmpty()) {

    return returnList;

            }

    //获取每个数组集合的元素个数

            Object[] co = list.get(0);

            //获取当前实体类的属性名、属性值、属性类别

            List attributeInfoList =getFiledsInfo(model);

            //创建属性类别数组

            Class[] c2 =new Class[attributeInfoList.size()];

            //如果数组集合元素个数与实体类属性个数不一致则发生错误

            if (attributeInfoList.size() != co.length) {

    return returnList;

            }

    //确定构造方法

            for (int i =0; i < attributeInfoList.size(); i++) {

    c2[i] = (Class) attributeInfoList.get(i).get("type");

            }

    try {

    for (Object[] o : list) {

    Constructor constructor = clazz.getConstructor(c2);

                    returnList.add(constructor.newInstance(o));

                }

    }catch (Exception ex) {

    logger.error("实体数据转化为实体类发生异常:异常信息:{}", ex.getMessage());

                return returnList;

            }

    return returnList;

        }

    /**

        * 根据属性名获取属性值

        *

        * @param fieldName 属性名

        * @param modle    实体类

        * @return 属性值

        */

        private static ObjectgetFieldValueByName(String fieldName, Object modle) {

    try {

    String firstLetter = fieldName.substring(0, 1).toUpperCase();

                String getter ="get" + firstLetter + fieldName.substring(1);

                Method method = modle.getClass().getMethod(getter, new Class[]{});

                Object value = method.invoke(modle, new Object[]{});

                return value;

            }catch (Exception e) {

    return null;

            }

    }

    /**

        * 获取属性类型(type),属性名(name),属性值(value)的map组成的list

    *

        * @param model 实体类

        * @return list集合

        */

        private static ListgetFiledsInfo(Object model) {

    Field[] fields = model.getClass().getDeclaredFields();

            List list =new ArrayList(fields.length);

            Map infoMap =null;

            for (int i =0; i < fields.length; i++) {

    infoMap =new HashMap(3);

                infoMap.put("type", fields[i].getType());

                infoMap.put("name", fields[i].getName());

                infoMap.put("value", getFieldValueByName(fields[i].getName(), model));

                list.add(infoMap);

            }

    return list;

        }

    }

    相关文章

      网友评论

        本文标题:JPA 复杂查询和MYSQL性能优化

        本文链接:https://www.haomeiwen.com/subject/wctswktx.html