成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專(zhuān)欄INFORMATION COLUMN

JDBC【PreparedStatment、批處理、處理二進(jìn)制、自動(dòng)主鍵、調(diào)用存儲(chǔ)過(guò)程、函數(shù)】

YFan / 3119人閱讀

摘要:可對(duì)進(jìn)行預(yù)編譯,提高效率,預(yù)編譯的存儲(chǔ)在對(duì)象中防止注入。獲取到自動(dòng)主鍵列的值調(diào)用數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程調(diào)用存儲(chǔ)過(guò)程的語(yǔ)法調(diào)用函數(shù)的語(yǔ)法如果是類(lèi)型的,那么在調(diào)用的時(shí)候是要注冊(cè)的。

1.PreparedStatement對(duì)象

PreparedStatement對(duì)象繼承Statement對(duì)象,它比Statement對(duì)象更強(qiáng)大,使用起來(lái)更簡(jiǎn)單

Statement對(duì)象編譯SQL語(yǔ)句時(shí),如果SQL語(yǔ)句有變量,就需要使用分隔符來(lái)隔開(kāi),如果變量非常多,就會(huì)使SQL變得非常復(fù)雜。PreparedStatement可以使用占位符,簡(jiǎn)化sql的編寫(xiě)

Statement會(huì)頻繁編譯SQL。PreparedStatement可對(duì)SQL進(jìn)行預(yù)編譯,提高效率,預(yù)編譯的SQL存儲(chǔ)在PreparedStatement對(duì)象中

PreparedStatement防止SQL注入?!維tatement通過(guò)分隔符"++",編寫(xiě)永等式,可以不需要密碼就進(jìn)入數(shù)據(jù)庫(kù)】

        //模擬查詢(xún)id為2的信息
        String id = "2";

        Connection connection = UtilsDemo.getConnection();

        String sql = "SELECT * FROM users WHERE id = ?";
        PreparedStatement preparedStatement = connection.preparedStatement(sql);

        //第一個(gè)參數(shù)表示第幾個(gè)占位符【也就是?號(hào)】,第二個(gè)參數(shù)表示值是多少
        preparedStatement.setString(1,id);

        ResultSet resultSet = preparedStatement.executeQuery();

        if (resultSet.next()) {
            System.out.println(resultSet.getString("name"));
        }

        //釋放資源
        UtilsDemo.release(connection, preparedStatement, resultSet);
2.批處理

當(dāng)需要向數(shù)據(jù)庫(kù)發(fā)送一批SQL語(yǔ)句執(zhí)行時(shí),應(yīng)避免向數(shù)據(jù)庫(kù)一條條發(fā)送執(zhí)行,采用批處理以提升執(zhí)行效率

批處理有兩種方式:

Statement

PreparedStatement

通過(guò)executeBath()方法批量處理執(zhí)行SQL語(yǔ)句,返回一個(gè)int[]數(shù)組,該數(shù)組代表各句SQL的返回值

以下代碼是以Statement方式實(shí)現(xiàn)批處理

        /*
        * Statement執(zhí)行批處理
        *
        * 優(yōu)點(diǎn):
        *       可以向數(shù)據(jù)庫(kù)發(fā)送不同的SQL語(yǔ)句
        * 缺點(diǎn):
        *       SQL沒(méi)有預(yù)編譯
        *       僅參數(shù)不同的SQL,需要重復(fù)寫(xiě)多條SQL
        * */
        Connection connection = UtilsDemo.getConnection();

        Statement statement = connection.createStatement();
        String sql1 = "UPDATE users SET name="zhongfucheng" WHERE id="3"";
        String sql2 = "INSERT INTO users (id, name, password, email, birthday)" +
                " VALUES("5","nihao","123","[email protected]","1995-12-1")";

        //將sql添加到批處理
        statement.addBatch(sql1);
        statement.addBatch(sql2);

        //執(zhí)行批處理
        statement.executeBatch();

        //清空批處理的sql
        statement.clearBatch();

        UtilsDemo.release(connection, statement, null);

