利用Java实体bean对象批量数据传输处理方案小结

javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set方法JavaBean是一种JAVA语言写成的可重用组件。为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器。

下面通过本文给大家分享利用Java实体bean对象批量数据传输处理的解决方案。

需求

现在有两方数据库表结构相同,一方A、另一个方B,现想从A处查询出多个表的数据,传输到B地保存起来。

解决方案1

最简单粗暴的方法就是,查询出A处相关表的数据封装到实体对象中,之后放到List集合中,再传递给B处,B处再遍历集合,将数据保存到B处。但是此处的问题是想要再添加一个表的数据时,需要改查询的代码还需要改保存的代码,非常麻烦,所以不建议使用。

方案2

新建一个需要准备哪些数据的实体类对象

待查询的猫

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Cat {

    private String id;

    private String food;

    private String weight;

    private String height;

}

待查询的狗

@Data
@AllArgsConstructor
public class Dog {

    private String id;

    private String food;

    private String weight;

    private String height;
}

待查询的猪

@Data
@AllArgsConstructor
public class Pig {

    private String id;

    private String food;

    private String weight;

    private String height;

    private String pid;
}

自定义传输实体对象,这里定义了需要查询那些集合对象

@Data
@AllArgsConstructor
@NoArgsConstructor
public class CustomDataTransferDTO{

    /**
     * ===============================================================
     *                         数据查询结果
     * ===============================================================
     */
    /**
     * 待查询的猫信息
     */
    private List<Cat> catList;

    /**
     * 待查询的狗信息 通过注解来明确关联关系
     */
    @CustomAnnotation.connectTable(tablePath = "com.study.customdatatransfer.Pig")
    private List<Dog> dogList;

    /**
     * 待查询的猪信息
     */
    @Ignore
    private List<Pig> pigList;

2,新建参数关系类

公共参数关系类

/**
 * 这里为共通参数信息设置
 * @author jieya
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class CommonParameterDTO {

    /**
     * ===============================================================
     *                         这里配置所有集合查询的公共查询条件
     * ===============================================================
     */
    /**
     * 主键信息
     */
    public String id;

}

自定义查询参数

/**
 * 自定义查询条件及关联表信息查询实体对象
 * @author Administrator
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TableAndParamsDTO {

    /**
     * 主表名 这里是查询那个实体对象的数据,这里的table值一定要和CustomDataTransferDTO中的List的泛型对上
     */
    @CustomAnnotation.Table
    private String table;
    /**
     * ===============================================================
     *                          自定义参数
     * ===============================================================
     */
    /**
     * 自定义查询参数  search 标记这是一个查询参数
     */
    @CustomAnnotation.search
    private String food;

    /**
     * connectSearchTerm(term = "id")  这个标记为这是连表查询的副表,主表的id等于副表的pid
     */
    @CustomAnnotation.connectSearchTerm(term = "id")
    private String pid;
}

新建自定义处理主方法

/**
 * 自定义数据处理主方法
 *
 * @author Administrator
 */
public class CustomDataMain {

    private static final List<Cat> catList = new ArrayList<>();
    private static final List<Dog> dogList = new ArrayList<>();
    private static final List<Pig> pigList = new ArrayList<>();
    private static List<TableAndParamsDTO> tableAndParamsList = new ArrayList();
    private static CommonParameterDTO commonParameter = new CommonParameterDTO();

    static {
        catList.add(new Cat("1", "面包1", "10", "12"));
        catList.add(new Cat("2", "面包2", "10", "12"));
        catList.add(new Cat("3", "面包3", "10", "12"));
        catList.add(new Cat("4", "面包4", "10", "12"));

        dogList.add(new Dog("1", "米饭1", "10", "12"));
        dogList.add(new Dog("2", "米饭2", "10", "12"));
        dogList.add(new Dog("3", "米饭3", "10", "12"));
        dogList.add(new Dog("4", "米饭4", "10", "12"));

        pigList.add(new Pig("1", "麻辣烫1", "10", "12", "1"));
        pigList.add(new Pig("2", "麻辣烫2", "10", "12", "2"));
        pigList.add(new Pig("3", "麻辣烫3", "10", "12", "3"));
        pigList.add(new Pig("4", "麻辣烫4", "10", "12", "4"));
    }

