最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文說(shuō)透什么是MySQL的預(yù)編譯

 更新時(shí)間:2022年11月15日 11:35:02   作者:緑水長(zhǎng)流*z  
這篇文章主要介紹了一文說(shuō)透什么是MySQL的預(yù)編譯,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

一、什么是MySQL的預(yù)編譯?

通常我們發(fā)送一條SQL語(yǔ)句給MySQL服務(wù)器時(shí),MySQL服務(wù)器每次都需要對(duì)這條SQL語(yǔ)句進(jìn)行校驗(yàn)、解析等操作。

但是有很多情況下,我們的一條SQL語(yǔ)句可能需要反復(fù)的執(zhí)行,而SQL語(yǔ)句也只可能傳遞的參數(shù)不一樣,類似于這樣的SQL語(yǔ)句如果每次都需要進(jìn)行校驗(yàn)、解析等操作,未免太過(guò)于浪費(fèi)性能了,因此我們提出了SQL語(yǔ)句的預(yù)編譯。

所謂預(yù)編譯就是將一些靈活的參數(shù)值以占位符?的形式給代替掉,我們把參數(shù)值給抽取出來(lái),把SQL語(yǔ)句進(jìn)行模板化。

讓MySQL服務(wù)器執(zhí)行相同的SQL語(yǔ)句時(shí),不需要在校驗(yàn)、解析SQL語(yǔ)句上面花費(fèi)重復(fù)的時(shí)間

預(yù)編譯其實(shí)就是來(lái)提高我們的查詢速度的,并不是大家心里想的那個(gè)"預(yù)編譯"

二、 如何使用預(yù)編譯?

2.1 MySQL預(yù)編譯的語(yǔ)法

