【java】itoo项目实战之优化后具体代码

在我的前一篇博客中<<itoo项目实战之减少IO读写的导入思路>>,我介绍了如何完成减少IO读写的Excel导入,在这里我就把具体的代码实现分享给大家:

我就按照这张图的顺序给大家分享.

检查Excel 数据是否重复的代码:

<span style="font-family:Times New Roman;font-size:18px;">// 2.从指定列中寻找重复行
				for (int i = 1; i < realRows - 1; i++) {
					int nullCols = 0;
					// 利用set元素的不重复特征来判断是否有重复行
					Set<Integer> sameSet = new HashSet<Integer>();
					for (int j = 0; j < uniqueFields.length; j++) {
						String currentContent = uniqueCells[j][i].getContents();
						Cell sameCell = sheet.findCell(currentContent,
								uniqueCells[j][i].getColumn(),
								uniqueCells[j][i].getRow() + 1,
								uniqueCells[j][i].getColumn(),
								uniqueCells[j][realRows - 1].getRow(), true);
						if (sameCell != null) {
							nullCols++;
							sameSet.add(sameCell.getRow());
						}
					}

					if (nullCols == uniqueFields.length && sameSet.size() == 1) {
						throw new ExcelException("Excel中有重复行,请检查");
					}
				}

			}</span>

检查Excel数据是否在database中是否已存在:

