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. diango url的命名和反向解析

    url的命名和反向解析 静态路由 url(r'^login/', views.login,name='login'), 反向解析ht 模板 {% url 'login' %} --> '/app ...

  2. PostgreSQL中的onflict

    PostgreSQL 9.5 引入了一项新功能,UPSERT(insert on conflict do),当插入遇到约束错误时,直接返回,或者改为执行UPDATE. 1.不存在则插入,存在则更新 i ...

  3. 基于django的个人博客网站建立(五)

    基于django的个人博客网站建立(五) 前言 网站效果可点击这里访问 之前鸽了两天,今天继续再写点 主要内容 今天加了个展示照片的功能,就叫他生活记录吧 先建表 class Record(model ...

  4. yml和properties的加载顺序和区别

    正常的情况是先加载yml,接下来加载properties文件.如果相同的配置存在于两个文件中.最后会使用properties中的配置.最后读取的优先集最高. 两个配置文件中的端口号不一样会读取prop ...

  5. Qt的诞生和本质

    有没有发现,在这个主函数里面没有了消息循环了.消息循环到哪里去了呢? 我们知道,每个GUI应用程序都有消息循环,一般都需要将消息循环while那个函数写到main的最后位置.那既然如此,为了代码复用, ...

  6. mysql分组报错Expression #1 of SELECT list is not in GROUP BY clause and contains nonaggregated column

    环境:Server version: 5.7.27-0 ubuntu 18.04.1 (Ubuntu) 执行分组语句:select * from pet group by owner;时报错: mys ...

  7. 如何使redis中存放的都是热点数据?

    当redis使用的内存超过设置的最大内存时,会触发redis的key淘汰机制,在redis3.0中的6中淘汰策略如下: (1)noeviction :不删除策略.当达到最大内存限制时,如果需要使用更多 ...

  8. IT兄弟连 HTML5教程 HTML5文字版面和编辑标签 小结及试题

    小结 HTML标签包含结构标签和基础标签,基础标签是在页面制作最常使用的一些标签.基础标签包含标题标签(<h1>~<h6>).换行标签(<br>).段落标签(< ...

  9. Google Chome浏览器下如何开发UHF读写器

    google Chrome浏览器不支持ocx,也就不能通过ocx来连接UHF读写器,只能使用RFID读写器云服务插件,通过javascript语言来连接和操控UHF读写器YW-602H.RFID读写器 ...

  10. SQL Server 通过游标重新定义单据数据的单据编号

    DECLARE @Index INTSET @Index=100DECLARE UpdateCursor  CURSOR  FOR (SELECT DISTINCT AA.Id FROM dbo.表 ...