    public static void main(String[] args) throws Exception {
        // 共通参数
        commonParameter.setId("1");
        //
        TableAndParamsDTO tableAndParamsDTO = new TableAndParamsDTO();
        tableAndParamsDTO.setTable("Pig");
        tableAndParamsDTO.setFood("麻辣烫1");
        tableAndParamsDTO.setPid("id");
        tableAndParamsList.add(tableAndParamsDTO);
        findCustomData(CustomDataTransferDTO.class);
    }

    public static Object findCustomData(Class<?> clazz) throws Exception {

        // 实例化数据传输类
        Object obj = clazz.newInstance();

        // 首先得到pojo所定义的字段
        Field[] fields = clazz.getDeclaredFields();
        for (Field curField : fields) {
            // 设置字段可访问(必须,否则报错)
            curField.setAccessible(true);
            // 如果
            if (!curField.isAnnotationPresent(Ignore.class)) {
                CustomAnnotation.connectTable annotation = curField.getAnnotation(CustomAnnotation.connectTable.class);
                String sideTablePath = null;
                if (annotation != null) {
                    sideTablePath = annotation.tablePath();
                }

                Class<?> curFieldType = curField.getType();
                // 集合List元素
                if (curFieldType.equals(List.class)) {
                    // 当前集合的泛型类型
                    Type genericType = curField.getGenericType();
                    if (null == genericType) {
                        continue;
                    }
                    if (genericType instanceof ParameterizedType) {
                        ParameterizedType pt = (ParameterizedType) genericType;
                        // 得到泛型里的class类型对象
                        Class<?> actualTypeArgument = (Class<?>) pt.getActualTypeArguments()[0];
                        // 获取完整路径信息
                        String tablePath = actualTypeArgument.getName();
                        // 获取实体对象名称
                        String tableName = actualTypeArgument.getSimpleName();
                        // 获取该实体对象设置的自定义信息
                        TableAndParamsDTO tableAndParams = tableAndParamsList.stream().filter(o -> o.getTable().equals(tableName)).findAny().orElse(null);
                        // 拼接hql和执行获取数据
                        obj = connectSqlAndExexute(obj, clazz, tablePath, tableAndParams, sideTablePath);
                    }
                } else {
                    System.out.println(curField.getName() + "--暂不支持的类型--" + curFieldType.getSimpleName());
                }
            } else {
                System.out.println("Ignore----");
            }
        }
        return null;
    }