<span style="font-family:Times New Roman;font-size:18px;">for (int i = 1; i < realRows; i++) {
				// 新建要转换的对象
				T entity = entityClass.newInstance();

				// 根据业务主键查询对象
				LinkedHashMap<Object, Object> uniqueMap = new LinkedHashMap<Object, Object>();
				String enValue = "";
				for (int m = 0; m < uniqueFields.length; m++) {

					// 获取英文字段名
					String enName = combineMap.get(uniqueFields[m]);
					// 获取英文字段值
					// 1.获取列号
					int col = colMap.get(uniqueFields[m]);
					// 2.获取内容
					enValue = sheet.getCell(col, i).getContents().toString()
							.trim();
					Field field = null;

					Field[] fields  = entityClass.getDeclaredFields();  //获取子类中所有的属性

						if (Arrays.asList(fields).contains(enName)) {  //判断传进来的属性是否属于该自诶

							field = entityClass.getDeclaredField(enName); // 通过反射,获取类的属性
						}
						else{
							Class<T> firstClass = entityClass;
							firstClass = (Class<T>) firstClass.getSuperclass();
							field = firstClass.getDeclaredField(enName);
						}

					field.setAccessible(true);

					//先通过反射把list对象中的值取出来,然后在进行比较,判断数据库中是否已经存在
					for (int j = 0; j < queryAllList.size(); j++) {

						Object fieldValue = field.get(queryAllList.get(j));

						// 如果对象已存在,在添加到错误列表,并continue
						if (fieldValue.equals(enValue) && fieldValue !=null ) {
							// 将该行添加到错误列表
							errorMap.put(i, "对象已存在");
							continue;
						}
					}
				}
			</span>

处理含有主外键关系的数据:

<span style="font-family:Times New Roman;font-size:18px;">// 用来标记是否有为空的引用对象
				boolean isReferNull = false;

				// 如果有引用字段,则给引用字段赋值
				if (referFieldMap != null && referFieldMap.size() != 0) {
					// 给对象的引用字段赋值
					for (Entry<LinkedHashMap<String, Class<?>>, LinkedHashMap<String, String>> entry : referFieldMap
							.entrySet()) {
						LinkedHashMap<String, Class<?>> keyMap = entry.getKey(); // 获取实体中外键名
						LinkedHashMap<String, String> valueMap = entry // 外键所对应的类
								.getValue();

						// 获取引用字段名和类型
						String referField = "";
						Class<?> type = null; // 定义外键多对一个的类
						for (Entry<String, Class<?>> keyEntry : keyMap
								.entrySet()) {
							referField = keyEntry.getKey(); // 需要导入的对象的外键属性
							type = keyEntry.getValue(); // 外键所对应的类
						}

						String enField = ""; // excel中有外键关系的字段
						String cnField = ""; // excel中类名所对应的数据库字段名
						String content = "";
						for (Entry<String, String> valueEntry : valueMap
								.entrySet()) {
							enField = valueEntry.getValue();
							// excel中有外键关系的字段
							cnField = valueEntry.getKey();
							int col = colMap.get(cnField);
							content = sheet.getCell(col, i).getContents()
									.toString().trim(); // 获取外键所对应的单元格内容
						}

						boolean isObjectBe = false; // 判断业务主键代表的引用对象 是否存在

						// list变成map start
						Object fieldIdValue = "";
						Object fieldNameValue = "";

						// 把list中的值放到map中
						Field fieldId = null;

						Field fieldName = null;
						try {
							fieldName = type.getDeclaredField(enField); // 通过反射,获取类的属性Name
						} catch (NoSuchFieldException e1) {

							e1.printStackTrace();
						} catch (SecurityException e1) {

							e1.printStackTrace();
						}// 属性Name
						fieldName.setAccessible(true); // 设置可以访问私有属性
						for (; type != Object.class; type = type
								.getSuperclass()) {
							try {
								fieldId = type.getDeclaredField("id"); // 通过反射,获取类的属性id
							} catch (Exception e) {
							}
						}
						fieldId.setAccessible(true);
						String linkKey = "";

						for (Entry<String, List> listEntity : listFileMap
								.entrySet()) {
							linkKey = listEntity.getKey();
							List listvalue = listEntity.getValue();
							if (linkKey != "" && linkKey.equals(referField)) { // 判断当前所循环的外键属性与map中的key值是否一致

								Map<Object, Object> fileMap = new HashMap<Object, Object>(); // 放属性值
								for (int k = 0; k < listvalue.size(); k++) {
									try {
										fieldIdValue = fieldId.get(listvalue
												.get(k)); // 获取Id的值
										fieldNameValue = fieldName
												.get(listvalue.get(k)); // 获取name值
									} catch (IllegalArgumentException
											| IllegalAccessException e) {
										e.printStackTrace();
									}

									fileMap.put(fieldIdValue, fieldNameValue);

									if (fieldNameValue != null
											& fieldNameValue.toString().equals(
													content)) { // 判断该单元格中内容在list中是否存在
										// 赋值给entity对象
										setFieldValueByName(referField,
												listvalue.get(k), entity);
										isObjectBe = true;
									}

								}
							}
						}

						// 如果引用对象不为空,则给对象赋值
						if (isObjectBe == false) {
							isReferNull = true;
							errorMap.put(i, "业务主键代表的引用对象不存在");
							break;
						}
					}
				}</span>

以行为单位把数据保存到list中:

<span style="font-family:Times New Roman;font-size:18px;">	/**
	 * @MethodName : setFieldValueByName
	 * @Description : 根据字段名给对象的字段赋值
	 * @param fieldName
	 *            字段名
	 * @param fieldValue
	 *            字段值
	 * @param o
	 *            对象
	 */
	private void setFieldValueByName(String fieldName, Object fieldValue,
			Object o) throws Exception {

		Field field = getFieldByName(fieldName, o.getClass());
		if (field != null) {
			field.setAccessible(true);
			// 获取字段类型
			Class<?> fieldType = field.getType();

			// 根据字段类型给字段赋值
			if (String.class == fieldType) {
				field.set(o, String.valueOf(fieldValue));
			} else if ((Integer.TYPE == fieldType)
					|| (Integer.class == fieldType)) {
				field.set(o, Integer.parseInt(fieldValue.toString()));
			} else if ((Long.TYPE == fieldType) || (Long.class == fieldType)) {
				field.set(o, Long.valueOf(fieldValue.toString()));
			} else if ((Float.TYPE == fieldType) || (Float.class == fieldType)) {
				field.set(o, Float.valueOf(fieldValue.toString()));
			} else if ((Short.TYPE == fieldType) || (Short.class == fieldType)) {
				field.set(o, Short.valueOf(fieldValue.toString()));
			} else if ((Double.TYPE == fieldType)
					|| (Double.class == fieldType)) {
				field.set(o, Double.valueOf(fieldValue.toString()));
			} else if (Character.TYPE == fieldType) {
				if ((fieldValue != null)
						&& (fieldValue.toString().length() > 0)) {
					field.set(o,
							Character.valueOf(fieldValue.toString().charAt(0)));
				}
			} else if (Date.class == fieldType) {
				field.set(o, new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
						.parse(fieldValue.toString()));
			} else {
				field.set(o, fieldValue);
			}
		} else {
			throw new ExcelException(o.getClass().getSimpleName() + "类不存在字段名 "
					+ fieldName);
		}
	}
</span>

代码同时也反映着一个人的思考方式,你想读懂别人的代码,你需要做的是如何让别人先读懂自己代码.最近学会了一个读别人代码的好办法,和大家分享一下,在看别人的代码的时候,先别一头扎进去,然后自己就在里面出不来了.先从宏观上给代码画一张图,然后按照这张图去代码,代码整块整块的读,细节需要的话在研究,这样你就会觉得读别人的代码也是一件轻松的事情.

以上的代码只是部分代码,完整代码可以到这里下载:

ExcelUtil.java

时间: 2024-12-20 06:20:00

【java】itoo项目实战之优化后具体代码的相关文章

【java】itoo项目实战之大数据查询之使用 new map 优化hibernate之级联查询

在我的上一篇博客<[java]itoo项目实战之hibernate 懒加载优化性能>中,我曾提到过学生数据有2万条,查询数据十分的慢,这是让人很受不了的事情,看着页面进度条一直转着圈圈,那种着急的感觉真的没法形容.最开始考虑着使用lazy 来优化,因为前台框架的原因,lazy 优化并没有起到什么左右,后来就想着有select new map 优化.我先来画画关于查询学生的级联树 这个树的意思就是查询学生的时候它的深度是4级. 在没有优化之前,使用的是hibernate的hql 语句:From

Java Drp项目实战——Drp知多少

是什么 Drp是Distribution Resource Planning的缩写,意思是分销资源计划,它是用来管理企业的运行于Internet上的分销网络的系统,是以商业流程优化为基础,它的核心是销售和库存总和控制.这个分销系统或者说是分销体系,它的使用者包括一个大型企业的内部.各个分公司.各级分销商等,它的作用就在于即时的掌握各地的销售信息流.财务资金流.库存信息等一些功能. 产生背景是什么 知道了Drp是什么,我们还需要了解下它的开发背景是什么,为什么要开发这样的一个系统呢. 这个原因还是

JAVA Drp项目实战—— Unable to compile class for JSP 一波三折

交代下背景,电脑系统是64位的,用的是64位的Tomcat,安装是32位的Myeclipse10,java环境也是32位的,Tomcat在开始启动时会报这样一个错误,"Can't load IA 64-bit .dll on a AMD32-bit platform",但是不耽误使用,最近在敲Drp项目中用到了底层接口的几个方法,这个错误导致项目不能正常运行了,所以就将64位的Tomcat换成了与java环境一样的32位的Tomcat,上面的问题就顺利解决了,于是继续自己的开发,但是当

【java】itoo项目实战之常被忽视的性能优化

Itoo V3.0很快就要结束了,功能上基本上开发完成了,但是放到jboss中部署的时候,使用时感觉特别的慢,如果是数据量多的话,就把慢这个词发挥到了极致.这个慢的问题有大部分是因为基础系统中使用了JPA级联导致的,每次查询的时候,只要有关联的表,都会全部查询出来,一下发出一大版的HQL 语句,看着也是挺吓人的.出来优化JPA级联问题,还可以从代码中下手,从以下的几个方面考虑. (1)减少对象生命周期 对象的生命周期有这么一个计算公式:对象生命周期=销毁时间-创建时间 实际上减少对象生命周期有2

【java】itoo项目实战之hibernate 懒加载优化性能

在做itoo 3.0 的时候,考评系统想要上线,就开始导入数据了,只导入学生2万条数据,但是导入的速度特别的慢,这个慢的原因是因为导入的时候进行了过多的IO操作.但是导入成功之后,查询学生的速度更加慢,因为底层用了hibernate的hql语句进行查询的,学习过hibernate的人都知道,如果hibernate不设置懒加载的话,只有是有关联的数据都会一次性全部都查询出来,我试了试,查询2万条数据,最深的级联查询是有5层,然后发出来的语句是460条,时间大概是10s.然后就考虑使用lazy进行优

【java】itoo项目实战之hibernate 懒载入优化性能

在做itoo 3.0 的时候,考评系统想要上线,就開始导入数据了,仅仅导入学生2万条数据,可是导入的速度特别的慢.这个慢的原因是由于导入的时候进行了过多的IO操作.可是导入成功之后,查询学生的速度更加慢.由于底层用了hibernate的hql语句进行查询的,学习过hibernate的人都知道,假设hibernate不设置懒载入的话,仅仅有是有关联的数据都会一次性所有都查询出来,我试了试.查询2万条数据,最深的级联查询是有5层,然后发出来的语句是460条,时间大概是10s.然后就考虑使用lazy进

【java】itoo项目实战之hibernate 批量保存优化

在itoo中.基本上每一个系统都有一个导入功能,大量的数据填写进入excel模板中.然后使用导入功能导入的数据库中,这样能够大大的提高工作效率. 那么导入就涉及到了批量保存数据库的问题了. 那么通常情况下,在一个Session对象的缓存中数量有限的持久化对象,等到Session对象处理事务完成,还要关闭Session对象,从而及时释放session的缓存占用的内存.在批量保存1万条数据,假设一次性把须要保存的1万条数据载入到内存职工,当运行事务提交的时候,就会清理缓存,hibernate运行1万

【java】itoo项目实战之百万数据查询优化收集与实践

1.对查询进行优化,应考虑在where 及 order by 涉及的列上建立索引. 2.应尽量避免在where 子句中对字段进行 null值判断,如:        select id from t wherenum is null 可以在num上设置默认值0,确保表中num列没有null值,然后这样查询: select idfrom t where num=0 3.应尽量避免在where 子句中使用!=或<>操作符. 4.应尽量避免在where 子句中使用 or 来连接条件,如: selec

【java】itoo项目实战之java Web 中web的作用

在ITOO中,每个war包下的web.xml都是一样的.它的结构如下: itoo中含有多个war包,而且每个war包中web.xml都和上图的结构一样,而且配置内容都是一样的. 在Javaweb 应用中可以包含HTML 文档,Servlet,JSP和相关java类等,为了Servlet容器能够顺利地找到javaWeb 应用中的各个组件,Servlet规范规定,javaWeb应用必须采取固定的目录结构,即每种类型的组件在Web应用中都有固定的存放目录.Servlet规范还规定,javaWeb应用的