以下方式以PreparedStatement方式實(shí)現(xiàn)批處理

        /*
        * PreparedStatement批處理
        *   優(yōu)點(diǎn):
        *       SQL語(yǔ)句預(yù)編譯了
        *       對(duì)于同一種類(lèi)型的SQL語(yǔ)句,不用編寫(xiě)很多條
        *   缺點(diǎn):
        *       不能發(fā)送不同類(lèi)型的SQL語(yǔ)句
        *
        * */
        Connection connection = UtilsDemo.getConnection();

        String sql = "INSERT INTO test(id,name) VALUES (?,?)";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);

        for (int i = 1; i <= 205; i++) {
            preparedStatement.setInt(1, i);
            preparedStatement.setString(2, (i + "zhongfucheng"));

            //添加到批處理中
            preparedStatement.addBatch();

            if (i %2 ==100) {

                //執(zhí)行批處理
                preparedStatement.executeBatch();

                //清空批處理【如果數(shù)據(jù)量太大,所有數(shù)據(jù)存入批處理,內(nèi)存肯定溢出】
                preparedStatement.clearBatch();
            }

        }
        //不是所有的%2==100,剩下的再執(zhí)行一次批處理
        preparedStatement.executeBatch();

        //再清空
        preparedStatement.clearBatch();

        UtilsDemo.release(connection, preparedStatement, null);



3.處理大文本和二進(jìn)制數(shù)據(jù)

clob和blob

clob用于存儲(chǔ)大文本

blob用于存儲(chǔ)二進(jìn)制數(shù)據(jù)

MYSQL

MySQL存儲(chǔ)大文本是用Test【代替clob】,Test又分為4類(lèi)

TINYTEXT

TEXT

MEDIUMTEXT

LONGTEXT

同理blob也有這4類(lèi)

下面用JDBC連接MySQL數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)和二進(jìn)制數(shù)據(jù)



/*
*用JDBC操作MySQL數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)
*
*setCharacterStream(int parameterIndex,java.io.Reader reader,long length)
*第二個(gè)參數(shù)接收的是一個(gè)流對(duì)象,因?yàn)榇笪谋静粦?yīng)該用String來(lái)接收,String太大會(huì)導(dǎo)致內(nèi)存溢出
*第三個(gè)參數(shù)接收的是文件的大小
*
* */
public class Demo5 {

    @Test
    public void add() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO test2 (bigTest) VALUES(?) ";
            preparedStatement = connection.prepareStatement(sql);

            //獲取到文件的路徑
            String path = Demo5.class.getClassLoader().getResource("BigTest").getPath();
            File file = new File(path);
            FileReader fileReader = new FileReader(file);

            //第三個(gè)參數(shù),由于測(cè)試的Mysql版本過(guò)低,所以只能用int類(lèi)型的。高版本的不需要進(jìn)行強(qiáng)轉(zhuǎn)
            preparedStatement.setCharacterStream(1, fileReader, (int) file.length());

            if (preparedStatement.executeUpdate() > 0) {
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }


    }

    /*
    * 讀取大文本數(shù)據(jù),通過(guò)ResultSet中的getCharacterStream()獲取流對(duì)象數(shù)據(jù)
    * 
    * */
    @Test
    public void read() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM test2";
            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {

                Reader reader = resultSet.getCharacterStream("bigTest");

                FileWriter fileWriter = new FileWriter("d:abc.txt");
                char[] chars = new char[1024];
                int len = 0;
                while ((len = reader.read(chars)) != -1) {
                    fileWriter.write(chars, 0, len);
                    fileWriter.flush();
                }
                fileWriter.close();
                reader.close();

            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, resultSet);
        }
        
    }



/*
* 使用JDBC連接MYsql數(shù)據(jù)庫(kù)操作二進(jìn)制數(shù)據(jù)
* 如果我們要用數(shù)據(jù)庫(kù)存儲(chǔ)一個(gè)大視頻的時(shí)候,數(shù)據(jù)庫(kù)是存儲(chǔ)不到的。
* 需要設(shè)置max_allowed_packet,一般我們不使用數(shù)據(jù)庫(kù)去存儲(chǔ)一個(gè)視頻
* */
public class Demo6 {

