java数据库编程——执行SQL 语句

【0】README

1) 本文文字描述+source code 均转自 core java volume 2 , 旨在理解 java数据库编程——执行SQL 语句 的基础知识 ;
2)for source code, please visit : https://github.com/pacosonTang/core-java-volume/tree/master/coreJavaAdvanced/chapter4/executeSQL
3)for database connection config, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/database.properties


【1】java数据库编程——执行SQL 语句相关

1)执行 SQL 命令前, 首先需要创建一个 Statement 对象: 要创建 statement 对象,不需要调用 DriverManager.getConnection 方法所获得的 Connection对象;(干货——Statement object == 语句对象)

  • step1) Statement stat = conn.createStatement();
  • step2) 将要执行的 SQL 语句放入字符串中,如:

    String command = “update ….”;

  • step3) 然后,调用Statement 接口中的executeUpdate 方法:

    stat.executeUpdate(command); // executeUpdate 方法:将返回受SQL命令影响的行数, 或者对于不返回行数的语句返回0; (干货——executeUpdate返回受SQL命令影响的行数,或者0)

2)execute系列方法: (干货——execute系列方法:executeUpdate + executeQuery + execute)

  • 2.1)executeUpdate 方法:既可以执行诸如 insert, update, 和 delete之类的操作(DML), 也可以执行诸如 create , drop 之类的数据定义语句(DDL);
  • 2.2)executeQuery方法: 执行 select 查询语句时 必须使用 executeQuery 方法;
  • 2.3)execute 方法: 可以执行任意的sql 语句, 通常只用于用户提供的交互式查询;

3)查询结果(ResultSet 类型): executeQuery 方法返回一个ResultSet类型的对象, 可以通过它来每次一行地迭代遍历所有查询结果;

ResultSet rs = stat.executeQuery(“select * from books”);

  • 3.1)分析结果集时通常可以使用类似如下循环语句的代码:

    while(rs.next() )
    {
    look at a row of the result set
    }

  • Warnning)

    • W1)ResultSet接口的 迭代协议与 java.util.Iterator 接口稍有不同。 对于ResultSet 接口, 迭代器初始化时被设定在第一行之前的位置,必须调用 next 方法将它移动到第一行; (干货——ResultSet接口的 迭代协议与 java.util.Iterator 接口稍有不同)
    • W2)另外,它没有hasNext方法, 我们需要不断地调用 next, 直至该方法返回 false;
    • W3)结果集中行的顺序是任意的, 不能为行序强加任何意义; (干货——ResultSet结果集中行的顺序是任意的, 不能为行序强加任何意义)
  • 3.2)查看每一行,需要知道每一列的内容:

    String str = rs.getString(1);
    double price = rs.getDouble(1);

  • 3.3)不同的数据类型有不同的访问器: 比如 getString 和 getDouble; 每个访问器都有两种形式,一种接收数字类型参数,一个接收字符串类型参数;

  • Warning) 数据库的列序号从1开始算 ;

  • 3.4)当使用 字符串参数时, 指的是结果集中以该字符串为列名的列;如,
    rs.getDouble(“price”) 返回列名为 Price 的列所对应的值;

  • 3.5)当get方法的类型和列的数据类型不一致时, 每个get 方法都会进行合理的类型转换;

【2】管理连接、语句和结果集

1)每个Connection对象都可以创建一个或多个 Statement对象;

  • 1.1)同一个Statement对象可以用于不相关的命令和查询;
  • 1.2)但是,一个Statement对象最多只能有一个打开的结果集;
  • 1.3)需要说明的是: 至少有一种常用的数据库(Microsoft SQL Server) 的JDBC驱动程序只允许同时存在一个活动的 Statement 对象。使用 DatabaseMetaData 接口中的 getMaxStatements 方法可以获取JDBC 驱动程序支持的同时活动的语句对象的总数;
    • 1.3.1)这看上去很有局限性。实际上,我们通常并不需要同时处理多个 结果集。对数据库进行组合查询比使用 java 程序遍历多个结果集要高效得多; (干货——我们通常并不需要同时处理多个 结果集,对数据库进行组合查询比使用 java 程序遍历多个结果集要高效得多)
  • 1.4)close方法:使用完 ResultSet , Statement , Connection对象后,立即调用 close方法;
  • 1.5)closeOnCompletion方法: 在java 7中, 可以在 Statement 上调用 closeOnCompletion 方法, 在其所有结果集都被关闭后, 该语句会立即被自动关闭; (干货——java7引入的新方法closeOnCompletion)
  • 1.6)如果所用连接都是短时的,无需考虑关闭语句和结果集。 只需要将 close 语句放 在 带资源的try语句中, 以便确保最终连接对象不可能继续保持打开状态:

    try (Connnection conn =…)
    {
    Statement stat = conn.createStatement();
    ResultSet result = stat.executeQuery(queryStr);
    process query result
    }

