黄东旭关于基础软件产品价值的思考
808
2023-04-09
MySQL Java 教程
这是 MySQL 数据库的 Java 教程。 它涵盖了使用 JDBC 进行 Java 中 MySQL 编程的基础。
如果您需要重新了解 Java 语言,可以在上找到完整的Java 教程。
JDBC
_JDBC_ 是 Java 编程语言的 API,用于定义客户端如何访问数据库。 它提供了查询和更新数据库中数据的方法。 JDBC 面向关系数据库。 从技术角度来看,API 是 java.sql 包中的一组类。 要将 JDBC 与特定数据库一起使用,我们需要该数据库的 JDBC 驱动程序。
JDBC 是 Java 数据库编程的基石。 今天,它被认为是非常底层的,并且容易出错。 创建了诸如 MyBatis 或 JdbcTemplate 之类的解决方案来减轻 JDBC 编程的负担。 但是,实际上,这些解决方案仍然使用 JDBC。 JDBC 是 Java Standard Edition 平台的一部分。
JDBC 管理以下三个主要的编程活动:
连接到数据库;向数据库发送查询和更新语句;检索和处理从数据库接收到的结果以响应查询。
MySQL 连接器
为了以 Java 连接到 MySQL,MySQL 提供了 MySQL Connector / J,它是实现 JDBC API 的驱动程序。 MySQL Connector / J 是 JDBC Type 4 驱动程序。 Type 4 表示驱动程序是 MySQL 协议的纯 Java 实现,并且不依赖 MySQL 客户端库。 在本教程中,我们使用 MySQL Connector / J 5.1.41,它是 5.1 生产分支的维护版本。
连接字符串
使用连接字符串定义数据库连接。 它包含诸如数据库类型,数据库名称,服务器名称和端口号之类的信息。 它还可能包含用于配置的其他键/值对。 每个数据库都有其自己的连接字符串格式。
以下是 MySQL 连接字符串的语法:
jdbc:mysql://[host1][:port1][,[host2][:port2]]...[/[database]] [?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]
可以为服务器故障转移设置指定多个主机。 方括号中的项目是可选的。 如果未指定主机,则主机名默认为 localhost。 如果未指定主机端口,则默认为 MySQL 服务器的默认端口号 3306。
jdbc:mysql://localhost:3306/testdb?useSSL=false
这是一个 MySQL 连接字符串的示例。 jdbc:mysql://被称为子协议,对于 MySQL 来说是恒定的。 我们在 MySQL 标准端口 3306 上连接到localhost。数据库名称为testdb。 其他键/值对在问号字符(?)之后。 useSSL=false告诉 MySQL,将没有安全连接。
关于 MySQL 数据库
MySQL 是领先的开源数据库管理系统。 它是一个多用户,多线程的数据库管理系统。 MySQL 在网络上特别流行。 它是由 Linux,Apache,MySQL 和 PHP 组成的非常流行的 LAMP 平台的一部分。 目前,MySQL 由 *** 拥有。 在大多数重要的 OS 平台上都可以使用 MySQL 数据库。 它可以在 BSD Unix,Linux,Windows 或 Mac OS 上运行。 维基百科和 YouTube 使用 MySQL。 这些站点每天管理数百万个查询。 MySQL 有两个版本:MySQL 服务器系统和 MySQL 嵌入式系统。
设置 MySQL
在本节中,我们将安装 MySQL 服务器,创建testdb数据库和测试用户。
$ sudo apt-get install mysql-server
此命令将安装 MySQL 服务器和其他各种软件包。 在安装软件包时,提示我们输入 MySQL 根帐户的密码。
接下来,我们将创建一个新的数据库用户和一个新的数据库。 我们使用mysql客户端。
$ sudo service mysql statusmysql start/running, process 5129
我们检查 MySQL 服务器是否正在运行。 如果没有,我们需要启动服务器。 在 Ubuntu Linux 上,可以使用sudo service mysql start命令来完成。
我们使用 _mysql 监视器 _ 客户端应用连接到服务器。 我们使用根帐户连接到数据库。 我们用SHOW DATABASES语句显示所有可用的数据库。
mysql> CREATE DATABASE testdb;Query OK, 1 row affected (0.02 sec)
我们创建一个新的testdb数据库。 在整个教程中,我们将使用此数据库。
mysql> CREATE USER 'testuser'@'localhost' IDENTIFIED BY 'test623';Query OK, 0 rows affected (0.00 sec)mysql> USE testdb;Database changedmysql> GRANT ALL ON testdb.* TO 'testuser'@'localhost';Query OK, 0 rows affected (0.00 sec)mysql> quit;Bye
我们创建一个新的数据库用户。 我们为该用户授予 testdb 数据库所有表的所有特权。
Maven 文件
我们使用以下 Maven 文件:
pom.xml
POM 文件具有 MySQL 驱动程序的依赖关系。 我们还包括用于执行 Maven Java 程序的exec-maven-plugin。 在
Java MySQL 版本
如果以下程序运行正常,则我们已安装一切正常。 我们检查 MySQL 服务器的版本。
JdbcMySQLVersion.java
我们连接到数据库并获取有关 MySQL 服务器的一些信息。
String url = "jdbc:mysql://localhost:3306/testdb?useSSL=false";
这是 MySQL 数据库的连接 URL。 每个驱动程序对于 URL 都有不同的语法。 在本例中,我们提供了主机,端口和数据库名称。
try (Connection con = DriverManager.getConnection(url, user, password); Statement st = con.createStatement(); ResultSet rs = st.executeQuery(query)) {
我们使用连接 URL,用户名和密码建立与数据库的连接。 通过getConnection()方法建立连接。
连接对象的createStatement()方法创建一个Statement对象,用于将 SQL 语句发送到数据库。
连接对象的executeQuery()方法执行给定的 SQL 语句,该语句返回单个ResultSet对象。 ResultSet是由特定 SQL 语句返回的数据表。
try-with-resources语法可确保最终清除资源。
if (result.next()) { System.out.println(result.getString(1));}
ResultSet对象维护一个游标,该游标指向其当前数据行。 最初,光标位于第一行之前。 next()方法将光标移动到下一行。 如果没有剩余的行,则该方法返回false。 getString()方法检索指定列的值。 第一列的索引为 1。
} catch (SQLException ex) { Logger lgr = Logger.getLogger(JdbcMySQLVersion.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex);}
如果发生异常,我们将记录错误消息。 对于此控制台示例,该消息显示在终端中。
$ mvn exec:java -q5.7.21-0ubuntu0.16.04.1
我们从命令行运行程序。 Manen 的-q选项在安静模式下运行 Maven。 即我们只看到错误消息。
创建和填充表
接下来,我们将创建数据库表并用数据填充它们。 这些表将在本教程中使用。
mysql_tables.sql
USE testdb;DROP TABLE IF EXISTS Books, Authors, Testing, Images;CREATE TABLE Authors(Id BIGINT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(100));CREATE TABLE Books(Id BIGINT PRIMARY KEY AUTO_INCREMENT, AuthorId BIGINT, Title VARCHAR(100), FOREIGN KEY(AuthorId) REFERENCES Authors(Id) ON DELETE CASCADE);CREATE TABLE Testing(Id INT);CREATE TABLE Images(Id INT PRIMARY KEY AUTO_INCREMENT, Data MEDIUMBLOB);INSERT INTO Authors(Id, Name) VALUES(1, 'Jack London');INSERT INTO Authors(Id, Name) VALUES(2, 'Honore de Balzac');INSERT INTO Authors(Id, Name) VALUES(3, 'Lion Feuchtwanger');INSERT INTO Authors(Id, Name) VALUES(4, 'Emile Zola');INSERT INTO Authors(Id, Name) VALUES(5, 'Truman Capote');INSERT INTO Books(Id, AuthorId, Title) VALUES(1, 1, 'Call of the Wild');INSERT INTO Books(Id, AuthorId, Title) VALUES(2, 1, 'Martin Eden');INSERT INTO Books(Id, AuthorId, Title) VALUES(3, 2, 'Old Goriot');INSERT INTO Books(Id, AuthorId, Title) VALUES(4, 2, 'Cousin Bette');INSERT INTO Books(Id, AuthorId, Title) VALUES(5, 3, 'Jew Suess');INSERT INTO Books(Id, AuthorId, Title) VALUES(6, 4, 'Nana');INSERT INTO Books(Id, AuthorId, Title) VALUES(7, 4, 'The Belly of Paris');INSERT INTO Books(Id, AuthorId, Title) VALUES(8, 5, 'In Cold blood');INSERT INTO Books(Id, AuthorId, Title) VALUES(9, 5, 'Breakfast at Tiffany');
SQL 命令创建四个数据库表:Authors,Books,Testing和Images。 这些表是 InnoDB 类型的。 InnoDB 数据库支持外键约束和事务。 我们将外键约束放置在Books表的AuthorId列上。 我们用初始数据填充Authors和Books表。
mysql> source mysql_tables.sqlQuery OK, 0 rows affected (0.07 sec)Query OK, 0 rows affected (0.12 sec)Query OK, 1 row affected (0.04 sec)...
我们使用source命令执行tables.sql脚本。
Java MySQL 预备语句
现在,我们将以预备语句来关注自己。 在编写预备语句时,我们使用占位符,而不是直接将值写入语句中。 预准备的语句可提高安全性和性能。
在 Java 中,PreparedStatement是代表预编译的 SQL 语句的对象。
JdbcPrepared.java
我们将新作者添加到Authors表中。
try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement(sql)) {
在这里,我们创建一个预备语句。 在编写预备语句时,我们使用占位符,而不是直接将值写入语句中。 预备语句更快,并且可以防止 SQL 注入攻击。 ?是一个占位符,稍后将被填充。
pst.setString(1, author);
值绑定到占位符。
pst.executeUpdate();
执行预备语句。 当我们不希望返回任何数据时,我们使用语句对象的executeUpdate()方法。 这是当我们创建数据库或执行INSERT,UPDATE,DELETE语句时。
$ mvn exec:java -qA new author has been insertedmysql> select * from Authors;+----+--------------------+| Id | Name |+----+--------------------+| 1 | Jack London || 2 | Honore de Balzac || 3 | Lion Feuchtwanger || 4 | Emile Zola || 5 | Truman Capote || 6 | Trygve Gulbranssen |+----+--------------------+6 rows in set (0.00 sec)
我们在表中插入了一位新作者。
测试 MySQL 预备和非预备的语句
对于以下两个示例,我们将使用“测试”表。 我们将执行一条普通语句和一条准备语句 5000 次。 我们检查执行时间是否有差异。
JdbcNotPreparedTesting.java
第一个示例使用普通的Statement对象。
for (int i = 1; i <= 5000; i++) { String sql = "INSERT INTO Testing(Id) VALUES(" + 2 * i + ")"; st.executeUpdate(sql);}
我们建立查询并执行 5000 次。
$ time mvn exec:java -qreal 4m14.716suser 0m6.820ssys 0m0.404s
完成 5000 次插入需要 4.14 分钟。
JdbcPreparedTesting.java
现在,我们使用PreparedStatement执行相同的任务。
try (Connection con = DriverManager.getConnection(cs, user, password); PreparedStatement pst = con.prepareStatement(sql)) {
我们使用prepareStatement()方法创建预备语句。
for (int i = 1; i <= 5000; i++) { pst.setInt(1, i * 2); pst.executeUpdate();}
我们将一个值绑定到预备语句,并在循环中执行数千次。
$ time mvn exec:java -qreal 3m53.962suser 0m6.280ssys 0m0.380s
现在花了 3.53 分钟完成了 5000 次插入。 我们节省了 20 秒。
Java MySQL 检索数据
接下来,我们将展示如何从数据库表中检索数据。 我们从Authors表中获取所有数据。
JdbcRetrieve.java
我们从Authors表中获取所有作者并将其打印到控制台。
String query = "SELECT * FROM Authors";try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement(query); ResultSet rs = pst.executeQuery()) {
我们执行一个查询,该查询从Authors表中选择所有列。 我们使用executeQuery()方法。 该方法执行给定的 SQL 语句,该语句返回单个ResultSet对象。 ResultSet是 SQL 查询返回的数据表。
while (rs.next()) { System.out.print(rs.getInt(1)); System.out.print(": "); System.out.println(rs.getString(2));}
next()方法将光标移至下一条记录。 当结果集中没有更多行时,它将返回false。 getInt()和getString()方法检索此ResultSet对象当前行中指定列的值,作为 Java 编程语言的int和String。
$ mvn exec:java -q1: Jack London2: Honore de Balzac3: Lion Feuchtwanger4: Emile Zola5: Truman Capote6: Trygve Gulbranssen
我们执行程序; 我们在控制台上印有作者的 ID 和姓名。
属性
通常的做法是将配置数据放在程序外部的单独文件中。 这样程序员可以更加灵活。 我们可以更改用户,密码或连接 URL,而无需重新编译程序。 它在需要大量测试,调试,保护数据等的动态环境中特别有用。
在 Java 中,Properties是为此经常使用的类。 该类用于轻松读取和保存键/值属性。
db.properties
db.url=jdbc:mysql://localhost:3306/testdb?useSSL=falsedb.user=testuserdb.passwd=test623
我们有一个db.properties文件,其中有三个键/值对。 这些是在程序执行期间动态加载的。
JdbcProperties.java
我们连接到 testdb 数据库,并将Authors表的内容打印到控制台。 这次,我们从文件加载连接属性。 他们没有在程序中硬编码。
Properties props = new Properties();String fileName = "src/main/resources/db.properties";try (FileInputStream in = new FileInputStream(fileName)) { props.load(in);} catch (IOException ex) { Logger lgr = Logger.getLogger(JdbcProperties.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex);}
创建Properties类。 数据是从名为db.properties的文件中加载的,其中包含我们的配置数据。
String url = props.getProperty("db.url");String user = props.getProperty("db.user");String passwd = props.getProperty("db.passwd");
使用getProperty()方法检索这些值。
Java MySQL 数据源
在此示例中,我们使用数据源连接到数据库。 数据源的使用可以提高应用的性能和可伸缩性。 与DriverManager相比,使用数据源具有多个优点:增强了可移植性,连接池和分布式事务。
MysqlDataSource是用于创建数据源的类。
db.properties
是 MySQL 数据库的属性。
ComLineDSEx.java
在此示例中,我们使用数据源连接到数据库。
String fileName = "src/main/resources/db.properties";try (FileInputStream fis = new FileInputStream(fileName)) { props.load(fis);} catch (IOException ex) { Logger lgr = Logger.getLogger(ComLineDSEx.class.getName()); lgr.log(Level.SEVERE, ex.getMessage(), ex);}
从db.properties文件中读取数据库属性。
MysqlDataSource ds = new MysqlDataSource();ds.setURL(props.getProperty("mysql.url"));ds.setUser(props.getProperty("mysql.username"));ds.setPassword(props.getProperty("mysql.password"));
创建MysqlDataSource并设置数据源属性。
try (Connection con = ds.getConnection(); PreparedStatement pst = con.prepareStatement(query); ResultSet rs = pst.executeQuery()) {
连接对象是从数据源创建的。
Java MySQL 多条语句
可以在一个查询中执行多个 SQL 语句。 必须将allowMultiQueries设置为启用 MySQL 中的多个语句。
JdbcMulStat.java
在代码示例中,我们从Authors表中检索三行。 我们使用三个SELECT语句来获取三行。
String cs = "jdbc:mysql://localhost:3306/" + "testdb?allowMultiQueries=true&useSSL=false";
通过将allowMultiQueries参数设置为 true,我们可以在数据库 URL 中启用多个语句查询。
String query = "SELECT Id, Name FROM Authors WHERE Id=1;" + "SELECT Id, Name FROM Authors WHERE Id=2;" + "SELECT Id, Name FROM Authors WHERE Id=3";
在这里,我们有一个包含多个语句的查询。 语句用分号分隔。
boolean isResult = pst.execute();
我们调用已预备语句对象的execute()方法。 该方法返回一个布尔值,该布尔值指示第一个结果是否为ResultSet对象。 使用getMoreResults()方法调用后续结果。
do { try (ResultSet rs = pst.getResultSet()) { while (rs.next()) { System.out.print(rs.getInt(1)); System.out.print(": "); System.out.println(rs.getString(2)); } isResult = pst.getMoreResults(); }} while (isResult);
结果的处理在do while循环内完成。 通过getResultSet()方法调用检索ResultSet。 为了找出是否还有其他结果,我们调用getMoreResults()方法。
$ mvn exec:java -q1: Jack London2: Honore de Balzac3: Lion Feuchtwanger
这是示例的输出。 前三行是从Authors表中检索的。
Java MySQL 列标题
下面的示例显示如何使用数据库表中的数据打印列标题。 我们将列名称称为 MetaData。 元数据是有关数据库中核心数据的数据。
JdbcColumnHeaders.java
在此程序中,我们从Authors表中选择作者,并从Books表中选择他们的书。 我们打印结果集中返回的列的名称。 输出已格式化。
String query = "SELECT Name, Title From Authors, " + "Books WHERE Authors.Id=Books.AuthorId";
这是将作者与他们的书联系在一起的 SQL 语句。
ResultSetMetaData meta = rs.getMetaData();
要获取列名,我们需要获取ResultSetMetaData。 它是一个对象,可用于获取有关ResultSet对象中列的类型和属性的信息。
String colname1 = meta.getColumnName(1);String colname2 = meta.getColumnName(2);
从获得的元数据中,我们获得列名。
String header = String.format("%-21s%s", colname1, colname2);System.out.println(header);
我们将列名称打印到控制台。
while (rs.next()) { String row = String.format("%-21s", rs.getString(1)); System.out.print(row); System.out.println(rs.getString(2));}
我们将数据打印到控制台。 第一列为 21 个字符,并在左侧对齐。
$ mvn exec:java -qNAME TitleJack London Call of the WildJack London Martin EdenHonore de Balzac Old GoriotHonore de Balzac Cousin BetteLion Feuchtwanger Jew SuessEmile Zola NanaEmile Zola The Belly of ParisTruman Capote In Cold bloodTruman Capote Breakfast at Tiffany
这是程序的输出。
MySQL Java 自动生成的键
MySQL 的AUTO_INCREMENT属性为新行生成唯一的 ID。 以下示例说明了如何使用 JDBC 检索自动生成的键值。
JdbcAutoGenKey.java
在该示例中,我们向表中添加了一个新作者,其主键由 MySQL 自动递增。 我们检索生成的 ID。
try (Connection con = DriverManager.getConnection(url, user, password); PreparedStatement pst = con.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
第一步,我们必须将Statement.RETURN_GENERATED_KEYS传递给prepareStatement()方法。
try (ResultSet rs = pst.getGeneratedKeys()) {
然后,我们使用getGeneratedKeys()方法检索生成的键。
if (rs.first()) { System.out.printf("The ID of new author: %d", rs.getLong(1));}
由于我们只有一个插入语句,因此我们使用first()导航到该值。
$ mvn exec:java -qThe ID of new author: 7
这是一个示例输出。
MySQL Java 编写图像
有些人喜欢将其图像放入数据库中,有些人则希望将其保留在文件系统中以供其应用使用。 当我们处理大量图像时,会出现技术难题。 图像是二进制数据。 MySQL 数据库具有一种特殊的数据类型来存储称为BLOB(二进制大对象)的二进制数据。
对于此示例,我们使用Images表。
JdbcWriteImage.java
在前面的示例中,我们从当前工作目录中读取 PNG 图像,并将其插入Images表中。
String sql = "INSERT INTO Images(Data) VALUES(?)";
这是插入图像的 SQL。
File myFile = new File("src/main/resources/tree.png");try (FileInputStream fin = new FileInputStream(myFile)) {
我们为图像文件创建一个File对象。 要从该文件读取字节,我们创建一个FileInputStream对象。
pst.setBinaryStream(1, fin, (int) myFile.length());
二进制流设置为预备语句。 setBinaryStream()方法的参数是要绑定的参数索引,输入流和流中的字节数。
pst.executeUpdate();
我们执行该语句。
MySQL Java 读取图像
在前面的示例中,我们已将图像插入数据库表中。 现在,我们将从表中读取图像。
JdbcReadImage.java
我们从图片表中读取了一张图片。
String query = "SELECT Data FROM Images LIMIT 1";
我们从表中选择一条记录。
String fileName = "src/main/resources/tree.png";try (FileOutputStream fos = new FileOutputStream(fileName)) {
创建FileOutputStream对象以写入文件。 它旨在写入原始字节流,例如图像数据。
Blob blob = result.getBlob("Data");
我们通过调用getBlob()方法从Data列中获取图像数据。
int len = (int) blob.length();
我们计算出斑点数据的长度。 换句话说,我们得到字节数。
byte[] buf = blob.getBytes(1, len);
getBytes()方法以字节数组的形式检索 Blob 对象的所有字节。
fos.write(buf, 0, len);
字节被写入输出流。 该映像在文件系统上创建。
事务支持
事务是针对一个或多个数据库中数据的数据库操作的基本单位。 事务中所有 SQL 语句的影响可以全部提交给数据库,也可以全部回滚。
MySQL 数据库具有不同类型的存储引擎。 最常见的是 MyISAM 和 InnoDB 引擎。 在数据安全性和数据库速度之间需要权衡。 MyISAM 表的处理速度更快,并且不支持事务。 另一方面,InnoDB 表可以更安全地防止数据丢失。 它们支持事务,并且处理速度较慢。
JdbcTransaction.java
在此程序中,我们想在Authors表的第一行上更改作者的姓名。 我们还必须更改与该作者相关的书籍。 这是一个需要进行事务的很好的例子。 如果我们更改作者但不更改作者的书,则数据已损坏。
con.setAutoCommit(false);
st.executeUpdate("UPDATE Books SET Titl = 'Anna Karenina' " + "WHERE Id = 2");
第三个 SQL 语句有一个错误。 表中没有 Titl 栏。
如果没有异常,则提交事务。
try { con.rollback();} catch (SQLException ex1) { Logger lgr = Logger.getLogger(JdbcTransaction.class.getName()); lgr.log(Level.WARNING, ex1.getMessage(), ex1);}
发生异常时,事务将回滚。 没有更改提交到数据库。
该应用以异常结束。
mysql> SELECT Name, Title From Authors, Books WHERE Authors.Id=Books.AuthorId;+-------------------+----------------------+| Name | Title |+-------------------+----------------------+| Jack London | Call of the Wild || Jack London | Martin Eden || Honore de Balzac | Old Goriot || Honore de Balzac | Cousin Bette || Lion Feuchtwanger | Jew Suess || Emile Zola | Nana || Emile Zola | The Belly of Paris || Truman Capote | In Cold blood || Truman Capote | Breakfast at Tiffany |+-------------------+----------------------+9 rows in set (0.01 sec)
事务已回滚,并且未进行任何更改。
但是,如果没有事务,数据是不安全的。
JdbcNoTransaction.java
我们有同样的例子。 这次,没有事务支持。
mysql> SELECT Name, Title From Authors, Books WHERE Authors.Id=Books.AuthorId;+-------------------+----------------------+| Name | Title |+-------------------+----------------------+| Leo Tolstoy | War and Peace || Leo Tolstoy | Martin Eden || Honore de Balzac | Old Goriot || Honore de Balzac | Cousin Bette || Lion Feuchtwanger | Jew Suess || Emile Zola | Nana || Emile Zola | The Belly of Paris || Truman Capote | In Cold blood || Truman Capote | Breakfast at Tiffany |+-------------------+----------------------+9 rows in set (0.00 sec)
再次引发异常。 列夫·托尔斯泰没有写马丁·伊甸园; 数据已损坏。
批量更新
当我们需要使用多个语句更新数据时,可以使用批处理更新。 批处理更新可用于INSERT,UPDATE,DELETE语句以及CREATE TABLE和DROP TABLE语句。
JdbcBatchUpdate.java
这是用于批处理更新的示例程序。 我们从“作者”表中删除所有数据,然后插入新数据。 我们添加了一位新作者,Umberto Eco,以查看更改。
st.addBatch("DROP TABLE IF EXISTS Authors2");st.addBatch("CREATE TABLE Authors2(Id INT PRIMARY KEY, " + "Name VARCHAR(100))");st.addBatch("INSERT INTO Authors2(Id, Name) " + "VALUES(1, 'Jack London')");...
我们使用addBatch()方法向该语句添加新命令。
int counts[] = st.executeBatch();
添加所有命令后,我们调用executeBatch()进行批量更新。 该方法返回已提交更改的数组。
批处理更新在事务中提交。
} catch (SQLException ex) { try { con.rollback(); } catch (SQLException ex2) { Logger lgr = Logger.getLogger(JdbcBatchUpdate.class.getName()); lgr.log(Level.FINEST, ex2.getMessage(), ex2); } Logger lgr = Logger.getLogger(JdbcBatchUpdate.class.getName()); lgr.log(Level.FINEST, ex.getMessage(), ex);}
万一批量更新失败,我们将其称为rollback()。
$ mvn exec:java -qCommitted 8 updatesmysql> SELECT * from Authors2;+----+-------------------+| Id | Name |+----+-------------------+| 1 | Jack London || 2 | Honore de Balzac || 3 | Lion Feuchtwanger || 4 | Emile Zola || 5 | Truman Capote || 6 | Umberto Eco |+----+-------------------+6 rows in set (0.00 sec)
我们执行BatchUpdate程序。 SELECT语句显示Authors2表已成功更新。 它有一个新作者,Umerto Eco。
将数据导出到 CSV 文件
下一个示例将数据导出到 CSV 文件。
我们需要对testuser具有适当的文件许可权; 否则,我们会收到拒绝访问错误消息。
mysql> GRANT FILE ON *.* TO 'testuser'@'localhost';
我们设置了FILE权限。
mysql> SHOW VARIABLES LIKE "secure_file_priv";+------------------+-----------------------+| Variable_name | Value |+------------------+-----------------------+| secure_file_priv | /var/lib/mysql-files/ |+------------------+-----------------------+1 row in set (0.26 sec)
出于安全原因,MySQL 从启用--secure-file-priv选项开始,该选项仅允许处理特定目录中的文件。 该目录在secure_file_priv变量中指定。 在 Windows 上,路径类似于'C:/ProgramData/MySQL/My*** 5.7/Uploads'。
ExportCSV.java
我们将作者及其相应的书籍导出到/var/lib/mysql-files/authors_books.csv文件中。
String query = "SELECT Name, Title INTO OUTFILE " + "'/var/lib/mysql-files/authors_books.csv' " + "FIELDS TERMINATED BY ',' " + "FROM Authors, Books WHERE " + "Authors.Id=Books.AuthorId";
要将数据导出到文件中,我们使用SELECT INTO OUTFILE SQL 语句。
$ cat /var/lib/mysql-files/authors_books.csvJack London,Call of the WildJack London,Martin EdenHonore de Balzac,Old GoriotHonore de Balzac,Cousin BetteLion Feuchtwanger,Jew SuessEmile Zola,NanaEmile Zola,The Belly of ParisTruman Capote,In Cold bloodTruman Capote,Breakfast at Tiffany
我们验证数据。
您可能也对 MySQL Python 教程, MySQL Visual Basic 教程或 MySQL PHP 教程,MySQL Java 教程,MySQL Ruby 教程,MySQL C# 教程感兴趣。
版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。