    @Test
    public void add() {


        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;


        try {
            connection = JdbcUtils.getConnection();
            String sql = "INSERT INTO test3 (blobtest) VALUES(?)";
            preparedStatement = connection.prepareStatement(sql);

            //獲取文件的路徑和文件對(duì)象
            String path = Demo6.class.getClassLoader().getResource("1.wmv").getPath();
            File file = new File(path);

            //調(diào)用方法
            preparedStatement.setBinaryStream(1, new FileInputStream(path), (int)file.length());

            if (preparedStatement.executeUpdate() > 0) {

                System.out.println("添加成功");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

    }

    @Test
    public void read() {


        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;


        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM test3";
            preparedStatement = connection.prepareStatement(sql);

            resultSet = preparedStatement.executeQuery();


            //如果讀取到數(shù)據(jù),就把數(shù)據(jù)寫(xiě)到磁盤(pán)下
            if (resultSet.next()) {
                InputStream inputStream = resultSet.getBinaryStream("blobtest");
                FileOutputStream fileOutputStream = new FileOutputStream("d:aa.jpg");

                int len = 0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {

                    fileOutputStream.write(bytes, 0, len);

                }
                fileOutputStream.close();
                inputStream.close();

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }

    }


Oracle

下面用JDBC連接Oracle數(shù)據(jù)庫(kù)去操作大文本數(shù)據(jù)和二進(jìn)制數(shù)據(jù)



//使用JDBC連接Oracle數(shù)據(jù)庫(kù)操作二進(jìn)制數(shù)據(jù)
    
/*
* 對(duì)于Oracle數(shù)據(jù)庫(kù)和Mysql數(shù)據(jù)庫(kù)是有所不同的。
* 1.Oracle定義了BLOB字段,但是這個(gè)字段不是真正地存儲(chǔ)二進(jìn)制數(shù)據(jù)
* 2.向這個(gè)字段存一個(gè)BLOB指針,獲取到Oracle的BLOB對(duì)象,把二進(jìn)制數(shù)據(jù)放到這個(gè)指針里面,指針指向BLOB字段
* 3.需要事務(wù)支持
*
* */
public class Demo7 {
    @Test
    public void add() {


        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = UtilsDemo.getConnection();

            //開(kāi)啟事務(wù)
            connection.setAutoCommit(false);

            //插入一個(gè)BLOB指針
            String sql = "insert into test4(id,image) values(?,empty_blob())";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1, 1);
            preparedStatement.executeUpdate();

            //把BLOB指針查詢(xún)出來(lái),得到BLOB對(duì)象
            String sql2 = "select image from test4 where id= ? for update";
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.setInt(1, 1);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {
                //得到Blob對(duì)象--當(dāng)成是Oracle的Blob,不是JDBC的,所以要強(qiáng)轉(zhuǎn)[導(dǎo)的是oracle.sql.BLOB包]
                BLOB  blob = (BLOB) resultSet.getBlob("image");

                //寫(xiě)入二進(jìn)制數(shù)據(jù)
                OutputStream outputStream = blob.getBinaryOutputStream();

                //獲取到讀取文件讀入流
                InputStream inputStream = Demo7.class.getClassLoader().getResourceAsStream("01.jpg");

                int len=0;
                byte[] bytes = new byte[1024];
                while ((len = inputStream.read(bytes)) > 0) {

                    outputStream.write(bytes, 0, len);
                }
                outputStream.close();
                inputStream.close();
                connection.setAutoCommit(true);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }

    }

    @Test
    public void find() {
        
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = UtilsDemo.getConnection();
            String sql = "SELECT * FROM test4 WHERE id=1";

            preparedStatement = connection.prepareStatement(sql);
            resultSet = preparedStatement.executeQuery();

            if (resultSet.next()) {

                //獲取到BLOB對(duì)象
                BLOB blob = (BLOB) resultSet.getBlob("image");

                //將數(shù)據(jù)讀取到磁盤(pán)上
                InputStream inputStream = blob.getBinaryStream();
                FileOutputStream fileOutputStream = new FileOutputStream("d:zhongfucheng.jpg");
                int len=0;
                byte[] bytes = new byte[1024];

                while ((len = inputStream.read(bytes)) > 0) {

                    fileOutputStream.write(bytes, 0, len);
                }

                inputStream.close();
                fileOutputStream.close();

            }

        } catch (SQLException e) {
            e.printStackTrace();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            UtilsDemo.release(connection, preparedStatement, null);
        }
    }
}


對(duì)于JDBC連接Oracle數(shù)據(jù)庫(kù)操作CLOB數(shù)據(jù),我就不再重復(fù)了,操作跟BLOB幾乎相同

4.獲取數(shù)據(jù)庫(kù)的自動(dòng)主鍵列 為什么要獲取數(shù)據(jù)庫(kù)的自動(dòng)主鍵列數(shù)據(jù)?

應(yīng)用場(chǎng)景:

有一張老師表,一張學(xué)生表。現(xiàn)在來(lái)了一個(gè)新的老師,學(xué)生要跟著新老師上課。

我首先要知道老師的id編號(hào)是多少,學(xué)生才能知道跟著哪個(gè)老師學(xué)習(xí)【學(xué)生外鍵參照老師主鍵】。


