【0】README
1) 本文部分文字描述和source code 均转自 core java volume 2 , 旨在理解 java数据库编程——执行查询操作(二) 的基础知识 ;
2) 本文和 java数据库编程——执行查询操作(一) 是姊妹篇, 共同组成了 java数据库编程——执行查询操作的全部内容, for java数据库编程——执行查询操作(一), please visit http://blog.csdn.net/PacosonSWJTU/article/details/50628980 ;
3)for database connection config, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/database.properties
【1】SQL转义
1)转义定义: 转义语法支持各种数据库普遍支持的特性, 但是数据库使用的是与数据库相关的语法变体, 因此,将转义语法转译为 特定数据库的语法是JDBC 驱动程序的任务之一。 (干货——将转义语法转译为 特定数据库的语法是JDBC 驱动程序的任务之一)
2)转义主要用于下列特性(Character):
- C1)日期和时间字面常量;
- C2)调用标量函数;
- C3)调用存储过程;
- C4)外连接;
- C5) 在 like 子句中的 转义字符;
2.1)应该使用d, t, ts 来表示 DATE, TIME 和 TIMESTAMP的值:
{d, ‘2008-01-24’}
{t, ‘23:59:59’}
{ts, ‘2008-01-24 23:59:59.999’}2.2)标量函数: 是指仅返回一个值的函数;要调用函数, 需要嵌入标准的函数名和参数: (干货——标量函数定义)
{fn left(?, 20)}
{fn user() }2.3 )存储过程: 是在数据库中执行的用数据库相关的语言编写的过程。要调用存储过程, 需要使用 call 转移命令, 其中在存储过程没有任何参数的时候, 就不用加上括号。另外,应该用=来捕获存储过程的返回值; (干货——存储过程定义)
{call PROC1(?, ?)}
{call PROC2}
{call ?=PROC3(?)}2.4)外连接;
- 2.5) _ 和 % 字符在 LIKE 子句中具有特殊含义: 用来匹配一个字符或一个字符序列。 目前并不存在任何在字面上使用它们的标准方式, 所以如果想要匹配所有包含_ 字符的字符串, 就必须使用下面结构: (干货——_ 和 % 字符在 LIKE 子句中具有特殊含义)
…. where ? like %!_% {escape ‘!’}
这里, 我们将 ! 定义为 转移字符, 而 !_ 组合表示字面常量下划线; (干货—— 叹号! 定义为转移字符)
【2】多结果集
0)多结果集定义: 在执行存储过程,或在使用允许在单个查询中提交多个select 语句的数据库时,一个查询有可能会返回多个结果集。 (干货——多结果集定义)
1)下面是获取结果集的步骤: (干货——获取结果集的步骤)
- step1)使用execute 方法来执行 sql 语句;
- step2) 获取第一个结果集或更新计数;
- step3)重复调用 getMoreResults 方法以移动到下一个结果集;
step4) 当不存在更多的结果集或更新计数时, 完成操作;
1.1) 如果由多结果集构成的链中的下一项是结果集, execute 和 getMoreResults 方法将返回 true, 而如果在链中的下一项不是更新计数,getUpdateCount 方法将返回-1;
- 1.2)下面的循环遍历所有结果集:
boolean isResult = stat .execute(command);
boolean done = false;
while(!done)
{if(isResult){ResultSet result = stat.getResultSet()do sth with result}else{int updateCount = stat.getUpdateCount();if(updateCount >= 0)do sth with updateCountelsedone = true;}if(!done)isResult = stat.getMoreResults();
}
2)看个多结果集的荔枝:
- 2.1)for souce code, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/execute_select/OneCommitMultipleSelect.java
- 2.2)key source code at a glance:
package com.corejava.chapter4;import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;public class OneCommitMultipleSelect
{private static String cur_dir = System.getProperty("user.dir") + File.separator + "com" + File.separator + "corejava" + File.separator + "chapter4" + File.separator;// insert and select blob objpublic static void main(String[] args){try{try(Connection conn = getConnection()){// query starts. one sql commits multiple select statements.// String sql = "select id from student;select name from student";String sql = "call multi_select()";Statement stat = conn.createStatement(); boolean isResult = stat.execute(sql);boolean done = false;if(isResult){ResultSet result = stat.getResultSet();while(result.next()) // print result set named id {System.out.println("student.id = " + result.getInt(1));}}// 重复调用 getMoreResults 方法以移动到下一个结果集if((isResult = stat.getMoreResults())){ResultSet result = stat.getResultSet();while(result.next()) // print result set named 'name' {System.out.println("student.name = " + result.getString(1));}}System.out.println("the last stat.getMoreResults() == " + stat.getMoreResults());stat.close();conn.close();}}catch(Exception e){e.printStackTrace();}}public static Connection getConnection() throws IOException, SQLException{Properties prop = new Properties();try(InputStream in = Files.newInputStream(Paths.get(cur_dir + "database.properties"))){prop.load(in);}String drivers = prop.getProperty("jdbc.drivers");if(drivers != null){System.setProperty("jdbc.drivers", drivers); // register drivers for accessing database }String url = prop.getProperty("jdbc.url");String user = prop.getProperty("jdbc.username");String pass = prop.getProperty("jdbc.password");return DriverManager.getConnection(url, user, pass);}
}
- 2.3)relative printing results as follows:
Complementary)
C1)怎样创建+查看+调用存储过程;
C2)在创建存储过程的命令行代码中, delimiter // 以及 最后的 end// 是什么意思?
它其实就是一个分隔符而已, 表明分隔符内的 分号; 并不表示输入结束,输入结束的标志是配对的 ‘//’: for detailed info , please visit http://database.51cto.com/art/201011/235017.htm
【3】获取自动生成键
1)当我们向数据库插入一个新行, 且其键自动生成时,可以实现下面的代码来获取这个键:
stmt.executeUpdate(insertStatement, Statement.RETURN_GENERATED_KEYS); // 自动生成主键;
ResultSet rs = stmt.getGeneratorKeys(); // 返回自动生成键的结果集;
if(rs.next())
{int key = rs.getInt(1);...
}
2)看个获取自动生成键的荔枝:
- 2.1)for souce code, please visit : https://github.com/pacosonTang/core-java-volume/blob/master/coreJavaAdvanced/chapter4/execute_select/MyGetPrimaryKey.java
- 2.2)key source code at a glance:
public static void main1(String[] args) throws SQLException, IOException{ try{try(Connection conn = getConnection()){String sql = "insert employee(name, salary, address) values('zhangsan',1000,'beijing')";Statement stat = conn.createStatement();stat.executeUpdate(sql, Statement.RETURN_GENERATED_KEYS);ResultSet rs = stat.getGeneratedKeys();if(rs.next()){System.out.println(rs.getInt(1)); // print generated keys}}}catch(Exception e){e.printStackTrace();}}public static Connection getConnection() throws IOException, SQLException{Properties prop = new Properties();try(InputStream in = Files.newInputStream(Paths.get(cur_dir + "database.properties"))){prop.load(in);}String drivers = prop.getProperty("jdbc.drivers");if(drivers != null){System.setProperty("jdbc.drivers", drivers); // register drivers for accessing database }String url = prop.getProperty("jdbc.url");String user = prop.getProperty("jdbc.username");String pass = prop.getProperty("jdbc.password");return DriverManager.getConnection(url, user, pass);}
- 2.3)relative printing results as follows: