用Java控制SQL进行一些简单的处理

本文详细介绍了如何优化大数据处理速度,通过改进数据库建模和查询策略,将豆瓣书评数据集转换为包含行ID、书ID、书名、用户ID、用户名和评分的新表。重点讨论了使用Java与SQL连接数据库,建立用户表和书表的方法,并解决了Statement和ResultSet关系导致的资源泄露问题。文章还提出了提高效率的可能解决方案,包括批量读取和插入数据、将表缓存在内存中以及引入多线程处理。

之前已经实现了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和内存还有余力,所以如果可能的话,我想用多线程来充分利用剩余的硬件资源。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值