Attention) 应该使用带资源的try 语句块来关闭连接,并使用一个单独的 try /catch 块处理异常。 分离 try 程序块可以 提高代码的可读性和可维护性;


【3】分析 SQL 异常(SQLException)

1) java 6 改进了 SQLException 类,让其实现了 Iterable接口, 其 iterator() 方法可以产生一个 Iterable< Throwable>;

  • 1.1) 这个迭代器是可以迭代这两个链, 首先迭代第一个 SQLException 的成因链, 然后迭代下一个 SQLException ,以此类推;如,

    for(Throwable t : sqlException)
    {
    do sth with t
    }

  • 1.2)可以在 SQLException 上调用 getSQLState 和 getErrorCode 方法来进一步分析它;

2) SQLException 按照层次结构树的方式组合到了一起, 如下图所示:
这里写图片描述

  • 2.1)数据库驱动程序将非致命问题作为警告报告,我们可以从连接(Connection), 语句(Statement)或结果集(ResultSet)中获取这些警告;
  • 2.2)SQLWarning: 是 SQLException的子类,我们可以调用 getSQLState 和 getErrorCode 来获取有关警告的更多信息; (干货——SQLWarning 定义)
  • 2.3)要获得所有警告,使用下面的循环:

    SQLWarning w = stat.getWarning()
    while(w != null)
    {
    do wth with w
    w = w.nextWarning();
    }

  • 2.4)当数据从数据库中读出并意外被截断时, SQLWarning 的 DataTruncation 子类就派上用场了; 如果数据截断发送在更新语句中, 那么DataTrucation 将会被当做异常抛出;


【4】组装数据库

1)看个荔枝:(用java 操作数据库)

  • step1)连接数据库。

    • step1.1) getConnection 方法:读取database.properties 文件中的 属性信息,并将属性jdbc.drivers 添加到系统属性中;
    • step1.2) 驱动程序管理器:使用属性jdbc.drivers 加载相应的驱动程序;
    • step1.3) getConnection方法: 使用 jdbc.url , jdbc.username, jdbc.password 等属性打开数据库连接;
  • step2)使用 sql 语句打开文件;

  • step3) 使用 泛化的execute 方法执行每条语句;
  • step4) 如果产生了结果集, 则打印结果;
  • step5) 如果运行过程中出现 SQL 异常, 则打印出这个异常以及所有可能包含在其中的与其连接在一起的相关异常;
  • step6)关闭数据库连接;

2)运行结果如下:

(java -classpath .;D:\Software_Cluster\Development\mysql\mysql-connector-java-5.1.17\mysql-connector-java-5.1.17-bin.jar com.corejava.chapter4.ExecSQL)
这里写图片描述

3)source code at a glance