    @Test
    public void test() {

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();

            String sql = "INSERT INTO test(name) VALUES(?)";
            preparedStatement = connection.prepareStatement(sql);

            preparedStatement.setString(1, "ouzicheng");

            if (preparedStatement.executeUpdate() > 0) {

                //獲取到自動(dòng)主鍵列的值
                resultSet = preparedStatement.getGeneratedKeys();

                if (resultSet.next()) {
                    int id = resultSet.getInt(1);
                    System.out.println(id);
                }
            }
            
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(connection, preparedStatement, null);
        }



5.調(diào)用數(shù)據(jù)庫(kù)的存儲(chǔ)過(guò)程

調(diào)用存儲(chǔ)過(guò)程的語(yǔ)法:

    {call [(,, ...)]}

調(diào)用函數(shù)的語(yǔ)法:

    {?= call [(,, ...)]}

如果是Output類(lèi)型的,那么在JDBC調(diào)用的時(shí)候是要注冊(cè)的。如下代碼所示:


/*
    jdbc調(diào)用存儲(chǔ)過(guò)程

    delimiter $$
        CREATE PROCEDURE demoSp(IN inputParam VARCHAR(255), INOUT inOutParam varchar(255))
        BEGIN
            SELECT CONCAT("zyxw---", inputParam) into inOutParam;
        END $$
    delimiter ;
*/
//我們?cè)贘DBC調(diào)用存儲(chǔ)過(guò)程,就像在調(diào)用方法一樣
public class Demo9 {