準(zhǔn)備數(shù)據(jù):

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用戶名稱',
  `birthday` datetime(0) NULL DEFAULT NULL COMMENT '生日',
  `sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '性別',
  `address` varchar(256) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '地址',
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '小龍', '2019-02-27 17:47:08', '男', '南昌市西湖區(qū)');
INSERT INTO `user` VALUES (2, '小剛', '2019-03-02 15:09:37', '男', '南昌市東湖區(qū)');
INSERT INTO `user` VALUES (3, '小蘭', '2019-03-04 11:34:34', '女', '南昌市青山湖區(qū)');
INSERT INTO `user` VALUES (4, '小紅', '2019-03-04 12:04:06', '女', '南昌市青云譜區(qū)');
INSERT INTO `user` VALUES (5, '小麗', '2019-03-07 17:37:26', '女', '南昌市紅谷灘區(qū)');
INSERT INTO `user` VALUES (6, '小明', '2019-03-08 11:44:00', '男', '南昌市新建區(qū)');
INSERT INTO `user` VALUES (7, '龍龍', '2019-04-08 11:44:00', '男', '南昌市西湖區(qū)');

定義預(yù)編譯SQL語(yǔ)句:

-- 定義一個(gè)預(yù)編譯語(yǔ)句
prepare name from statement; 

prepare statement_1 from 'select * from user where id=?';

設(shè)置參數(shù)值:

set @id=1;

執(zhí)行預(yù)編譯SQL語(yǔ)句:

execute statement_1 using @id;

釋放預(yù)編譯SQL語(yǔ)句:

deallocate prepare statement_1;

三、使用PreparedStatement進(jìn)行預(yù)編譯

3.1 開(kāi)啟查詢?nèi)罩?/h3>

為了方便測(cè)試,我們打開(kāi)MySQL的查詢?nèi)罩荆?/p>

在MySQL配置文件中的[mysqld]下增加如下配置:

# 是否開(kāi)啟mysql日志  0:關(guān)閉(默認(rèn)值) 1:開(kāi)啟
general-log=1

# mysql 日志的存放位置
general_log_file="D:/query.log"

2)重啟MySQL服務(wù)(要以管理員身份運(yùn)行):

net stop mysql

net start mysql

3.2 開(kāi)啟預(yù)編譯功能

PreparedStatement的預(yù)編譯功能默認(rèn)是關(guān)閉的,要讓其生效,必須在JDBC連接的URL設(shè)置useServerPrepStmts=true,讓其打開(kāi)。

如下所示:

jdbc:mysql://localhost:3306/mybatis?&useServerPrepStmts=true

測(cè)試代碼:

package com.lscl.test;
import org.junit.Test;
import java.sql.*;

public class Demo01 {
    @Test
    public void test1() throws Exception {

        // 獲取連接
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true", "root", "admin");

        String sql = "select * from user where id = ?";

        PreparedStatement ps = connection.prepareStatement(sql);

        ps.setInt(1, 1);

        // 執(zhí)行查詢,獲取結(jié)果集
        ResultSet rs = ps.executeQuery();

        //遍歷查詢結(jié)果集
        while (rs.next()) {
            System.out.println(rs.getObject("id")+"---"+rs.getObject("username"));
        }
        rs.close();
        ps.close();

    }
}

查看MySQL的查詢?nèi)罩荆?/p>

我們?cè)O(shè)置的是MySQL連接參數(shù),目的是告訴MySQL JDBC的PreparedStatement使用預(yù)編譯功能(5.0.5之后的JDBC驅(qū)動(dòng)版本需要手動(dòng)開(kāi)啟,而之前的默認(rèn)是開(kāi)啟的)

3.3 cachePrepStmts參數(shù)

當(dāng)使用不同的PreparedStatement對(duì)象來(lái)執(zhí)行相同的SQL語(yǔ)句時(shí),還是會(huì)出現(xiàn)編譯兩次的現(xiàn)象,我們可以開(kāi)啟"預(yù)編譯緩存",來(lái)實(shí)現(xiàn)"一次編譯,到處運(yùn)行"(要是同一個(gè)Connection)

開(kāi)啟預(yù)編譯緩存:cachePrepStmts=true;

url連接:

jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true&cachePrepStmts=true

測(cè)試代碼(沒(méi)有開(kāi)啟緩存):

@Test
public void test1() throws Exception {

    // 獲取連接
//        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true&cachePrepStmts=true", "root", "admin");
    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true", "root", "admin");

    String sql = "select * from user where id = ?";

    PreparedStatement ps = connection.prepareStatement(sql);

    ps.setInt(1, 1);

    // 執(zhí)行查詢,獲取結(jié)果集
    ResultSet rs = ps.executeQuery();

    //遍歷查詢結(jié)果集
    while (rs.next()) {
        System.out.println(rs.getObject("id")+"---"+rs.getObject("username"));
    }

    // 關(guān)閉對(duì)象連接
    rs.close();
    ps.close();

    ps = connection.prepareStatement(sql);

    ps.setInt(1, 1);

    // 執(zhí)行查詢,獲取結(jié)果集
    rs = ps.executeQuery();

    //遍歷查詢結(jié)果集
    while (rs.next()) {
        System.out.println(rs.getObject("id")+"---"+rs.getObject("username"));
    }

    rs.close();
    ps.close();

}

查看查詢?nèi)罩荆?/p>

開(kāi)啟預(yù)編譯緩存測(cè)試(在url連接上加上cachePrepStmts=true):

jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true&cachePrepStmts=true

四、Statement是否具備預(yù)編譯功能?

Statement不具備預(yù)編譯功能

測(cè)試代碼:

@Test
public void test2() throws Exception {

    // 獲取連接
    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useServerPrepStmts=true&cachePrepStmts=true", "root", "admin");

    String sql = "select * from user where id = 1";

    Statement statement = connection.createStatement();

    // 執(zhí)行查詢,獲取結(jié)果集
    ResultSet rs = statement.executeQuery(sql);

    //遍歷查詢結(jié)果集
    while (rs.next()) {
        System.out.println(rs.getObject("id")+"---"+rs.getObject("username"));
    }

    rs.close();
    statement.close();
}

查看MySQL查詢?nèi)罩荆?/p>

五、總結(jié)

1)到了這里,大家應(yīng)該知道什么是預(yù)編譯了,預(yù)編譯是用來(lái)提升SQL語(yǔ)句的響應(yīng)速度的,將一段SQL語(yǔ)句定制成模板,把靈活的參數(shù)作為占位符讓我們傳遞進(jìn)去,達(dá)到多次執(zhí)行相同的SQL語(yǔ)句必須要重復(fù)校驗(yàn)、解析等操作;

2)默認(rèn)的情況下,PreparedStatement是沒(méi)有開(kāi)啟預(yù)編譯的,需要我們?cè)谶B接的url參數(shù)上指定useServerPrepStmts=true參數(shù)開(kāi)啟,并且預(yù)編譯是支持"緩存"的,我們可以通過(guò)參數(shù)cachePrepStmts=true來(lái)設(shè)置;

3)statement是不支持預(yù)編譯的,即使設(shè)置了useServerPrepStmts=true也不管用;

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論

巩留县| 乾安县| 阜宁县| 布拖县| 南城县| 竹北市| 社旗县| 延安市| 阿城市| 扶风县| 葫芦岛市| 吉隆县| 青冈县| 理塘县| 鸡东县| 始兴县| 赤水市| 页游| 河曲县| 驻马店市| 晋宁县| 泸水县| 商南县| 会泽县| 兴化市| 木兰县| 达日县| 嵩明县| 大石桥市| 射阳县| 都兰县| 上高县| 康保县| 托克逊县| 虞城县| 五大连池市| 临洮县| 淮滨县| 舟曲县| 喀喇沁旗| 斗六市|