class ExecSQL
{private static String cur_dir = System.getProperty("user.dir") + File.separator +  "com" + File.separator + "corejava" + File.separator +  "chapter4" + File.separator;public static void main(String args[]) throws IOException{try{Scanner in = args.length == 0 ? new Scanner(System.in) : new Scanner(Paths.get(args[0]));try (Connection conn = getConnection()){Statement stat = conn.createStatement();while (true){if (args.length == 0) System.out.println("Enter command or EXIT to exit:");if (!in.hasNextLine()) return;String line = in.nextLine();if (line.equalsIgnoreCase("EXIT")) return;if (line.trim().endsWith(";")) // remove trailing semicolon{line = line.trim();line = line.substring(0, line.length() - 1);}try{boolean isResult = stat.execute(line);if (isResult){ResultSet rs = stat.getResultSet(); //结果集showResultSet(rs); // 打印结果集}else{int updateCount = stat.getUpdateCount();System.out.println(updateCount + " rows updated");}}catch (SQLException ex){for (Throwable e : ex)e.printStackTrace();}}}}catch (SQLException e){for (Throwable t : e)t.printStackTrace();}}public static Connection getConnection() throws SQLException, IOException{Properties props = new Properties();try (InputStream in = Files.newInputStream(Paths.get(cur_dir + "database.properties"))){props.load(in);}String drivers = props.getProperty("jdbc.drivers");if (drivers != null) System.setProperty("jdbc.drivers", drivers);String url = props.getProperty("jdbc.url");String username = props.getProperty("jdbc.username");String password = props.getProperty("jdbc.password");return DriverManager.getConnection(url, username, password);}public static void showResultSet(ResultSet result) throws SQLException{ResultSetMetaData metaData = result.getMetaData(); // 结果集元数据int columnCount = metaData.getColumnCount();for (int i = 1; i <= columnCount; i++){if (i > 1) System.out.print(", ");System.out.print(metaData.getColumnLabel(i));}System.out.println();while (result.next()) // 循环打印结果集{for (int i = 1; i <= columnCount; i++){if (i > 1) System.out.print(", ");System.out.print(result.getString(i));}System.out.println();}}
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/331451.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

php cdi_Quarkus的其他(非标准)CDI功能

php cdiQuarkus支持CDI&#xff08;上下文和依赖注入&#xff09;2.0&#xff0c;但并非全部&#xff0c;仅支持最常见的功能。 但是&#xff0c;Quarkus确实包含一些非标准功能&#xff0c;这些功能对于开发人员非常方便&#xff0c;我想在下面的视频中进行展示。 不管您是否…

Shell入门(七)之关系运算

一、关系运算 shell关系运算符只支持数字&#xff0c;不支持字符串&#xff0c;除非字符串的值是数字。 a10 b20 运算符说明举例-eq检测两个数是否相等&#xff0c;相等返回 true。[ $a -eq $b ] 返回 false。-ne检测两个数是否相等&#xff0c;不相等返回 true。[ $a -ne $…

java数据库编程——Insert and Retrieve Images from MySql Table Using Java

【0】README0.1&#xff09;本文翻译自 http://harmeetsingh13.blogspot.jp/2013/03/insert-and-retrieve-images-from-mysql.html【1】正文如下&#xff1a;段1&#xff09;演示 从数据库表中插入和查询出图片。大多数情况下&#xff0c;图片数据都存储在数据库外部的一些文件…

Shell入门(八)之布尔运算

一、常规的布尔运算 常规的布尔运算符有&#xff1a;!、&&、|| 使用语法 ! exp exp && exp exp || exp [[ n op m && a op b]] ... exp为[ n op m ]或test n op m或true或false 二、条件测试的布尔运算 条件测试的布尔运算有&#xff1a;!、…

java switch语句_Java 14:查看更新的switch语句

java switch语句于2020年3月发布的JDK 14带有switch语句的更新版本。 这是JDK 12和JDK 13中的预览功能。 要了解差异&#xff0c;让我们看一个简单的示例。 假设我们要基于DayOfWeek枚举来计算每日工作时间。 使用旧的使用switch语句的方法&#xff0c;我们的解决方案可能如下…

java数据库编程——执行查询操作(一)

【0】README 1&#xff09; 本文部分文字描述和source code 均转自 core java volume 2 &#xff0c; 旨在理解 java数据库编程——执行查询操作 的基础知识 &#xff1b; 2&#xff09; 本文和 java数据库编程——执行查询操作&#xff08;二&#xff09; 是姊妹篇&#xff…

Shell入门(九)之字符串比较

一、字符串比较 字符串比较符&#xff1a;、!、-z、-n、str 实际上&#xff0c;shell不区分数值与字符串类型&#xff0c;数值也可以使用上面比较。 a"mk" b"maokun" 运算符说明举例检测两个字符串是否相等&#xff0c;相等返回 true。[ $a $b ] 返回…

java中将毫秒转换成时间_在Java中将时间单位转换为持续时间

java中将毫秒转换成时间java.util.concurrent.TimeUnit以给定的粒度单位表示Java中的持续时间&#xff0c;并提供跨单位转换的实用方法。 java.util.concurrent.TimeUnit最早是在Java早期&#xff08;1.5&#xff09;引入的&#xff0c;但自那时以来已经扩展了好几次。 在此博客…

java数据库编程——执行查询操作(二)

【0】README 1&#xff09; 本文部分文字描述和source code 均转自 core java volume 2 &#xff0c; 旨在理解 java数据库编程——执行查询操作&#xff08;二&#xff09; 的基础知识 &#xff1b; 2&#xff09; 本文和 java数据库编程——执行查询操作&#xff08;一&…

Shell入门(十)之echo

一、echo参数 echo [参数选项] 字符串 参数选项 -e 解析字符串中的转义字符&#xff0c;如\n -E 这是默认设置&#xff0c;不解析转义字符 -n 不输出换行&#xff0c;可以使用echo -e 字符串"\c" 代替 #!/bin/bash a"abc\n" echo $a echo -e…

vaadin_Vaadin提示:延迟加载和商品标识

vaadin延迟加载 在Vaadin中使用网格&#xff0c;树或任何其他多值组件时&#xff0c;您通常希望显示数据库表中的数据&#xff0c;并且通常数据库中有多行。 在这种情况下&#xff0c;加载数千甚至数百万条记录是没有意义的&#xff0c;这将是一个巨大的性能问题。 对于此用例&…

com.mysql.jdbc.NotUpdatable: Result Set not updatable (references no primary keys).(解决方法)

【1】异常详细信息 com.mysql.jdbc.NotUpdatable: Result Set not updatable (references no primary keys). This result set must come from a statement that was created with a result set type of ResultSet.CONCUR_UPDATABLE, the query must select only one table, …

jdk 取整数_JDK 15中的确切绝对整数

jdk 取整数JDK 15 Early Access Build b18向Math和StrictMath类引入了新方法&#xff0c;这些方法将在提供的值超出方法所支持的范围时抛出ArithmeticException &#xff0c;而不会溢出。 这些方法为Java中的“绝对值”概念带来了Math.addExact &#xff0c; Math.subtractExac…

java数据库编程——可滚动和可更新的结果集

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java数据库编程——可滚动和可更新的结果集 的基础知识 &#xff1b; 2&#xff09;for database connection config, please visit &#xff1a;…

Spring入门(四)之BeanFactory

一、BeanFacotry访问一个Spring bean容器的根接口。这是一个Bean容器基本客户端视图&#xff1b;进一步的接口如ListableBeanFactory和configurablebeanfactory供特定用途。此接口由包含许多bean定义的对象来实现&#xff0c;每个对象都有唯一的字符串名称标识。根据bean定义&a…

apache derby_Apache Derby数据库JVM安全策略

apache derby抽象 我已经发布了许多有关Derby的博客&#xff1a; Derby数据库备份 同一主机上的多个Derby网络服务器 Apache Derby数据库用户和权限 与Maven和内存中Derby数据库的集成测试 这本不打算是一个系列。 但是多年来&#xff0c;我越来越多地使用Derby。 我开始将…

java数据库编程——事务

【0】README 1&#xff09; 本文部分文字描述转自 core java volume 2 &#xff0c; 测试源代码均为原创&#xff0c; 旨在理解 java数据库编程——事务 的基础知识 &#xff1b; 2&#xff09;for database connection config, please visit &#xff1a; https://github.co…

算法九之基数排序

一、基数排序 &#xff08;1&#xff09;基数排序的简介 基数排序不同于其他的排序算法&#xff0c;它不是基于比较的算法。基数排序是一种借助多关键字排序的思想对单逻辑关键字进行排序的方法。它是一种稳定的排序算法。  通常用于对数的排序选择的是最低位优先法&#xff…

在Spring中使用多个动态缓存

在第三篇有关Spring&#xff08;长时间&#xff09;的缓存管理器的文章中&#xff0c;我想通过展示如何配置多个动态创建缓存的缓存管理器来扩展前 两个 。 Spring具有CompositeCacheManager &#xff0c;从理论上讲&#xff0c;它应该允许使用多个缓存管理器。 它通过询问基础…