    public static void main(String[] args) {
        Connection connection = null;
        CallableStatement callableStatement = null;

        try {
            connection = JdbcUtils.getConnection();
            
            callableStatement = connection.prepareCall("{call demoSp(?,?)}");

            callableStatement.setString(1, "nihaoa");
            
            //注冊(cè)第2個(gè)參數(shù),類(lèi)型是VARCHAR
            callableStatement.registerOutParameter(2, Types.VARCHAR);
            callableStatement.execute();
            
            //獲取傳出參數(shù)[獲取存儲(chǔ)過(guò)程里的值]
            String result = callableStatement.getString(2);
            System.out.println(result);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                connection.close();
                callableStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

參考資料:


----------------------------------------------------------------------------------過(guò)程

#修改mysql語(yǔ)句的結(jié)果符為//
mysql > delimiter //

#定義一個(gè)過(guò)程,獲取users表總記錄數(shù),將10設(shè)置到變量count中
create procedure simpleproc(out count int)
begin
    select count(id) into count from users;
end
//

#修改mysql語(yǔ)句的結(jié)果符為;
mysql > delimiter ;

#調(diào)用過(guò)程,將結(jié)果覆給變量a,@是定義變量的符號(hào)
call simpleproc(@a);

#顯示變量a的值
select @a;

//以下是Java調(diào)用Mysql的過(guò)程
    String sql = "{call simpleproc(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.INTEGER);
    cstmt.execute();
    Integer count = cstmt.getInt(1);
    System.out.println("共有" + count + "人");

----------------------------------------------------------------------------------函數(shù)

#修改mysql語(yǔ)句的結(jié)果符為//
mysql > delimiter //

#定義一個(gè)函數(shù),完成字符串拼接
create function hello( s char(20) ) returns char(50) 
return concat("hello,",s,"!");
//

#修改mysql語(yǔ)句的結(jié)果符為;
mysql > delimiter ;

#調(diào)用函數(shù)
select hello("world");

//以下是Java調(diào)用Mysql的函數(shù)
    String sql = "{? = call hello(?)}";
    Connection conn = JdbcUtil.getConnection();
    CallableStatement cstmt = conn.prepareCall(sql);
    cstmt.registerOutParameter(1,Types.VARCHAR);
    cstmt.setString(2,"zhaojun");
    cstmt.execute();
    String value = cstmt.getString(1);
    System.out.println(value);
    JdbcUtil.close(cstmt);
    JdbcUtil.close(conn);

如果文章有錯(cuò)的地方歡迎指正,大家互相交流。習(xí)慣在微信看技術(shù)文章的同學(xué),可以關(guān)注微信公眾號(hào):Java3y

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/68488.html

相關(guān)文章

  • Java3y文章目錄導(dǎo)航

    摘要:前言由于寫(xiě)的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 前言 由于寫(xiě)的文章已經(jīng)是有點(diǎn)多了,為了自己和大家的檢索方便,于是我就做了這么一個(gè)博客導(dǎo)航。 由于更新比較頻繁,因此隔一段時(shí)間才會(huì)更新目錄導(dǎo)航哦~想要獲取最新原創(chuàng)的技術(shù)文章歡迎關(guān)注我的公眾號(hào):Java3y Java3y文章目錄導(dǎo)航 Java基礎(chǔ) 泛型就這么簡(jiǎn)單 注解就這么簡(jiǎn)單 Druid數(shù)據(jù)庫(kù)連接池...

    KevinYan 評(píng)論0 收藏0
  • Java JDBC編程

    摘要:和很像,嚴(yán)格來(lái)說(shuō),應(yīng)該是模仿了是設(shè)計(jì)。程序中使用該類(lèi)的主要功能是獲取對(duì)象,該類(lèi)包含如下方法該方法獲得對(duì)應(yīng)數(shù)據(jù)庫(kù)的連接代表數(shù)據(jù)庫(kù)連接對(duì)象,每個(gè)代表一個(gè)物理連接會(huì)話(huà)。當(dāng)執(zhí)行查詢(xún)時(shí),返回查詢(xún)到的結(jié)果集。程序可以通過(guò)操作該對(duì)象來(lái)取出查詢(xún)結(jié)果。 JDBC基礎(chǔ) JDBC的全稱(chēng)是Java Database Connectivity,即Java數(shù)據(jù)庫(kù)連接,它是一種可以執(zhí)行SQL語(yǔ)句的Java API。...

    鄒強(qiáng) 評(píng)論0 收藏0
  • 通過(guò)項(xiàng)目逐步深入了解Mybatis<一>

    摘要:解決方法使用數(shù)據(jù)庫(kù)連接池管理數(shù)據(jù)庫(kù)連接。向中設(shè)置參數(shù),對(duì)占位符號(hào)位置和設(shè)置參數(shù)值,硬編碼在代碼中,同樣也不利于系統(tǒng)的維護(hù)。從中遍歷結(jié)果集數(shù)據(jù)時(shí),存在硬編碼,將獲取表的字段進(jìn)行硬編碼,不利于系統(tǒng)維護(hù)。 Mybatis Mybatis 和 SpringMVC 通過(guò)訂單商品案例驅(qū)動(dòng) 官方中文地址:http://www.mybatis.org/mybati... 官方托管地址:https://...

    2bdenny 評(píng)論0 收藏0
  • hibernate和jdbc的淵源

    摘要:同時(shí),我們將語(yǔ)句預(yù)編譯在中,這個(gè)類(lèi)可以使用占位符,避免注入,當(dāng)然,后面說(shuō)到的的占位符的原理也是這樣,同時(shí),的占位符原理也是如此。的底層封裝了,比如說(shuō)為了防止注入,一般會(huì)有占位符,也會(huì)有響應(yīng)的占位符。 介紹jdbc 我們學(xué)習(xí)Java數(shù)據(jù)庫(kù)操作時(shí),一般會(huì)設(shè)計(jì)到j(luò)dbc的操作,這是一位程序員最基本的素養(yǎng)。jdbc以其優(yōu)美的代碼和高性能,將瞬時(shí)態(tài)的javabean對(duì)象轉(zhuǎn)化為持久態(tài)的SQL數(shù)據(jù)。...

    includecmath 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<