刚刚接触到Hibernate,有个使用它的机会便心痒痒的使用了一下。才明白“纸上得来终觉浅,绝知此事要躬行”的道理。
简单了解了下用poi解析excel的原理,将excel最后转换成了二维数组。这中间遇到了些小麻烦,至今没有能很好的解决,比如:明明5列600行的表格,解析出来就是7列630行之类,读错的没有内容,由于poi不是今天说的重点,我就先把那些读错的单元格直接没有写到二维数组中。虽然这个处理方法不是很严密,但是在整个工程的运行中,二维数组中正确的包含了excel的所有内容。
再说工程中遇到的另外一个问题:
数据库是前人建好的,我就很天真的用hibernate映射好数据库中我需要的表,将二维数组用HQL语句update,需要的时候就将对象持久化添加,其中有个表就是死活添加不进去,各种反思自己的程序,无数次添加后我甚至发现在程序运行刚结束时数据是有的,一分钟后就神奇的没有了啊!
原来问题就出现在这个神奇的数据库中。数据库是定时和另外一个校园卡中心的数据库同步的,一小时同步一次,所以我导入的某些数据一小时就会被同步掉。但是这也不能出现上述现象啊。又想到这是不是脏读,幻读,不可重复读之类的情况,跟这个原理类似,原因竟然是数据库中原来设定好的触发器将我该的数据清除了,禁用触发器后就好了。
再说心得吧:最后数据终于成功导入了,很兴奋的运行程序,看结果,同时更改了某个校区的11栋宿舍楼的数据,竟然某个表的数据再应用程序上不显示!原来是由于先验知识不足,弄错了一列宿舍号。就在寻找这个问题的几天里,那么多通道机就那么半残废的运行着,电话一个个的来,实在是吃不消!事罢回想这件事,感觉自己犯了两个低级错误:第一:事先没有很系统的了解这个任务,出现问题只在自己这快找二没有系统的联想一下,才让触发器拌了脚,浪费了不少时间。第二:应该提前将程序完全验证到位再发布到整个校区(总数据库),最起码应该在某个宿舍楼上验证完全成功,否则发布后出现错误的压力真的很大。当然这都是常识,还是那句话“事不躬亲不知难”,这不是件难事,但是第一次就能把它做完美并不容易。
最后的最后回去看自己的程序,完全没用到hibernate面向对象,以及二级缓存的优势,还需要继续深入。
啰嗦这么多上代码:
这是导入一个表的代码,往下有解析excel的类,往上有将整个文件夹中所有表格同样操作的类。
package Manager;
import java.io.File;
import java.util.Date;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
import Utils.CommonFunctions;
import Utils.ExcelOperator;
import Bean.AlleyUser;
import Bean.AuthorityManage;
import Bean.UserInfo;
public class Excel2DB {
//用来将exel表格的内容转移到数据库中
//该方法以AuthorityManage为例
public String[][] eContent;
public void excel2String(String fileName){
//将电子表格转换为二维数组
ExcelOperator eo=new ExcelOperator();
File inFile = new File(fileName);
boolean setFile = eo.setFile(inFile);
System.out.println("setFile"+setFile);
eContent = eo.getExcelContent(6);
}
public void excel2DBProcessing(){
Configuration conf = new Configuration().configure();
SessionFactory sf = conf.buildSessionFactory();
Session sess = sf.openSession();
int queryRslt = 0;//条记录插入所影响的行数
int ui_success_count = 0;//成功插入userinfo总条数
int au_success_count = 0;//成功插入alleyuser总条数
int flushCount=0;
List updateFailureUI = null;//在userinfo中更新失败的卡号集合
List updateFailureAU = null;//在alleyuser中更新失败的卡号集合
List uid;//从数据表中查找的userinfo的id
List aid=null;//从数据表中查找的alleyuser的id
List ucardno;
List roomid;
//查找宿舍楼对应的id
List campusId = sess.createQuery("select c.id from CampusInfo c where Name=:CName")
.setString("CName", eContent[0][4])
.list();//从campusinfo中选出校区号
List buildingId = sess.createQuery("select b.id from BuildingInfo b where Name=:BName and CampusId=:CId")
.setString("BName", eContent[0][2])
.setString("CId", String.valueOf(campusId.get(0)))
.list();//从buildinginfo中选出某校区楼号对应的楼id
System.out.println("要插入的宿舍楼id为:"+String.valueOf(buildingId.get(0)));
Date beginTime = new Date();
Date endTime = new Date(2015-1900,7-1, 1, 0, 0, 0);
System.out.println("本表格共有"+eContent.length+"条记录");
org.hibernate.Transaction tx = sess.beginTransaction();
for(String[] srow:eContent){
//语句中的属性大小写是根据配置文件中属性决定的。
uid = sess.createQuery("select u.id from UserInfo u where StudentNo=:StudentNo")
.setString("StudentNo", srow[0])
.list();
//找出房间ID
roomid = sess.createQuery("select r.id from RoomInfo r where Name=:Name and BuildingId=:BuildingId")
.setString("Name", srow[3])
.setString("BuildingId", String.valueOf(buildingId.get(0)))
.list();
if(uid.size()==0){
//userinfo中没有此学号
System.out.println("没有该userinfo的记录");
continue;
}
try{
Query query1 = sess.createQuery("update UserInfo u set u.BuildingId =:BuildingId ,RoomId =:RoomId,CampusId=:CampusId where StudentNo=:StudentNo")
.setString("BuildingId",String.valueOf(buildingId.get(0)))
.setString("RoomId", String.valueOf(roomid.get(0)))
.setString("CampusId",String.valueOf(campusId.get(0)))
.setString("StudentNo", srow[0]);
queryRslt=query1.executeUpdate();
if(queryRslt>0){
ui_success_count++;
}else{
updateFailureUI.add(srow[0]);
}
}catch(Exception e){
e.getStackTrace();
System.out.println("userinfo在更新学号为"+srow[0]+"的记录时,执行失败...");
}
flushCount++;
uid = sess.createQuery("select u.id from UserInfo u where StudentNo=:StudentNo")
.setString("StudentNo", srow[0])
.list();
ucardno = sess.createQuery("select u.CardNo from UserInfo u where StudentNo=:StudentNo")
.setString("StudentNo", srow[0])
.list();
try{
aid = sess.createQuery("select a.id from AlleyUser a where UserId=:UserId")
.setString("UserId",String.valueOf(uid.get(0)))
.list();
}catch(HibernateException e){
e.getStackTrace();
}catch(Exception e){
e.getStackTrace();
System.out.println("没有对应aid");
}
if(uid.size()!=0&& ucardno.size()!=0 ){
try{
AlleyUser au = new AlleyUser("2", String.valueOf(buildingId.get(0)), String.valueOf(uid.get(0)),"555", String.valueOf(uid.get(0)), String.valueOf(ucardno.get(0)), beginTime, endTime);
sess.save(au);
}catch(HibernateException e){
e.printStackTrace();
}catch(Exception e){
e.printStackTrace();
}
}
else{
System.out.println("uid.size() 或 ucardno.size()=0 没有该条userinfo的记录,也无法插入alleyuser的记录");
}
if ( flushCount % 20 == 0 ) { //20, same as the JDBC batch size //20,与JDBC批量设置相同
//flush a batch of inserts and release memory:
//将本批插入的对象立即写入数据库并释放内存
sess.flush();
sess.clear();
}
}
tx.commit();
sess.close();
System.out.println("本表格共有"+eContent.length+"条记录");
System.out.println("userinfo中成功插入条数:"+ui_success_count);
}
}