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 更新操作执行必须执行

:moveToInsertRow()  是把ResultSet移动到插入行 这个插入行是表中特殊的一行
moveToCurrentRow() 移动到插入行 如果之前Insert,那么就移动到之前Insert()0哪一行,没有Insert 就没有效果
:UpdateXXX()
: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(,"Fant.J");
preparedStatement.setInt(,);
int result = preparedStatement.executeUpdate(); // 第一次使用 preparedStatement.setString(,"Fant.J reUseTest");
preparedStatement.setInt(,);
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(, "aaa");
preparedStatement.setLong (, );
preparedStatement.addBatch(); preparedStatement.setString(, "bbb");
preparedStatement.setLong (, );
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(, );
ps.setString(, "Jack");
ps.executeUpdate();
//出现异常
System.out.println( / );
//给 rose 加钱
ps = conn.prepareStatement("update account set balance = balance + ? where name=?");
ps.setInt(, );
ps.setString(,"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(, );
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()   方法 可以使用正则表达式

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

JDBC进阶 元数据的更多相关文章

  1. day16(jdbc进阶,jdbc之dbUtils)

    1.jdbc进阶 jdbc事务管理 jdbc中的事务管理其实就是交给了连接对象去管理.先写一个简单的事务管理 public class Demo01 { private static Connecti ...

  2. MYSQL 之 JDBC(十): JDBC的元数据

    可以从Connection对象中获得有关数据库管理系统的各种信息 获取这些信息的方法都是在DatabaseMetaData类中. DatabaseMetaData:描述数据库的元数据对象 Result ...

  3. JDBC进阶

    PreparedStatement的使用: conn = DriverManager.getConnection("jdbc:mysql://localhost/mydata?" ...

  4. Apache kylin进阶——元数据篇

    一.Apache kylin元数据的存储 Apache kylin的元数据包括 立方体描述(cube description),立方体实例(cube instances)项目(project).作业( ...

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

    一.什么是PreparedStatement           参阅Java API文档,我们可以知道,PreparedStatement是Statement的子接口(如图所示),表示预编译的 SQ ...

  6. JDBC 进阶:使用封装通用DML DQL 和结构分层以及at com.mysql.jdbc.PreparedStatement.setTimestamp空指针异常解决

    准备: 数据表 CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(10) DEFAULT ...

  7. jdbc详解(三)

    开源数据库连接池 l 现在很多 WEB 服务器 ( Weblogic , WebSphere , Tomcat) 都提供了 DataSoruce 的实现,即连接池的实现.通常我们把 DataSourc ...

  8. JDBC学习DayTwo

    一.利用反射及JDBC元数据编写通用的查询方法 1.ResultSetMetaData 定义:描述ResultSet的元数据对象,即从中可以获取到结果集中有多少列.列名是什么. 获取 ResultSe ...

  9. ref:Spring JDBC框架

    ref:https://blog.csdn.net/u011054333/article/details/54772491 Spring JDBC简介 先来看看一个JDBC的例子.我们可以看到为了执行 ...

随机推荐

  1. Windows10安装ubuntu18.04双系统教程

    写在前面:本教程为windows10安装ubuntu18.04(64位)双系统教程,是我多次安装双系统的经验总结,安装方法同样适用于ubuntu16.04(64位).为了直观和易于理解,我会尽量图文并 ...

  2. [译]Vulkan教程(20)重建交换链

    [译]Vulkan教程(20)重建交换链 Swap chain recreation 重建交换链 Introduction 入门 The application we have now success ...

  3. Yii2 中常用的增删改查操作总结

    一.新增 1.使用save() $model = new User(); $model->name = 'test'; $model->phone = '13000000000'; $mo ...

  4. C#添加错误日志信息

    错误日志是软件用来记录运行时出错信息的文本文件.编程人员和维护人员等可以利用错误日志对系统进行调试和维护. 系统日志 系统日志包含了由Windows系统组件记录的事件.例如,在启动期间装入驱动程序或其 ...

  5. java spring是元编程框架---使用的机制是注解+配置

    java spring是元编程框架---使用的机制是注解+配置

  6. spark log4j 日志配置

    现在我们介绍spark (streaming) job独立配置的log4j的方法,通过查看官方文档,要为应用主程序(即driver端)或执行程序使(即executor端)自定义log4j配置,需要两步 ...

  7. opencv与mfc显示图片操作,MFC的鼠标响应在opencv图片上失效,opencv滚轮事件没有响应问题描述解决。

    原文作者:aircraft 原文链接:https://www.cnblogs.com/DOMLX/p/11588758.html 用mfc 与OPENCV编写成. 出了很多冲突异常事件导致鼠标操作没有 ...

  8. Java每日一面(Part1:计算机网络)[19/10/21]

    作者:故事我忘了¢个人微信公众号:程序猿的月光宝盒 1.UDP简介 1.1UDP报文结构: ​ Source Port:源端口 Destination Port:目标端口 Length:数据包长度 C ...

  9. 关于scrapy中如何区分是接着发起请求还是开始保存文件

    一.区分 根据yield迭代器生成的对象是request对象还是item对象 二.item 1.配置tem对象 在items.py文件中设置类 class MyscrapyItem(scrapy.It ...

  10. 最小割最大流定理&残量网络的性质

    最小割最大流定理的内容: 对于一个网络流图 $G=(V,E)$,其中有源点和汇点,那么下面三个条件是等价的: 流$f$是图$G$的最大流 残量网络$G_f$不存在增广路 对于$G$的某一个割$(S,T ...