JDBC进阶 元数据

网友投稿 744 2022-09-02

JDBC进阶 元数据

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  数据库元数据​​

​​在表中列出列​​

​​主键信息​​

​​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类型

移动绝对行 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语句必须要具备如下的属性: 通过 并发下面属性设置

只引用了单个表.

不含有join或者group by子句.

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

执行顺序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: 基本操作

执行查询

执行CUD操作

执行DDL操作

执行超大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 是不变的

//创建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 性能分析

是Statement的子类,区别:

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

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

两个级别的复用:

驱动程序重新使用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);//root@localhost

数据库所有信息的获取

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

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); }

在表中列出列

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); }

主键信息

获取主键信息

获取外键信息

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中的参数(占位符? )的个数 数据进行处理

前提:

增加

所有的参数认为是字符串(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); }

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:用PHP屏蔽关键字,敏感词,你用哪些方法(php全站过滤敏感词)
下一篇:并发工具类:AQS有哪些作用?(一)
相关文章

 发表评论

暂时没有评论,来抢沙发吧~