JDBC编程--2

JDBC编程–加强版

jdbc获取自增长的值

在数据库中建立一个表student,学生表中的id字段是主键,设置为自增长;
下面是给学生表中添加一条数据,获取这条数据的id:

package com.wy.increment;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

import com.wy.util.DBUtil;

public class IncreamentTest {
    public static void main(String[] args) {
        //这里是创建了一个类,用来获取数据库连接,这里代码不再提供
        Connection conn = DBUtil.getConnection();
        String sql = "INSERT INTO student(name,age) VALUES(?,?);";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            //设置返回自动生成的id
            //设置预编译语句返回自动生成的主键值,RETURN_GENERATED_KEYS
            pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            pstmt.setString(1, "cc");
            pstmt.setInt(2, 12);
            pstmt.executeUpdate();
            rs = pstmt.getGeneratedKeys();
            while(rs.next()){
                //结果返回自动生成的id值
                System.out.println(rs.getInt(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.closeConn(conn, pstmt);
        }
    }
}

JDBC的批处理

之前:一次操作只能发送一条sql语句到数据库服务器,效率并不高!
如果要插入2000条记录,那么必须发送2000条sql语句。
如果IO流的话,一次写出一个字节,显然效率效率并不高,所以可以使用缓存字节数组提高每次写出的效率。
现在:插入2000条记录,但现在使用sql缓存区,一次发送多条sql到数据库服务器执行。这种做法就叫做批处理。

 JDBC批处理的API
             Statement批处理:
                        void addBatch(String sql)  添加sql到缓存区(暂时不发送)
                        int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
                        void clearBatch()  清空sql缓存区

            PreparedStatement批处理:       
                        void addBatch() 添加参数到缓存区
                        int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
                        void clearBatch()  清空sql缓存区

下面使用statement和preparedstatement使用和不使用批处理向学生表插入2000条数据的效率。

package com.wy.statementbatch;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;

import com.wy.util.DBUtil;

public class StatementBatchTest {
    public static void main(String[] args) {
        long start = System.currentTimeMillis();
        //这里输出每一种方法执行插入2000条数据需要多长时间
        //statementTest();//60305
        //batchTest();//57021
        //preparedTest();//57725
        preparedBatchTest();//58703
        long end = System.currentTimeMillis();
        System.out.println(end - start);
    }   

    private static void preparedBatchTest() {
        Connection conn = null;
        PreparedStatement stmt = null;
        try{
            /*
             * 这里是创建了一个工具类,DBUtil,里面有两个静态方法,一个是getConnection(),
             * 一个是closeConn(Connection conn,Statement stmt);
             */
            conn  = DBUtil.getConnection();
            //创建一个动态的sql语句
            String sql  = "insert into student values(?,?,?);";
            stmt = conn.prepareStatement(sql);
            //型数据库插入2000条数据,一次插入一条
            for (int i = 1; i <=2000; i++) {
                stmt.setInt(1, i);
                stmt.setString(2, "cc");
                stmt.setInt(3, 14);
                stmt.addBatch();
                //判断每20条发送一次
                if (i%20==0) {
                    stmt.executeBatch();
                    //清空缓存区
                    stmt.clearBatch();
                }

            }
        }catch(Exception e){
            e.printStackTrace();
        }finally{
            //释放资源
            DBUtil.closeConn(conn, stmt);
        }

    }

    private static void preparedTest() {
        Connection conn = DBUtil.getConnection();
        PreparedStatement pstmt=null;
        try {
            for (int i = 1; i <= 2000; i++) {
                String sql = "INSERT INTO student VALUES(?,?,?);";
                pstmt = conn.prepareStatement(sql);
                pstmt.setInt(1, i);
                pstmt.setString(2, "cc");
                pstmt.setInt(3, 12);
                pstmt.executeUpdate();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.closeConn(conn, pstmt);
        }
    }

    private static void statementTest() {
        Connection conn = DBUtil.getConnection();
        Statement stmt=null;
        try {
            stmt = conn.createStatement();
            for (int i = 1; i <= 2000; i++) {
                String sql = "INSERT INTO student VALUES("+i+",'cc',23);";
                stmt.executeUpdate(sql);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.closeConn(conn, stmt);
        }
    }

    private static void batchTest() {
        Connection conn = DBUtil.getConnection();
        Statement stmt=null;
        try {
            stmt = conn.createStatement();
            for (int i = 1; i <= 2000; i++) {
                String sql = "INSERT INTO student VALUES("+i+",'cc',23);";
                stmt.addBatch(sql);
                if(i%20 == 0){
                    stmt.executeBatch();
                    stmt.clearBatch();
                }

            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.closeConn(conn, stmt);
        }       
    }   
}

jdbc处理大数据文件

大容量的字符字段:
            mysql: text(64K)   longtext(4G字符内容)
            oracle :  clob   longclob           

大容量的字节字段:
        mysql: blob(65kb)   mediumblob(16mb)  longblog(4GB)     
        oracle:   blob

jdbc处理大容量的字符字段示例:

package com.wy.clob;
/*
 *这个是在数据库中创建一个表,两个字段 
    CREATE TABLE news(
    title VARCHAR(100),
    content LONGTEXT
    );
 */

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import com.wy.util.DBUtil;

public class ClobTest {
    /*
     * 将一篇文章存入数据库
     */
    public static void main(String[] args) throws IOException {
        // saveToDB();
        writerTest();
    }

    private static void writerTest() throws IOException {
        Connection conn = DBUtil.getConnection();
        String sql = "select * from news;";
        Statement stmt = null;
        FileWriter fw = new FileWriter("result.txt");
        try {
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()){
                Reader reader = rs.getCharacterStream(2);
                char[] chs = new char[1024];
                int len;
                while((len = reader.read(chs))!= -1){
                    fw.write(chs, 0, len);
                    fw.flush();
                }
                reader.close();
            }
            fw.close();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeConn(conn, stmt);
        }
    }

    private static void saveToDB() {
        Connection conn = DBUtil.getConnection();
        String sql = "insert into news values(?,?);";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "studyyyyyy");
            // void setClob(int parameterIndex,Reader reader)throws SQLException
            pstmt.setClob(2, new FileReader("d://xuexi.docx"));
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeConn(conn, pstmt);
        }
    }
}

jdbc处理大容量的字符字段示例:

package com.wy.blob;

import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import com.wy.util.DBUtil;

public class BlobTest {
    public static void main(String[] args) {
        // 从数据库中读取数据
        // readTest();

        // 把mp3文件保存如数据库
        writerTest();
    }

    private static void writerTest() {
        Connection conn = DBUtil.getConnection();
        String sql = "insert into news values(?,?);";
        PreparedStatement pstmt = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1, "video_yueyu");
            // void setClob(int parameterIndex,Reader reader)throws SQLException
            pstmt.setClob(2, new FileReader("E://joy.mp4"));
            int count = pstmt.executeUpdate();
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeConn(conn, pstmt);
        }
    }

