JDBC进阶 元数据

1:resultSet

1.1最基本的ResultSet.

1.2 可滚动的ResultSet类型

1.3 可更新的ResultSet

1.4 可保持的ResultSet

2:PrepareStatement

2.1: 基本操作

2.2 复用pststemetn

2.3 性能分析

3:执行批量SQL

3.1: statemet 方式

3.2: preparedstatement 方式

4: 事物transaction

4.1 基本处理

4.2 断点事物处理

6 元数据类型

6.1 DatabaseMetaData  数据库元数据

在表中列出列 getColumS()

主键信息

6.2 ParameterMetaData 参数元数据类型

6.3 ResultSetMetaData 结果集元数据

1:resultSet

当创建一个ResultSet时,你可以设置三个属性:

类型

ResultSet.TYPE_FORWARD_ONLY

该常量指示光标只能向前移动的 ResultSet 对象的类型。

ResultSet.TYPE_SCROLL_INSENSITIVE

该常量指示可滚动但通常不受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。

ResultSet.TYPE_SCROLL_SENSITIVE

该常量指示可滚动并且通常受 ResultSet 底层数据更改影响的 ResultSet 对象的类型。

并发

ResultSet.CONCUR_READ_ONLY

该常量指示不可以更新的 ResultSet 对象的并发模式。

ResultSet.CONCUR_UPDATABLE

该常量指示可以更新的 ResultSet 对象的并发模式。

可保存性

ResultSet.HOLD_CURSORS_OVER_COMMIT

该常量指示提交当前事务时,具有此可保存性的打开的 ResultSet 对象将保持开放。

ResultSet.CLOSE_CURSORS_AT_COMMIT

该常量指示提交当前事务时,具有此可保存性的打开的 ResultSet 对象将被关闭。

在创建Statement或PreparedStatement时已经设置了这些值,如下所示:

Statement statement = connection.createStatement(
    ResultSet.TYPE_FORWARD_ONLY,
    ResultSet.CONCUR_READ_ONLY,
    ResultSet.CLOSE_CURSORS_OVER_COMMIT
   );

PreparedStatement statement = connection.prepareStatement(sql,
    ResultSet.TYPE_FORWARD_ONLY,
    ResultSet.CONCUR_READ_ONLY,
    ResultSet.CLOSE_CURSORS_OVER_COMMIT
   );

1.1最基本的ResultSet.

最基本的ResultSet是因为,这个ResultSet他起到的作用就是完成了查询结果的存储功能,而且只能读去一次,不能够来回的滚动读取. 最常用的

 1.2 可滚动的ResultSet类型

next(),previous(), first(),last()  移动绝对行 absolute(int n),移动相对行relative(int n),

ResultSet.TYPE_FORWARD_ONLY

只能向前滚动

ResultSet.TYPE_SCROLL_INSENSITIVE

实现任意的前后滚动, 对于修改不敏感

Result.TYPE_SCROLL_SENSITIVE

实现任意的前后滚动, 对于修改敏感.

1.3 可更新的ResultSet

ResultSet对象可以完成对数据库中表的修改,但是我知道ResultSet只是相当于数据库中表的视图,所以并不时所有的ResultSet只要设置了可更新就能够完成更新的,能够完成更新的ResultSet的SQL语句必须要具备如下的属性: 通过 并发下面属性设置

a,只引用了单个表.

b,不含有join或者group by子句.

c,那些列中要包含主关键字.

执行顺序UpdatXXX 更新操作执行必须执行

1:moveToInsertRow()  是把ResultSet移动到插入行 这个插入行是表中特殊的一行
  moveToCurrentRow() 移动到插入行 如果之前Insert,那么就移动到之前Insert()0哪一行,没有Insert 就没有效果
2:UpdateXXX()
3:insertRow()

1.4 可保持的ResultSet

所有的Statement的查询对应的结果集是一个,如果调用Connection的commit()方法也会关闭结果集.