    /**
     * 连接sql并获取数据
     *
     * @param obj
     * @param clazz
     * @param tablePath
     * @param tableAndParams
     * @param sideTablePath
     * @return
     * @throws Exception
     */
    private static Object connectSqlAndExexute(Object obj, Class<?> clazz, String tablePath,
                                               TableAndParamsDTO tableAndParams, String sideTablePath) throws Exception {
        int lastIndex = tablePath.lastIndexOf(".");
        String tableName = tablePath.substring(lastIndex + 1);
        List<Object> param = new ArrayList<>();
        // 查询语句
        StringBuilder selectBuilder = new StringBuilder(" select * from " + tableName + " where 1=1");
        // 查询条件
        StringBuilder whereBuilder = new StringBuilder();

        // 拼接共通参数
        if (commonParameter != null) {
            // 拼接共通参数
            Field[] fields = commonParameter.getClass().getDeclaredFields();
            for (Field curField : fields) {
                // 设置字段可访问(必须,否则报错)
                curField.setAccessible(true);
                String name = curField.getName();
                whereBuilder.append(" and " + name + "=?");
                Object vlaue = ReflectionUtil.getVlaue(commonParameter, name, "");
                param.add(vlaue);
            }
        }
        // 如果设置了表和特殊参数则按照特殊情况处理,否则使用共通参数拼接条件
        if (tableAndParams != null) {
            //  遍历该实体对象设置的配置信息
            // 获取主表
            String table = tableAndParams.getTable();

            // 拼接自定义经营范围
            Field[] fields = tableAndParams.getClass().getDeclaredFields();
            for (Field field : fields) {
                // 判断是否为查询条件
                if (field.isAnnotationPresent(CustomAnnotation.search.class)) {
                    whereBuilder.append(" and " + field.getName() + "=?");
                    Object vlaue = ReflectionUtil.getVlaue(tableAndParams, field.getName(), "");
                    param.add(vlaue);
                }

                // 关联查询
                if (field.isAnnotationPresent(CustomAnnotation.connectSearchTerm.class)) {
                    String name = field.getName();
                    String values = GsUtils.blankNull(ReflectionUtil.getVlaue(tableAndParams, name, ""));
                    String[] split = values.split(",");
                    String sideWhere = "";
                    for (int i = 0; i < split.length; i++) {

                        sideWhere += " and " + name + " in(";
                        sideWhere += "'" + split[i] + "'" + ",";
                    }
                    ;
                    sideWhere = sideWhere.substring(0, sideWhere.length() - 1);
                    sideWhere += " )";

                    whereBuilder.append(sideWhere);
                }
            }

        }
        // 获取查询对象的class对象
        Class tableClazz = Class.forName(tablePath);
        // hql不为空和hql中不包含and符号时,禁止执行sql,防止全库扫描
        if (StringUtils.isEmpty(whereBuilder.toString())) {
            throw new Exception("hql错误,因不存在and查询条件,会导致全库扫描" + selectBuilder.toString());
        }
        // TODO 执行sql 将查询到数据封装到list<bean>对象中
        // List list = baseDao.findByHql(selectBuilder.toString()+whereBuilder.toString(),tableClazz,param);
        // TODO 这段代码为无用的为获取数据的代码
        List list = findDataInfo(tableName,whereBuilder,param);
        // 将查询到的信息添加到传输文件实体对象中
        if (list != null && list.size() > 0) {
            obj = ReflectionUtil.setValue(obj, clazz, tableName, list);
        }

        // 连表查询
        if (sideTablePath != null) {
            String sideTableName = Class.forName(sideTablePath).getSimpleName();
            // 获取该实体对象设置的自定义信息
            TableAndParamsDTO sideTableAndParams = tableAndParamsList.stream().filter(o -> o.getTable().equals(sideTableName)).findAny().orElse(null);
            // 拼接自定义经营范围
            Field[] sideFields = sideTableAndParams.getClass().getDeclaredFields();
            for (Field field : sideFields) {
                // 关联查询
                if (field.isAnnotationPresent(CustomAnnotation.connectSearchTerm.class)) {
                    String term = field.getAnnotation(CustomAnnotation.connectSearchTerm.class).term();
                    String sideParam = "";
                    for (Object obj1 : list) {
                        Object value = ReflectionUtil.getVlaue(obj1, (String) term, "");
                        if (value != null) {
                            sideParam += value + ",";
                        }
                    }
                    if (StringUtils.isEmpty(sideParam)) {
                        throw new Exception("关联表但为获取到关联条件信息" + selectBuilder.toString());
                    }
                    // 将值设置到对象中
                    field.setAccessible(true);
                    field.set(sideTableAndParams, sideParam);
                }
            }
            // 拼接hql和执行获取数据
            obj = connectSqlAndExexute(obj, clazz, sideTablePath, sideTableAndParams, null);
        }
        System.out.println("tableAndParams:" + tableAndParams + "commonParams:" + commonParameter + "执行sql语句:" + selectBuilder.toString() + whereBuilder.toString() + "查询条件:" + param + "查询结果:" + list);
        return obj;
    }

    private static List findDataInfo(String tableName, StringBuilder whereBuilder, List<Object> param) {
        List<Object> list = new ArrayList<Object>();
        if("Cat".equals(tableName)){
            list.add(catList.get(0));
            return list;
        }
        if("Dog".equals(tableName)){
            list.add(dogList.get(0));
            return list;
        }
        return list;
    }
}

执行完成之后,就可以获取到咱们需要的数据了。

4.获取到数据后,发送给另一端,进行解析保存

/**
     * 保存待处理数据
     *
     * @param obj
     */
    @Override
    public void saveOtherInfo(Object obj) throws Exception {
        // 首先得到pojo所定义的字段
        Field[] fields = obj.getClass().getDeclaredFields();
        for (Field curField : fields) {
            // 设置字段可访问(必须,否则报错)
            curField.setAccessible(true);

            Class<?> curFieldType = curField.getType();
            // 集合List元素
            if (curFieldType.equals(List.class)) {
                // 当前集合的泛型类型
                Type genericType = curField.getGenericType();
                if (null == genericType) {
                    continue;
                }
                if (genericType instanceof ParameterizedType) {
                    Object object = ReflectionUtil.getVlaue(obj,(String) curField.getName(),"");
                    if(object!=null){
                        List list = (List)object;
                        for (int i=0;i<list.size();i++){
                            Object o = list.get(i);
//                            baseDao.saveOrUpdate(o);
                        }
                    }
                }
            }else{
                System.out.println((curField.getName() + "--暂不支持的类型--" + curFieldType.getSimpleName()));
            }
        }
    }

这样两端进行数据传输就完成了,或中间使用消息中间件进行传输也是可以的。

