利用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)