通过设置 HOLD_CURSORS_OVER_COMMIT 来保持数据

2:PrepareStatement

特点: 禁止了拼接SQL可以注入的现象,将会SQL传入数据库编译通过设置参数方式保证安全性

select * from user where name=‘aa‘ and password=‘bb‘ or 1=1 //类始于这种SQL的注入方式

2.1: 基本操作

executeQuery()    执行查询

executeUpdate()  执行CUD操作

execute() 执行DDL操作

executeLargeUpdate() 执行超大SQL语句

  String sql = "select * from user";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);

            ResultSet resultSet = preparedStatement.executeQuery();

            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String birthday = resultSet.getString("birthday");
                String sex = resultSet.getString("sex");
                String address = resultSet.getString("address");

                System.out.println("  " + username + " " + birthday + " " + sex
                        + " " + address);
            }

2.2 复用pststemetn

即为一次创建多次使用, 通过connection创建prepareStatement 多次使用 prepareStatement

特点 参数可以变,但是SQl 是不变的

 PreparedStatement preparedStatement = connection.prepareStatement(sql);//创建prepareStatement

            preparedStatement.setString(1,"Fant.J");
            preparedStatement.setInt(2,27);
            int result = preparedStatement.executeUpdate(); // 第一次使用

            preparedStatement.setString(1,"Fant.J reUseTest");
            preparedStatement.setInt(2,27);
            preparedStatement.executeUpdate();//第二次使用  但是都是用的第一次创建ps 时的编译语句 

2.3 性能分析

  PreparedStatement是Statement的子类,区别:

PreparedStatement  编译一次,可以将多条SQL语句汇聚到一起执行,提高执行效率

Statement 是每一条SQL执行一次,100条SQL 就要执行100次

两个级别的复用:

JDBC驱动程序重新使用PreparedStatement。

数据库重用PreparedStatement。

3:执行批量SQL

用到 addBatch()和executeBatch()方法   用于 Insert Update  Delete 等SQL的处理

  3.1: statemet 方式

Statement statement = null;
try{
    statement = connection.createStatement();

    statement.addBatch("update people set firstname=‘aaa‘ where id=123");
    statement.addBatch("update people set firstname=‘bbb‘ where id=456");
    statement.addBatch("update people set firstname=‘ccc‘  where id=789");

    int[] recordsAffected = statement.executeBatch();  // 返回每个SQl执行后影响的元组数
} finally {
    if(statement != null) statement.close();
}

  3.2: preparedstatement 方式

String sql = "update user set username=? where id=?";
PreparedStatement preparedStatement = null;
try{
    preparedStatement =connection.prepareStatement(sql);

    preparedStatement.setString(1, "aaa");
    preparedStatement.setLong  (2, 123);
    preparedStatement.addBatch();

    preparedStatement.setString(1, "bbb");
    preparedStatement.setLong  (2, 456);
    preparedStatement.addBatch();

    int[] affectedRecords = preparedStatement.executeBatch();// 返回每条语句执行影响的行数
}finally {
    if(preparedStatement != null) {
        preparedStatement.close();
    }
}

4: 事物transaction

 对出现异常的SQL代码进行回退(可能系统异常),保证数据一致性

4.1 基本处理

Connection connection = ...
try{
    connection.setAutoCommit(false);  // 这种处理方式 没有回滚点 出错将返回整个SQL代码
    // create and execute statements etc.
    connection.commit();
} catch(Exception e) {
    connection.rollback();
} finally {
    if(connection != null) {
        connection.close();
    }
}

4.2 断点事物处理

