主要是经常碰到一些 JDBC 参数问题,但又不熟,需要测试,所以记录下这个示例,方便测试。另外在示例后有两个关于 useCursorFetch 参数的问题总结。

JDBC相关概念

JDBC
Java Database Connectivity,即 Java 编程语言访问数据库的标准接口,是一个规范而不是一个实现

MySQL Connector/J
这是 MySQL 按照 JDBC 标准提供给 Java 程序连接 MySQL 的驱动,这是一个具体实现

JDBC 连接池
MySQL Connector/J 是不能单独提供连接池功能的,需要与第三方库一起才能实现连接池的功能。Java 语言中常用的数据库连接池有:

  • Druid
  • BoneCP
  • DBCP
  • C3P0
  • Proxool
  • JBoss
  • Tomcat-Jdbc

Druid 的文档中有一些数据库连接池之间的横向比较:https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98

示例

  1. 安装 jdk
rpm -ivh jdk-8u171-linux-x64.rpm
  1. 下载 Java MySQL 连接器
    mysql-connector-java-5.1.48

  2. 写一段 Java 代码

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

public class test3{
    public static void main(String[] args) throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/hucq?useCursorFetch=true", "hucq", "hucq");
        PreparedStatement sql1 = con.prepareStatement("select a from t5 where id=? and a=?;");
        sql1.setInt(1,2);
        sql1.setInt(2,2);
        System.out.println("Executing query...");
        ResultSet rs = sql1.executeQuery();
        while (rs.next()) {
            System.out.println(rs.getDouble(1) );
            }
        rs.close();
        sql1.close();
        con.close();
    }
}
  1. 编译
javac test3.java
  1. 运行 Java 程序
java -cp $CLASSPATH:/data/java_test/mysql-connector-java-5.1.48.jar test3

useCursorFetch 的影响

  1. useCursorFetch=false 导致精度丢失

useCursorFetch=true 会默认设置 useServerPrepStmts=true,而 useServerPrepStmts=true 和 binary protocol 是一回事。如果 useServerPrepStmts=false,则使用 text protocol,对于float字段,text protocol 的精度比 binary protocol要低,会导致精度丢失。

应该使用规范的数据类型,在 MySQL 中 double、float 数据类型都是不精确的,应该使用 decimal。

  1. useServerPrepStmts=true 导致带变量的 SQL不会记录到 ps.events_statements_summary_by_digest

通过一系列测试,发现其实跟 useCursorFetch 无直接关系,只与 useServerPrepStmts 参数有关:
useServerPrepStmts=true 时,确实带变量的 SQL不会记录到ps.events_statements_summary_by_digest
useCursorFetch 与 useServerPrepStmts 的关系是:
useCursorFetch=true,会默认设置 useServerPrepStmts=true

可以看这篇文章:https://cloud.tencent.com/developer/news/330350
目前官方已确认这是个 bug :https://bugs.mysql.com/bug.php?id=97496

文章来源于互联网:Linux上 Java 连接 MySQL 示例

发表评论