按照这个需求我去网上查了很多的资料,也找出了几种解决的办法,但是由于技术不够成熟,最终都放弃了,网上的参考方法是:
1.使用quartz框架,这是纯Java开发的框架,使用起来也很简单,只要自己定义一个Job,创建一个触发器即可。
2.使用定时作业,这个我不是很清楚,所以首先放弃了。
3.使用存储过程和Job,由于很久没接触过存储过程,很多知识也记不清了,所以也放弃了
4.有的建议是用DTSX,说实话到现在我还不知道它是个什么东东。
这些方法我都去尝试过,但是后来我还是用了自己最笨的方法,用java做了个定时器,定时去调用取数据,和导数据的方法,这个功能是实现了,我测试过也没什么问题,数据也没有丢失的现实。因为还没有正式使用,所以还找不出问题所在,现在我把我的思路和实现的方法给大家看下,如果有问题,请大家指导下,本人现谢过了。
首先由于在导数据的时候,操作员要了解数据是否导入,或者是否已导入成功,要涉及到日志,所以我自己写了一个专门写日志的一个类,代码如下:
public class PrintLog { public PrintLog(){ } public static void writeLog(String log){ //获取文件缓冲流 BufferedWriter writer=null; try { FileWriter fileWriter = new FileWriter("D://log.txt",true); writer=new BufferedWriter(fileWriter); //格式化写入时间 SimpleDateFormat sdf=new SimpleDateFormat("yyyy-MM-dd hh:mm:ss"); String writetime=sdf.format(new Date()); writer.write(writetime);//写入时间 writer.write(log);//写入日志内容 writer.newLine(); writer.flush(); writer.close(); } catch (IOException e) { e.printStackTrace(); } } }
接下来我就用jdbc实现的导入数据的功能,由于目前只有一个表。所以实现起来也很简单。但是问题是如果数据量大,会不会有数据重复,溢露的现象呢,这个我也无从分析,反正我用10000条数据测试了下,没有什么问题。然后就是效率的问题,我是每条数据都去执行一次插入,还是去批量的插入。后来我发现jdbc支持批量的插入,所以我选择了批量的插入。
代码如下:
public class DB { static int precount=100; public static Connection getConnect() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8", "root", "root"); return conn; } //插入数据 public static int insertObject(List<PoAJ> list){ Connection conn=null; PreparedStatement ps=null; try { conn=DB.getConnect(); //关闭自动提交 conn.setAutoCommit(false); //清空数据库 ps=conn.prepareStatement("truncate poaj"); //ps.executeUpdate();这里我没用执行,因为一旦出错,没法回滚! long startTime=System.currentTimeMillis(); String sql="insert into poaj(ah,name,data)values(?,?,?)"; ps=conn.prepareStatement(sql); for(int i=0;i<list.size();i++){ PoAJ p=list.get(i); ps.setString(1,p.getAh()); ps.setString(2,p.getName()); ps.setInt(3, p.getData()); ps.addBatch(); //每precount次就批量处理一次 } //提交 ps.executeBatch(); conn.commit(); ps.clearBatch(); long endTime=System.currentTimeMillis(); System.out.println("插入数据时间为:"+(endTime-startTime)); return (int)endTime; } catch (Exception e) { try { //如果出现问题就回滚 conn.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } e.printStackTrace(); }finally{ try { if(ps!=null) ps.close(); if(conn!=null) conn.close(); } catch (SQLException e) { e.printStackTrace(); } } return -1; } }
导数据的功能都有了,现在只差如何实现定时去导入数据,所以我用java做了个定时器,在特定是时间执行,这个类我是用timer实现的,它是一种线程设施,用于安排以后在后台线程中执行的任务。可安排任务执行一次,或者定期重复执行。实现的方法如下:
class PickTask{ private Timer timer; private String time;//触发时间 public PickTask(String time){ timer=new Timer(); this.time=time; } private TimerTask task=new TimerTask(){ @Override public void run() { Date date = new Date(); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); String beginDate = sdf.format(date); //截取时间段 String beginTime = beginDate.substring(11, 16); System.out.println(beginDate+" "+beginTime); // PrintLog log=new PrintLog(); if(beginTime.equals(time)){ PrintLog.writeLog("开始取出数据"); //这里我自定义了1000条数据 List<PoAJ> l=new ArrayList<PoAJ>(); long startTime=System.currentTimeMillis(); for(int i=10000;i<20000;i++){ PoAJ p=new PoAJ(); p.setAh(""+i); p.setName(""+i); p.setData(i); l.add(p); } long endTime=System.currentTimeMillis(); PrintLog.writeLog("取出数据数量为"+l.size()+" 时间为:"+(endTime-startTime)+"ms"); PrintLog.writeLog("开始导入数据"); int ret=DB.insertObject(l); if(ret>0){ PrintLog.writeLog("导入数据成功,时间为:"+ret+"ms"); }else{ PrintLog.writeLog("导入数据失败"); } // } } };
以上做好之后,只需要自定一个时间,然后它就会在定时间去运行。
功能是现实了,可是我相信还可以更加完善,或者有些漏洞我还没有考虑到的请大虾门指出,或者还有更好的方法借鉴,小弟在此恭候了。