Connection conn = JdbcUtils.getConnection();
        PreparedStatement ps = null;
        Savepoint savepoint=null;  //断点
        try {
            conn.setAutoCommit(false);
            savepoint = conn.setSavepoint();  //设置当前断点1 当然可以有多个断点
            ps = conn.prepareStatement("update account set balance = balance - ? where name=?");
            ps.setInt(1, 500);
            ps.setString(2, "Jack");
            ps.executeUpdate();
            //出现异常
            System.out.println(100 / 0);
            //给 rose 加钱
            ps = conn.prepareStatement("update account set balance = balance + ? where name=?");
            ps.setInt(1, 500);
            ps.setString(2,"Rose");
            ps.executeUpdate();
            //提交事务
            conn.commit();
            System.out.println("转账成功");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                conn.rollback(savepoint);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
        }finally {
            JdbcUtils.close(conn, ps);
        }
    }

5 存储过程

DELIMITER //   # 分割符号 默认是; 在多条语句时候需要进行改变

DELIMITER //   # 分割符号 默认是; 在多条语句时候需要进行改变
CREATE PROCEDURE findStuById(IN pid INTEGER)
BEGIN
    SELECT * FROM student WHERE id=pid;
END //
DELIMITER ;

通过Call关键字调用储存过程 CallableStatement处理存储过程     PreparedStatement ==处理DML DML DQL

@Test
    public void test_producer() throws SQLException {
        Connection conn = JdbcUtils.getConnection();
        CallableStatement call = conn.prepareCall("CALL findStuByID(?)");

        call.setInt(1, 1);
        ResultSet resultSet = call.executeQuery();
        Student student=null;
        while(resultSet.next()) {
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            boolean gender = resultSet.getBoolean("gender");
            Date birthday = resultSet.getDate("birthday");
            student= new Student(id, name, gender, birthday);
        }
        System.out.println(student);
    }

6 元数据类型

6.1 DatabaseMetaData  数据库元数据

数据库基本信息

  Connection conn = JdbcUtils.getConnection();

		DatabaseMetaData metaData = conn.getMetaData();

		int majorVersion = metaData.getDatabaseMajorVersion();
		String productVersion = metaData.getDatabaseProductVersion();
		String driverName = metaData.getDriverName();
		String url = metaData.getURL();
		String userName = metaData.getUserName();
		System.out.println(majorVersion);//8
		System.out.println(productVersion);//8.0.13
		System.out.println(driverName);//MySQL Connector/J
		System.out.println(url);//jdbc:mysql://127.0.0.1:3306/day
		System.out.println(userName);//[email protected]

  

数据库所有信息的获取

getTableTypes()   方法 可以使用正则表达式

    Connection conn = JdbcUtils.getConnection();
        DatabaseMetaData metaData = conn.getMetaData();
        //
        String   catalog          = "day";  //对应数据库名称
        String   schemaPattern    = "*"; // mysql没有这个概念 sql server对应用户名称操作权限
        String   tableNamePattern = "student"; // 对应数据库名称
        String[] types            = {"TABLE"}; // 数据库中具体的类型 "TABLE"、"VIEW"、"SYSTEM TABLE"、"GLOBAL TEMPORARY"、"LOCAL TEMPORARY"、"ALIAS" 和 "SYNONYM"。 

        ResultSet result = metaData.getTables(
            catalog, schemaPattern, tableNamePattern, types );

        while(result.next()) {
            String catalogName = result.getString(1);
            String schemaName = result.getString(2);
            String tableName = result.getString(3);
            String columName = result.getString(6);
            System.out.println(tableName);
            System.out.println(catalogName);
            System.out.println(columName);
        }

 在表中列出列 getColumS()

Connection conn = JdbcUtils.getConnection();
        DatabaseMetaData metaData = conn.getMetaData();
        //
        String catalog = "day"; // 对应数据库名称
        String schemaPattern = "*"; // mysql没有这个概念 sql server对应用户名称操作权限
        String tableNamePattern = "student"; // 对应数据库名称
        String columnNamePattern = null;

        ResultSet result = metaData.getColumns(catalog, schemaPattern, tableNamePattern, columnNamePattern);

        while (result.next()) {
            String columName = result.getString(4);// 列名称
            String data_type = result.getString(5);// 列类型
            System.out.println(columName);
            System.out.println(data_type);
        }

主键信息