以上就是利用Java实体bean对象批量数据传输处理的详细内容,更多关于java bean对象数据传输的资料请关注我们其它相关文章!

(0)

相关推荐

  • java使用BeanUtils.copyProperties踩坑经历

    1. 原始转换 提起对象转换,每个程序员都不陌生,比如项目中经常涉及到的DO.DTO.VO之间的转换,举个例子,假设现在有个OrderDTO,定义如下所示: public class OrderDTO { private long id; private Long userId; private String orderNo; private Date gmtCreated; // 省略get.set方法 } 有个OrderVO,定义如下所示: public class OrderVO { pr

  • 常用json与javabean互转的方法实现

    JSONObject 与 JSONArray区别 JSONObject: { "area": "武汉", "name": "张三", "age": 25 } JSONArray: [{ "area": "武汉", "name": "张三", "age": 25 }, { "area": &

  • Java 如何使用@Autowired注解自动注入bean

    Java @Autowired注解自动注入bean annotationWire.xml (一定记得配置context:annotation-config/) <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001

  • Java之SSM中bean相关知识汇总案例讲解

    bean 的生命周期 对象创建 实例化Bean对象,默认选择无参构造方法,如果只有一个有参构造那么调用有参构造,如果只有多个有参构造那么报错,除非其中一个有参构造添加了@AutoWired注解: 设置Bean的属性: 依赖注入以及判断是否实现了Aware相关接口(BeanNameAware, BeanFactoryAware, ApplicationContextAware) 如果这个 Bean 关联了 BeanPostProcessor 接口,将会调用BeanPostProcessor.pos

  • IDEA使用GsonFormat完成JSON和JavaBean之间的转换

    最近一直在对接接口,上游返回的都是 JSON 数据,我们需要将这些数据进行保存,我们可以解析成 Map 通过 key 的方式进行获取,然后 set 到实体类对象中,说到这里我开始想吐了,这样就造成了代码过多,没有可读性,如果有100个值,要 get 100次, set 100次吗? 所以最简单的方式是封装成对象,通过对象操作工具进行对象中属性值的映射,但是封装对象过程又繁琐了,属性过多极大的浪费时间,记得初中历史学过的一段话,人和动物最根本的区别就是会不会制造和使用工具,大神和菜鸟之间的差距也莫

  • Java 确保某个Bean类被最后执行的几种实现方式

    一.事出有因 ​ 最近有一个场景,因同一个项目中不同JAR包依赖同一个组件,但依赖组件的版本不同,导致无论使用哪个版本都报错(无法同时兼容两个JAR包中所需的方法调用),经过分析发现差异的部份是在一个BEAN中的方法出入参不同而矣,故考虑通过动态替换掉这个存在兼容性的BEAN,换成我们自己继承自该BEAN类并实现适配兼容方法,从而最终解决组件版本不兼容问题: 二.解决方案困境 但在实现的编码过程中发现,原依赖的那个BEAN并不是普通的通过标注@Compent之类的注解实现的注册的BEAN,而是由

  • Java基础之Bean的创建、定位和使用

    一.前言 Bean是一个由Spring IoC容器实例化.组装和管理的对象.在 Spring 中,类的实例化.依赖的实例化.依赖的传入都交由 Spring Bean 容器控制,而不是用new方式实例化对象.通过非构造函数方法传入依赖等常规方式.这样可以减少垃圾回收对大量实例的回收工作. 在举例中使用到了三个类AAA,BBB和CCC.其中AAA和BBB是平等的两个类,可以相互调用.CCC是以BBB为构造参数的类. 二.自动装配Bean 2.1 注册Bean 为所有想要创建Bean的类添加@Comp

  • 如何动态修改JavaBean中注解的参数值

    我这里有一个需求需要修改Person类中的一个属性上的注解的值进行修改,例如: public class Person { private int age; @ApiParam(access="lala") private String name; //get set 方法忽略 } 将@ApiParam(access="lala") 修改为@ApiParam(access="fafa"),经过分析是可以实现的,需要用到动态代理进行操作. 具体源码

  • 利用Java实体bean对象批量数据传输处理方案小结

    javaBean在MVC设计模型中是model,又称模型层,在一般的程序中,我们称它为数据层,就是用来设置数据的属性和一些行为,然后我会提供获取属性和设置属性的get/set方法JavaBean是一种JAVA语言写成的可重用组件.为写成JavaBean,类必须是具体的和公共的,并且具有无参数的构造器. 下面通过本文给大家分享利用Java实体bean对象批量数据传输处理的解决方案. 需求 现在有两方数据库表结构相同,一方A.另一个方B,现想从A处查询出多个表的数据,传输到B地保存起来. 解决方案1

  • Java 如何从spring容器中获取注入的bean对象

    1.使用场景 控制层调用业务层时,控制层需要拿到业务层在spring容器中注入的对象 2.代码实现 import org.apache.struts2.ServletActionContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.suppo

  • 利用Java反射机制实现对象相同字段的复制操作

    一.如何实现不同类型对象之间的复制问题? 1.为什么会有这个问题? 近来在进行一个项目开发的时候,为了隐藏后端数据库表结构.同时也为了配合给前端一个更友好的API接口文档(swagger API文档),我采用POJO来对应数据表结构,使用VO来给传递前端要展示的数据,同时使用DTO来进行请求参数的封装.以上是一个具体的场景,可以发现这样子一个现象:POJO.VO.DTO对象是同一个数据的不同视图,所以会有很多相同的字段,由于不同的地方使用不同的对象,无可避免的会存在对象之间的值迁移问题,迁移的一

  • 浅谈Java实体对象的三种状态以及转换关系

    最新的Hibernate文档中为Hibernate对象定义了四种状态(原来是三种状态,面试的时候基本上问的也是三种状态),分别是:瞬时态(new, or transient).持久态(managed, or persistent).游状态(detached)和移除态(removed,以前Hibernate文档中定义的三种状态中没有移除态),如下图所示,就以前的Hibernate文档中移除态被视为是瞬时态. 瞬时态:当new一个实体对象后,这个对象处于瞬时态,即这个对象只是一个保存临时数据的内存区

  • java实体对象与Map之间的转换工具类代码实例

    这篇文章主要介绍了java实体对象与Map之间的转换工具类代码实例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 Map接口中键和值一一映射. 可以通过键来获取值. 给定一个键和一个值,你可以将该值存储在一个Map对象. 之后,你可以通过键来访问对应的值. 当访问的值不存在的时候,方法就会抛出一个NoSuchElementException异常. 当对象的类型和Map里元素类型不兼容的时候,就会抛出一个 ClassCastException异常

  • 利用JAVA反射,读取数据库表名,自动生成对应实体类的操作

    本代码是利用java反射,读取数据库表自动根据表名生成实体类,数据库采用老牌SQLSERVER 2000,驱动为JTDS,其他数据库可根据情况自定修改. 代码中包含了大部分数据库类型与JAVA类型的转换,少数未包含进去的会在生成代码时打印出来,方面后期查找修改. import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.io.PrintWriter; import java.sq

  • Java利用反射对list对象做过滤

    目录 1.对象结构 2.根据字段名获取value 3.对list过滤 4.精确匹配 5.模糊匹配 ​反射对效率有影响 慎用!!!​ 1.对象结构 public class BusinessDept { private String year;//年 private String month;//月 private String deptName;//部门名称 private String deptLeader;//部门负责人 private Double jyz; //经营值 private D

  • 关于JAVA中stream流的基础处理(获取对象字段和对象批量处理等)

    目录 Stream流程处理情况 1:按指定字段获取集合对象中的字段: 2:按指定字段对集合对象进行排序: 3: 按指定字段对集合对象去重处理 4: 对集合对象批量处理 5: 将集合对象中指定字段转数组 Stream流程处理情况 1:按指定字段获取集合对象中的字段: List<String> idList = initUserList.stream().map(User::getId).collect(Collectors.toList()); 2:按指定字段对集合对象进行排序: List<

  • Java中JavaBean对象和Map的互相转换方法实例

    目录 1.JavaBean转Map 1.1.简介 1.2.反射知识 1.3.简单转换 1. 4.属性里面套属性转换 1. 5.总结 2.Map转JavaBean对象 2.1.简介 2.2.Introspector介绍 2.3.BeanInfo介绍 2.4用反射实现转换 2.5.利用Introspector(内省)的方式转换 总结 1.JavaBean转Map 1.1.简介 这篇博客是通过反射来进行实现转换的 在学习redis中,发现了一个知识点,就是Java对象转map,视频中的内容是通过hut

  • 解决springmvc关于前台日期作为实体类对象参数类型转换错误的问题

    页面报错: 后台错误: Field error in object 'user' on field 'birthday': rejected value [2013-06-24]; codes [typeMismatch.user.birthday,typeMismatch.birthday,typeMismatch.java.util.Date,typeMismatch]; arguments [org.springframework.context.support.DefaultMessag

随机推荐