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

【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 updateCount
        else
            done = true;
    }
    if(!done)
        isResult = stat.getMoreResults();
}

2)看个多结果集的荔枝:

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 obj
    public 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)看个获取自动生成键的荔枝:

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:
  • 这里写图片描述
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值