为什么这个简单的 JDBC/JOOQ 代码会创建 10 个到我的数据库的连接?
Why does this simple JDBC/JOOQ code creates 10 connections to my database?
我正在使用 SpringToolSuite 在本地环境中处理 spring 项目 运行。我正在使用 Putty 创建一个隧道来访问一个应用程序服务器,我可以从中查询我的 MySQL 数据库(我必须使用 SSH)。所以我 运行 这个简单的代码:
public static void getConnection() {
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
Personne personne = Personne.PERSONNE.as("personne");
Evenement evenement = Evenement.EVENEMENT.as("evenement");
Genealogie genealogie = Genealogie.GENEALOGIE.as("genealogie");
Lieu lieu = Lieu.LIEU.as("lieu");
Result<Record3<Integer,Integer,String>> result = create
.select(DSL.countDistinct(personne.ID).as("countRs"),
evenement.IDGROUPE2.as("group2Rs"),
lieu.LIBELLE.as("libelleRs"))
.from(evenement.innerJoin(personne)
.on(personne.ID.eq(evenement.IDPERS))
.innerJoin(genealogie)
.on(genealogie.ID.eq(personne.IDGEN))
.innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDGROUPE2)))
.where(personne._NOM.eq(" ")
.and((personne._PRENOM.eq(" ")
.or(personne._PRENOM.like(" -%"))))
.and(evenement.IDPERS.isNotNull())
.and(lieu.LIBELLE.isNotNull())
.and(genealogie.STATUS.ge(Byte.valueOf("1")))
.and(personne.CONTEMPORAIN.eq(Byte.valueOf("0"))))
.groupBy(evenement.IDGROUPE2)
.fetch();
System.out.println("countRs group2Rs libellesRs");
System.out.println("---------------------------");
for (Record r : result) {
System.out.println(r.get("countRs")+" "+r.get("group2Rs")+" "+r.get("libelleRs"));
}
try {
create.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
如您所见,它基本上只是打开与数据库的连接,进行查询并关闭 connection/query,没什么特别的。
但是当我使用 MySQL Workbench 检查客户端与我的数据库的连接时,我可以看到我的代码打开了 10 个连接:
如您所见,这些连接中只有一个正在实际执行查询。
关于 JOOQ 如何执行查询,有什么我不知道的吗?或者可能是因为我正在使用 Putty 访问我的远程服务器并且它以某种方式创建了许多连接?
由于您在项目中使用 HikariCP,因此不应使用 DriverManager
:
手动创建新连接
// Don't do this
connection = DriverManager.getConnection(url, user, password);
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
相反,使用 HikariCP 作为 DataSource
并将其传递给 jOOQ:
// Do this
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);
现在,您不必再进行任何资源管理,因为 jOOQ / Hikari 会在幕后为您做这件事(即没有 close()
调用)
我正在使用 SpringToolSuite 在本地环境中处理 spring 项目 运行。我正在使用 Putty 创建一个隧道来访问一个应用程序服务器,我可以从中查询我的 MySQL 数据库(我必须使用 SSH)。所以我 运行 这个简单的代码:
public static void getConnection() {
try {
connection = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
Personne personne = Personne.PERSONNE.as("personne");
Evenement evenement = Evenement.EVENEMENT.as("evenement");
Genealogie genealogie = Genealogie.GENEALOGIE.as("genealogie");
Lieu lieu = Lieu.LIEU.as("lieu");
Result<Record3<Integer,Integer,String>> result = create
.select(DSL.countDistinct(personne.ID).as("countRs"),
evenement.IDGROUPE2.as("group2Rs"),
lieu.LIBELLE.as("libelleRs"))
.from(evenement.innerJoin(personne)
.on(personne.ID.eq(evenement.IDPERS))
.innerJoin(genealogie)
.on(genealogie.ID.eq(personne.IDGEN))
.innerJoin(lieu)
.on(lieu.ID.eq(evenement.IDGROUPE2)))
.where(personne._NOM.eq(" ")
.and((personne._PRENOM.eq(" ")
.or(personne._PRENOM.like(" -%"))))
.and(evenement.IDPERS.isNotNull())
.and(lieu.LIBELLE.isNotNull())
.and(genealogie.STATUS.ge(Byte.valueOf("1")))
.and(personne.CONTEMPORAIN.eq(Byte.valueOf("0"))))
.groupBy(evenement.IDGROUPE2)
.fetch();
System.out.println("countRs group2Rs libellesRs");
System.out.println("---------------------------");
for (Record r : result) {
System.out.println(r.get("countRs")+" "+r.get("group2Rs")+" "+r.get("libelleRs"));
}
try {
create.close();
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
如您所见,它基本上只是打开与数据库的连接,进行查询并关闭 connection/query,没什么特别的。
但是当我使用 MySQL Workbench 检查客户端与我的数据库的连接时,我可以看到我的代码打开了 10 个连接:
如您所见,这些连接中只有一个正在实际执行查询。 关于 JOOQ 如何执行查询,有什么我不知道的吗?或者可能是因为我正在使用 Putty 访问我的远程服务器并且它以某种方式创建了许多连接?
由于您在项目中使用 HikariCP,因此不应使用 DriverManager
:
// Don't do this
connection = DriverManager.getConnection(url, user, password);
DSLContext create = DSL.using(connection, SQLDialect.MYSQL);
相反,使用 HikariCP 作为 DataSource
并将其传递给 jOOQ:
// Do this
DSLContext create = DSL.using(dataSource, SQLDialect.MYSQL);
现在,您不必再进行任何资源管理,因为 jOOQ / Hikari 会在幕后为您做这件事(即没有 close()
调用)