    private static void readTest() throws Exception {
        Connection conn = DBUtil.getConnection();
        String sql = "select * from news;";
        Statement stmt = null;
        FileOutputStream fos;

            fos = new FileOutputStream("videoresult.mp4");

        try {
            stmt = conn.createStatement();
            ResultSet rs = stmt.executeQuery(sql);
            while(rs.next()){
                InputStream is = rs.getBinaryStream(2);

                byte[] bys = new byte[1024];
                int len;
                while((len = is.read(bys))!= -1){
                    fos.write(bys,0,len);
                }
                fos.close();
                is.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            DBUtil.closeConn(conn, stmt);
        }
}
}

数据库中的事务以及在JDBC中的体现

所谓的事务,如果把多条sql语句看做一个事务,那么这个事务要么一起成功,要么一起失败!!

数据库事务的四大特性(简称ACID,acid是英文酸,醋的意思)是:
1. 原子性(Atomicity)
要么一起成功过,要么一起失败
2. 一致性(Consistency)
数据库应该从一个一致性的状态到另一个一致性的状态,保持不变。
3. 分离性(亦称独立性Isolation)
多个并发事务直接应该可以相互隔离

  1. 持久性(Durability)
    事务一旦提交,应该永久保持下来。

mysql事务操作命令

set autocommit =0 / 1;          
设置是否自动提交事务
1: 表示自动提交事务,每执行一条sql语句,自动提交事务。
0: 表示关闭自动提交事务。

commit;
提交事务,一旦提交事务不能回滚

rollback;
回滚事务。回滚到事务的起始点。
CREATE DATABASE testdb;
 USE testdb;

