之前已经实现了SQL SERVER的配置,也能够用Java与SQL连接了。那么,现在要做的就是小试牛刀了!我要做的是处理一个关于豆瓣书评的数据集。原来导入的只有书名,用户名和评分。我现在要做的就是建立一个新表,里面包括行id,书的id,书名,用户Id,用户名和评分。主要问题是建立一个用户表和书表。当原表输入一个新行时,检测书名是否在书表里面出现过,出现过的话就用现成的书id,否则就把这个书名插入书表里面,并赋予一个新的id。
这里碰到了一个问题就是statement和结果集ResultSet是一一对应的关系,所以如果定义有Statement stmt,先定义了ResultSet st1=stmt.executeQuery(query1) 然后又定义了ResultSet st2=stmt.executeQuery(query2) 那么结果集st1会自动关闭。解决方法是定义2个Statement来定义2个结果集。即:
Statement st1=con.createStatement();
Statement st2=con.createStatement();
ResultSet rs1=st1.executeQuery(query1);
ResultSet rs2=st2.executeQuery(query2);
下面上程序:
package databasetest;
import java.sql.*;
public class javaConSQL{
public static void main(String[] args) {
String JDriver="com.microsoft.sqlserver.jdbc.SQLServerDriver";//SQL数据库引擎
String connectDB="jdbc:sqlserver://127.0.0.1:1433;DatabaseName=multiangle";//数据源
try{
Class.forName(JDriver);//加载数据库引擎,返回给定字符串名的类
}catch(ClassNotFoundException e){ //e.printStackTrace();
System.out.println("加载数据库引擎失败");
System.exit(0);
}
System.out.println("数据库驱动成功");
try{
String user="sa";
String password="admin";
Connection con=DriverManager.getConnection(connectDB,user,password);//连接数据库对象
System.out.println("连接数据库成功");
Statement stmt=con.createStatement();//创建SQL命令对象
Statement stmt_book=con.createStatement(); //创建book查询对象
Statement stmt_user=con.createStatement() ; //创建user查询对象
Statement stmt_initial=con.createStatement(); //用作插入用
System.out.println("删除旧的user_table");
String query="drop table user_table";
stmt_user.executeUpdate(query);
System.out.println("开始创建user_table数据库");
query="create table user_table(username varchar(50),userid int,useractiv int);";
stmt_user.executeUpdate(query);
System.out.println("删除旧的book");
query="drop table book";
stmt_book.executeUpdate(query);
System.out.println("开始创建book数据库");
query="create table book(bookname varchar(50),bookid int,bookactiv int)";
stmt_book.executeUpdate(query);
int bookcount=0,usercount=0; //记录bookid和userid
int bookid,userid;
int bookactiv,useractiv;
//int linecount=0;
System.out.println("清空Initial数据");
query="delete initial;";
stmt_initial.executeUpdate(query);
System.out.println("开始读取数据");
query="select *,row_number() over (order by bookname) as row from dbo.douban";
ResultSet rs=stmt.executeQuery(query); //返回SQL语句查询结果集(集合)
//循环输出每一条记录
//ResultSet rs_book ;
//ResultSet rs_user ;
while(rs.next()){
//linecount++ ;
//输出每个字段
// bookid相关
query="select * from book where bookname='"+rs.getString("bookname")+"';" ;
ResultSet rs_book=stmt_book.executeQuery(query);
if (rs_book.next()){
bookid=rs_book.getInt("bookid");
bookactiv=rs_book.getInt("bookactiv")+1;
query="update book set bookactiv="+bookactiv+" where bookid="+bookid ;
stmt_book.executeUpdate(query);
}
else{
bookcount++;
query="insert into book values("+rs.getString("bookname")+','+bookcount+','+'1'+");";
stmt_book.executeUpdate(query);
bookid=bookcount;
}
rs_book.close();
//userid相关
query="select * from user_table where username='"+rs.getString("username")+"';" ;
ResultSet rs_user=stmt_user.executeQuery(query);
if (rs_user.next()){
userid=rs_user.getInt("userid");
useractiv=rs_user.getInt("useractiv")+1;
query="update user_table set useractiv="+useractiv+" where userid="+userid ;
stmt_user.executeUpdate(query);
}
else{
usercount++;
query="insert into user_table values('"+rs.getString("username")+"',"+usercount+','+'1'+");";
stmt_user.executeUpdate(query);
userid=usercount;
}
rs_book.close();
query="insert into dbo.initial (row,bookid,bookname,userid,username,score) values ("+rs.getInt("row")+','+bookid+",'"+rs.getString("bookname")+"',"+userid+",'"+rs.getString("username")+"',"+Integer.parseInt(rs.getString("score"))+");";
//System.out.println(query) ; //测试用
stmt_initial.executeUpdate(query); //将寻找到的再加上处理过的数值插入initial表
System.out.println("line "+rs.getInt("row")+" is dealed");
}
//关闭连接
stmt.close();//关闭命令对象连接
stmt_user.close();
stmt_book.close();
stmt_initial.close();
con.close();//关闭数据库连接
}
catch(SQLException e){
e.printStackTrace();
//System.out.println("数据库连接错误");
System.exit(0);
}
}
}
存在的问题:太慢了!!!我在写这篇博文这会程序已经跑了50分钟。才处理了13W行。而我之前看过,这个76M的txt文件里面有360W行。。。按照现在的处理速度显然是不可接受的。
可能的解决方案:
1。一行一行的从数据库读取或者插入数据库,效率太低了,应该想办法一次读取多行,以提高效率;
2。此处程序里的user表和book表都是存入数据库,查找也从数据库里面查找。如此一来每处理一行原表都要多次访问数据库,降低效率。可以想办法把这两个表以链表形式存入内存,以提高效率;
3。跑程序的时候CPU和内存还有余力,所以如果可能的话,我想用多线程来充分利用剩余的硬件资源。