`
Donald_Draper
  • 浏览: 980175 次
社区版块
存档分类
最新评论

MySQL ServerPreparedStatement查询

    博客分类:
  • JDBC
阅读更多
JDBC驱动初始化-Mysql:http://donald-draper.iteye.com/blog/2342010
JDBC连接的获取:http://donald-draper.iteye.com/blog/2342011
Mysql负载均衡连接的获取:http://donald-draper.iteye.com/blog/2342089
Mysql主从复制读写分离连接的获取:http://donald-draper.iteye.com/blog/2342108
ConnectionImp创建MysqlIO :http://donald-draper.iteye.com/blog/2342959
Mysql预编译SQL:http://donald-draper.iteye.com/blog/2342960
MysqlSQL PreparedStatement的查询:http://donald-draper.iteye.com/blog/2343083
MySQL ServerPreparedStatement查询:http://donald-draper.iteye.com/blog/2343124
再前面说过PreparedStatement的查询,今天看一下ServerPreparedStatement的查询,
这篇文章要结合PreparedStatement的查询来理解。
//ServerPreparedStatement执行查询的时候,调用的是PreparedStatement的查询方法
//ServerPreparedStatement
 public ResultSet executeQuery()
        throws SQLException
    {
        checkClosed();
        ConnectionImpl locallyScopedConn = connection;
        checkForDml(originalSql, firstCharOfStmt);
        CachedResultSetMetaData cachedMetadata = null;
        synchronized(locallyScopedConn.getMutex())
        {
            if(locallyScopedConn.useMaxRows())
            {
                if(hasLimitClause)
                {
		    //没有分页语句的查询
                    results = executeInternal(maxRows, sendPacket, createStreamingResultSet(), true, metadataFromCache, false);
                } else
                {
                    if(maxRows <= 0)
                        executeSimpleNonQuery(locallyScopedConn, "SET OPTION SQL_SELECT_LIMIT=DEFAULT");
                    else
                        executeSimpleNonQuery(locallyScopedConn, "SET OPTION SQL_SELECT_LIMIT=" + maxRows);
                    results = executeInternal(-1, sendPacket, doStreaming, true, metadataFromCache, false);
                    if(oldCatalog != null)
                        connection.setCatalog(oldCatalog);
                }
            } else
            {
                results = executeInternal(-1, sendPacket, doStreaming, true, metadataFromCache, false);
            }
        }
        return results;
    }

executeInternal此方法在PreparedStatement有实现,由于ServerPreparedStatement继承
PreparedStatement,重写了这个方法,我们来看ServerPreparedStatement的这个方法
public class ServerPreparedStatement extends com.mysql.jdbc.PreparedStatement
{
    //执行查询,返回查询结果集
 protected ResultSetInternalMethods executeInternal(int maxRowsToRetrieve, Buffer sendPacket, boolean createStreamingResultSet, boolean queryIsSelectOnly, Field metadataFromCache[], boolean isBatch)
        throws SQLException
    {
        numberOfExecutions++;
	//委托给serverExecute方法
        return serverExecute(maxRowsToRetrieve, createStreamingResultSet, metadataFromCache);  
     }
}

//ServerPreparedStatement查询
private ResultSetInternalMethods serverExecute(int maxRowsToRetrieve, boolean createStreamingResultSet, Field metadataFromCache[])
        throws SQLException
    {
       //获取互斥锁
        Object obj = connection.getMutex();
        JVM INSTR monitorenter ;
        MysqlIO mysql;
        Buffer packet;
        long begin;
        boolean logSlowQueries;
        boolean gatherPerformanceMetrics;
        StatementImpl.CancelTask timeoutTask;
	//从连接获取MysqlIO
        mysql = connection.getIO();
	//从MysqlIO获取查询包
        packet = mysql.getSharedSendPacket();
        packet.clear();
        packet.writeByte((byte)23);
        packet.writeLong(serverStatementId);
        boolean usingCursor = false;
        if(connection.versionMeetsMinimum(4, 1, 2))
        {
            if(resultFields != null && connection.isCursorFetchEnabled() && getResultSetType() == 1003 && getResultSetConcurrency() == 1007 && getFetchSize() > 0)
            {
                packet.writeByte((byte)1);
                usingCursor = true;
            } else
            {
                packet.writeByte((byte)0);
            }
            packet.writeLong(1L);
        }
        int nullCount = (parameterCount + 7) / 8;
        int nullBitsPosition = packet.getPosition();
        for(int i = 0; i < nullCount; i++)
            packet.writeByte((byte)0);

        byte nullBitsBuffer[] = new byte[nullCount];
        packet.writeByte(((byte)(sendTypesToServer ? 1 : 0)));
        if(sendTypesToServer)
        {
            for(int i = 0; i < parameterCount; i++)
                packet.writeInt(parameterBindings[i].bufferType);

        }
        for(int i = 0; i < parameterCount; i++)
        {
            if(parameterBindings[i].isLongData)
                continue;
            if(!parameterBindings[i].isNull)
                storeBinding(packet, parameterBindings[i], mysql);
            else
                nullBitsBuffer[i / 8] |= 1 << (i & 7);
        }

        int endPosition = packet.getPosition();
        packet.setPosition(nullBitsPosition);
        packet.writeBytesNoNull(nullBitsBuffer);
        packet.setPosition(endPosition);
        begin = 0L;
        logSlowQueries = connection.getLogSlowQueries();
        gatherPerformanceMetrics = connection.getGatherPerformanceMetrics();
        if(profileSQL || logSlowQueries || gatherPerformanceMetrics)
            begin = mysql.getCurrentTimeNanosOrMillis();
        resetCancelledState();
        timeoutTask = null;
        ResultSetInternalMethods resultsetinternalmethods;
        if(connection.getEnableQueryTimeouts() && timeoutInMillis != 0 && connection.versionMeetsMinimum(5, 0, 0))
        {
	    //如果启动延时查询,创建延时查询TimeTask,并通过ConnectionImpl的CancelTimer(Timer)去调度
            timeoutTask = new StatementImpl.CancelTask(this, this);
            connection;
            ConnectionImpl.getCancelTimer().schedule(timeoutTask, timeoutInMillis);
        }
	//MysqlIO向Server发送查询命令
        Buffer resultPacket = mysql.sendCommand(23, null, packet, false, null, 0);
        long queryEndTime = 0L;
        if(logSlowQueries || gatherPerformanceMetrics || profileSQL)
            queryEndTime = mysql.getCurrentTimeNanosOrMillis();
        if(timeoutTask != null)
        {
            timeoutTask.cancel();
            if(timeoutTask.caughtWhileCancelling != null)
                throw timeoutTask.caughtWhileCancelling;
            timeoutTask = null;
        }
        synchronized(cancelTimeoutMutex)
        {
            if(wasCancelled)
            {
                SQLException cause = null;
                if(wasCancelledByTimeout)
                    cause = new MySQLTimeoutException();
                else
                    cause = new MySQLStatementCancelledException();
                resetCancelledState();
                throw cause;
            }
        }
	//转化结果集,这个我们在PreparedStatement,看过,这里就不说了
        ResultSetInternalMethods rs = mysql.readAllResults(this, maxRowsToRetrieve, resultSetType, resultSetConcurrency, createStreamingResultSet, currentCatalog, resultPacket, true, fieldCount, metadataFromCache);       
        return resultsetinternalmethods;
}

总结:
ServerPreparedStatement的查询与PreparedStatement的思想基本上一直的都是首先组装查询包,并通MysqlIO将包发送到Server,Server返回查询结果,MysqlIO将返回结果转换为ResultSetInternalMethods(ResultSetImpl),即ResultSet。
分享到:
评论

相关推荐

    sql查询优化(提高MySQL数据库查询效率的几个技巧)

    SQL 查询优化(提高 MySQL 数据库查询效率的几个技巧) 在 MySQL 数据库中,查询优化是一个非常重要的方面。在实际应用中,高效的查询可以提高整个系统的性能和响应速度。下面我们将介绍几个提高 MySQL 数据库查询...

    mysql 树形结构查询

    mysql 树形结构查询 MySQL 树形结构查询是指使用存储过程来实现 MySQL 数据库中的树形结构查询。这种查询方式可以高效地查询树形结构的数据,并且可以根据需要设置递归深度。 MySQL 中的树形结构查询可以使用存储...

    关系型数据库+Mysql+查询用户连续登陆天数+数据统计

    关系型数据库+Mysql+查询用户连续登陆天数+数据统计 关系型数据库+Mysql+查询用户连续登陆天数+数据统计 关系型数据库+Mysql+查询用户连续登陆天数+数据统计 关系型数据库+Mysql+查询用户连续登陆天数+数据统计 关系...

    MySQL递归查询

    MySQL 递归查询实现方法 MySQL 递归查询是指在 MySQL 中实现类似 Oracle Hierarchical Queries 的功能,用于查询树形结构中的所有子节点。由于 MySQL 目前还没有内置的递归查询功能,因此需要使用其他方法来实现。 ...

    MySQL数据库查询优化

    第3课 查询优化技术理论与MySQL实践(一)------子查询的优化(一) 第4课 查询优化技术理论与MySQL实践(二)------子查询的优化(二) 从理论看,子查询包括的内容和范围,建立清晰的概念 从实践看,MySQL的子查询...

    Mysql查询流程分析

    ### MySQL查询流程分析 在深入理解MySQL查询流程之前,我们首先需要明确几个基本概念:MySQL是一种关系型数据库管理系统,它支持SQL(Structured Query Language)语言,用于管理存储在表格中的数据。MySQL查询流程...

    mysql数据查询操作-实验训练2.docx

    本实验训练涵盖了 MySQL 数据查询操作的多个方面,包括单表查询、多条件查询、聚合函数查询、内连接查询、外连接查询、复合查询等。通过对实验内容的分析,可以总结出以下知识点: 1. 单表查询: * 了解如何使用 ...

    C#下的mysql数据库查询显示

    本资源针对的是在C#环境下进行MySQL数据库查询的基础教程,特别适合初学者学习。 首先,我们要理解C#与MySQL的结合是如何工作的。在C#应用中,我们需要一个连接MySQL的驱动,如`MySql.Data.MySqlClient`库,这个库...

    使用Python将Mysql的查询数据导出到文件的方法

    mysql官方提供了很多种connector,其中包括python的connector。 下载地址在:http://dev.mysql.com/downloads/connector/python/  直接安装即可。 在python中: 1. 连接: import mysql.connector ...2. 查询:

    数据库查询指令:mysql查询语句汇总+编程知识+技术开发

    mysql查询语句汇总,数据库查询指令:mysql查询语句汇总+编程知识+技术开发;mysql查询语句汇总,数据库查询指令:mysql查询语句汇总+编程知识+技术开发;mysql查询语句汇总,数据库查询指令:mysql查询语句汇总+...

    MySQL查询把多列返回结果集拼装成一个字段

    mysql中有种可以通过join相关操作进行表与表之间的方式查询不同结果集,但是在一对多的情况下,关键查询的结果是多条的.例如:班级和学习的关系,我想很直观的看到班级和学生的情况,列表显示出班级的信息和班级的男生...

    JDBC-MySQL分页查询

    本教程将深入探讨如何使用JDBC和MySQL实现分页查询。 首先,我们需要理解分页的基本概念。分页是将大型数据集分割成较小、更易管理的部分,通常每页包含一定数量的记录。在Web应用中,这通常通过设置“每页条目数”...

    mysql对省市县的查询.sql

    mysql对省市县的查询

    MySql常用查询命令操作大全

    MySQL是一种广泛使用的开源关系型数据库管理系统,其丰富的查询命令使得数据操作变得简单高效。以下是一些MySQL中的常用查询命令操作: 1. **查看版本信息**: - `mysql&gt; select version();` 可以用来查看MySQL...

    Mysql多表联合查询

    MySql,多表联合查询加AS语句,多余的就不说了,自己看,绝对简单!

    0.3 MySQL基础查询、分页查询

    MySQL基础查询、分页查询 本文将对 MySQL 基础查询、分页查询进行详细的介绍,并提供相关的知识点。 MySQL 基础查询 MySQL 基础查询是指使用 SELECT 语句来从数据库中检索数据的过程。SELECT 语句是 MySQL 中最...

    45-MySQL单表2000万数据查询慢解决方案1

    MySQL单表2000万数据查询慢解决方案1 本文主要讨论了如何解决MySQL单表2000万数据查询慢的问题,通过将表分区和使用时间触发器来实现数据的优化。 分区设计 在解决方案中,我们使用的是按照8周将单表分为8个区,...

    MySQL查询语句汇总+编程知识+开发技术

    MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询语句汇总+编程知识+开发技术; MySQL查询...

    mysql查询分析器

    MySQL查询分析器是一种强大的工具,专门用于帮助数据库管理员和开发人员高效地管理和操作MySQL数据库。SQLYog Enterprise绿色版是其中的一款,它提供了一个直观且功能丰富的界面,使得执行SQL查询、管理数据库对象...

Global site tag (gtag.js) - Google Analytics