 CREATE TABLE account(
 NAME VARCHAR(20),
 balance INT
 );

 INSERT INTO account VALUES('tom',5000);
 INSERT INTO account VALUES('kite',5000);

1.创建一个account表,然后进行存取操作,如果不设置自动提交,则为自动提交;
即下面的操作会直接更新数据库:

UPDATE account SET balance=balance-2000 WHERE NAME='kite';
UPDATE account SET balance=balance+2000 WHERE NAME='tom';

2.如果设置为手动提交,则更新不写入数据库:

 SET autocommit=0;
 UPDATE account SET balance=balance-2000 WHERE NAME='kite';
 UPDATE account SET balance=balance+2000 WHERE NAME='tom';

只有提交了,才会写入数据库:

commit;

3.如果设置为手动提交,在更新之后进行了回滚,则操作不更新到数据库:

SET autocommit=0;
UPDATE account SET balance=balance-2000 WHERE NAME='kite';
UPDATE account SET balance=balance+2000 WHERE NAME='tom';   
ROLLBACK;

4.如果设置为手动提交,在更新之后提交,再进行回滚,则回不到初始状态:

SET autocommit=0;
UPDATE account SET balance=balance-2000 WHERE NAME='kite';
UPDATE account SET balance=balance+2000 WHERE NAME='tom';   
COMMIT;

commit表示事务的结束;

jdbc事务操作

Connection.setAutoCommit(false)  开启事务
Connection.commit();  成功执行,最后提交事务
Connection.rollback();  一旦遇到错误,回滚事务
package com.wy.db;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
 * CREATE DATABASE testdb;
 USE testdb;

 CREATE TABLE account(
 NAME VARCHAR(20),
 balance INT
 );

 INSERT INTO account VALUES('tom',5000);
 INSERT INTO account VALUES('kite',5000);

 SET autocommit=0;
 SET autocommit=1;
 UPDATE account SET balance=balance-2000 WHERE NAME='kite';
 UPDATE account SET balance=balance+2000 WHERE NAME='tom';
 ROLLBACK;
 COMMIT;

 SELECT * FROM account;
 DELETE FROM account;
 DROP TABLE acount;
 */
//在Java中数据库的事务体现
public class TransactionTest {
    public static void main(String[] args) {
        Connection conn = getConnection();
        String sqlMinus = "UPDATE account SET balance=balance-2000 WHERE NAME=?;";
        String sqlAdd = " UPDATE account SET balance=balance+2000 WHERE NAME=?;";
        try {
            conn.setAutoCommit(false);
            PreparedStatement pstmt = conn.prepareStatement(sqlMinus);
            pstmt.setString(1, "kite");
            pstmt.executeUpdate();
            pstmt = conn.prepareStatement(sqlAdd);
            pstmt.setString(1, "tom");
            pstmt.executeUpdate();
            //只有都成功执行才进行提交,在数据库进行更改
            conn.commit();

        } catch (SQLException e) {
            e.printStackTrace();
            System.out.println("转账出现异常");
            try {
                //如果转账出现异常,则进行回滚
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            //释放资源
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    private static Connection getConnection() {
        //进行数据库连接
        String url = "jdbc:mysql://localhost:3306/testdb";
        String user = "root";
        String password = "root";
        try {
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(url, user, password);
            return conn;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;        
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值