getPrimaryKeys() 获取主键信息

getExportedKeys() 获取外键信息

 Connection conn = JdbcUtils.getConnection();
        DatabaseMetaData metaData = conn.getMetaData();
        //
        String catalog = "day"; //执行库
        String schemaPattern = null; // mysql为null
        String tableNamePattern = "student";

        ResultSet result = metaData.getPrimaryKeys(catalog, schemaPattern, tableNamePattern);
        metaData.getExportedKeys(catalog, schema, table)
        while (result.next()) {
            String tablename = result.getString(3);// 表名
            String keyname = result.getString(4);//主键名
            System.out.println(tablename);
            System.out.println(keyname);

6.2 ParameterMetaData 参数元数据类型

对于传递的SQL中的参数(占位符? )的个数 数据进行处理

前提:

增加 &generateSimpleParameterMetadata=true

所有的参数认为是字符串(VARCHAR)类型

 注意:ParameterMetaData许多方法MySQL并不友好支持,比如像获取指定参数的SQL类型的getParameterType方法,如果数据库驱动连接URL只是简单的“jdbc:mysql://localhost:3306/jdbcdemo”那么MyEclipse会抛出SQLException异常,必须要将URL修改为“jdbc:mysql://localhost:3306/jdbcdemo?generateSimpleParameterMetadata=true”才行。但是像getParameterType等等与其他的方法也没多好用,因为如下面的例子,这些方法好像只会将所有的参数认为是字符串(VARCHAR)类型

public void test_ParameterINFO() throws SQLException {
        Connection conn = JdbcUtils.getConnection();
        String sql="SELECT * FROM STUDENT WHERE id=?";
        PreparedStatement preparedStatement = conn.prepareStatement(sql);

        ParameterMetaData pMetaData = preparedStatement.getParameterMetaData();
        preparedStatement.setInt(1, 1);

        int count = pMetaData.getParameterCount();
        for(int i = 1; i <= count; i ++) {
            System.out.print(pMetaData.getParameterClassName(i) + "\t");
            System.out.print(pMetaData.getParameterType(i) + "\t");
            System.out.println(pMetaData.getParameterTypeName(i));
        }
        //执行查询操作
        preparedStatement.executeQuery();
        //执行查询操作
        ResultSet rs = preparedStatement.executeQuery();

        while(rs.next()) {
            System.out.println(rs.getInt("id") + "\t"
                    + rs.getString("name") + "\t" + rs.getBoolean("gender")
                    + "\t" + rs.getDate("birthday"));
         }
    }

6.3 ResultSetMetaData 结果集元数据

通过 ResultSet.getMetaData();获取 ,主要对于表中的一些列进行获取,处理

Connection conn = JdbcUtils.getConnection();

        String sql="SELECT * FROM STUDENT WHERE id=?";
        PreparedStatement pStatement = conn.prepareStatement(sql);

        pStatement.setInt(1, 1);
        ResultSet reSet = pStatement.executeQuery();

        ResultSetMetaData metaData = reSet.getMetaData();

        int count = metaData.getColumnCount();

        for (int i = 1; i <= count; i++) {
            String columnClassName = metaData.getColumnClassName(i);//类型
            String columnName = metaData.getColumnName(i);//列名
            int columnType = metaData.getColumnType(i);//列属性值
            String typeName = metaData.getColumnTypeName(i);//列类型名
            String label = metaData.getColumnLabel(i);//列名
            System.out.println(columnClassName+"\t"+columnName+"\t"+columnType+"\t"+typeName+"\t"+label);
        }

原文地址:https://www.cnblogs.com/dgwblog/p/11797616.html

时间: 2024-11-08 23:57:13

JDBC进阶 元数据的相关文章

Jdbc进阶(三)

******************可滚动.可更新的结果集***************** 1.可滚动的结果集JDK1.4之前默认打开的结果集不可随意滚动,如果想让结果集可以实现前后滚动等需要额外添加参数,从JDK5.0开始默认打开的结果集可以实现 滚动,可以用next.absolute.previouse.beforeFirst.first.last.afterLas移动结果集的指针,这种结果集叫做可滚动的结果集. 2.可更新的结果集 JDK5.0默认打开的结果集是不可更新的,如果想打开可更

JDBC:元数据 &amp;&amp; 获取插入记录的主键值 &amp;&amp; _JDBC_处理 Blob

一.元数据 DatabaseMetaData类 DatabaseMetaData 类中提供了许多方法用于获得数据源的各种信息,通过这些方法可以非常详细的了解数据库的信息: getURL():返回一个String类对象,代表数据库的URL. getUserName():返回连接当前数据库管理系统的用户名. isReadOnly():返回一个boolean值,指示数据库是否只允许读操作. getDatabaseProductName():返回数据库的产品名称. getDatabaseProductV

JDBC进阶

PreparedStatement的使用: conn = DriverManager.getConnection("jdbc:mysql://localhost/mydata?" + "user=root&password=root"); pstmt = conn.prepareStatement("insert into dept values (?,?,?)"); pstmt.setInt(1,deptno); pstmt.setSt

JDBC进阶之PreparedStatement执行SQL语句(MySQL)

一.什么是PreparedStatement 参阅Java API文档,我们可以知道,PreparedStatement是Statement的子接口(如图所示),表示预编译的 SQL 语句的对象,SQL 语句被预编译并存储在PreparedStatement 对象中.然后可以使用此对象多次高效地执行该语句. 二.通过PreparedStatement获取在运行命令行中执行的参数,将参数插入到某张数据表中 相关的实验过程,包括在预先创建程序所需数据库.创建所需数据表格.在开发环境中加载驱动程序包等

JDBC 获取元数据DatabaseMetaData

package org.data.jdbc; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; public

由浅到深学习JDBC一

JDBC: 虽然由于快节奏的开发,编程速度的追求,越爱越多的MVC框架出现,比如持久层的hibernate, mybatis等等,他们对Dao层的支持都很强大,既快速,又简便.但是他们的底层同样是使用了JDBC, 为了追求高速简便,我们可以不使用JDBC,但一定要了解JDBC.了解JDBC也有助于学习其他持久层框架. java和数据库交互需要中间程序作为中转.在很早以前,数据库厂商还没有一套统一的API作为 java语言和数据库的接口,开发程序是一件很头疼的事.对不同的数据库需要写不同的程序来作

jdbc就是这么简单

一.JDBC JAVA Database Connectivity java 数据库连接. JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序,同时,JDBC也是个商标名. 二.为什么会出现JDBC SUN公司提供的一种数据库访问规则.规范, 由于数据

Ubuntu + hadoop 2.7 + hive 1.1.1 + sprk 初装成功分享 有什么问题大家一起讨论

在网上看过的安装教程真的是有点心酸呢.好多都失败了. 分享下,自己实验成功可以用的博文供大家参考: 推荐1给力星:http://www.powerxing.com/install-hadoop/ hadoop+spark 完全参考的他的博文,相当给力推荐指数5个星 hive的话,我这边参考的文章太多了.没个能用的,不知道是我自己弄的不对还是怎么回事. ..... 最后无意间看到hive变成指南这本书,里面的教程安装成功的. [email protected]:/usr/local/hadoop/

第九周java学习总结

20145306<java程序设计>第九周学习总结 教材学习内容总结 第十六章 一.JDBC入门 1.JDBC简介 JDBC是用于执行SQL的解决方案,开发人员使用JDBC的标准接口,数据库厂商则对接口进行操作,开发人员无须接触底层数据库驱动程序的差异性,数据库本身是个独立运行的应用程序,你撰写的应用程序是利用通信协议对数据库进行指令交换,以进行数据的增删查找.通常你的应用程序会利用一组专门与数据库进行通信协议的链接库,以简化与数据库沟通时的程序撰写.有时候,更换数据库的需求并不是没有,应用程