📄 08. jdbc note.txt
字号:
字段名字:meta.getColumnName();
字段JDBC类型:meta.getColumnType();
字段数据库类型:meta.getColumnTypeName();
数据库元数据对象:DatabaseMetaData dbmd = con.getMetaData();
数据库名:dbmd.getDatabaseProductName();
数据库版本号:dbmd.getDatabaseProductVersion();
数据库驱动名:dbmd.getDriverName();
数据库驱动版本号:dbmd.getDriverVersion();
数据库Url:dbmd.getURL();
该连接的登陆名:dbmd.getUserName();
四、JDBC 中使用Transaction编程(事务编程)
1. 事务是具备以下特征(ACID)的工作单元:
原子性(Atomicity)—— 如果因故障而中断,则所有结果均被撤消;
一致性(Consistency)—— 事务的结果保留不变;
孤立性(Isolation)—— 中间状态对其它事务是不可见的;
持久性(Durability)—— 已完成的事务结果上持久的。
原子操作,也就是不可分割的操作,必须一起成功一起失败。
2. 事务处理三步曲:(事务是一个边界)
① connection.setAutoCommit(false); //把自动提交关闭;在创建Statement对象之前。
② 正常的DB操作 //若有一条SQL语句失败了,自动回滚
③ connection.commit() //主动提交
和 connection.rollback() //主动回滚,一般写在catch语句里,而前三个都写在try语句里
/*********事务的代码片段:*************/
try{
con.setAutoCommit(false); //step① 把自动提交关闭
Statement stm = con.createStatement(); //step② 正常的DB操作
stm.executeUpdate("insert into person(id, name, age) values(520, 'X-Man', 18)");
stm.executeUpdate("insert into Person(id, name, age) values(521, 'Super', 19)");
con.commit(); //step③ 成功主动提交
} catch(SQLException e){
try{con.rollback(); //如果中途发生异常,则roolback;这语句也会抛异常
}catch(Exception e){e.printStackTrace();} //step③ 失败则主动回滚
/************************************/
3.JDBC事务并发产生的问题和事务隔离级别(难,建议用例子学习)
JDBC事务并发产生的问题:
① 脏读(Dirty Reads) 一个事务读取了另一个并行事务还未提交的数据。(产生原因:读-写)
② 不可重复读(UnPrpeatable Read)一个事务前后两次读取数据时,得到的数据不一致,被另一个已提交的事务修改。
③ 幻读(Phantom Read) 一个事务再次查询,记录中的量变化了。(仅对统计有影响)
为了避免以上三种情况的出现,则采用事务隔离级别:
TRANSACTION_NONE 不使用事务(不可能用,只是理论的)
TRANSACTION_READ_UNCOMMITTED 可以读取未提交数据(允许脏读,也不可能)
TRANSACTION_READ_COMMITTED 只读提交的数据:可防止脏读;大部分数据库的默认隔离级别
TRANSACTION_REPEATABLE_READ 重复读取;只可以避免脏读
TRANSACTION_SERIALIZABLE 事务串行化:可以避免脏读,重复读取和幻读,但会降低数据库效率(最常用)
以上的五个事务隔离级别都是在Connection类中定义的静态常量。隔离级别越高,数据越安全,并发能力越差。
使用setTransactionIsolation(int level) 方法可以设置事务隔离级别。
比如:con.setTransactionIsolation(Connection.TRANSACTION_READ_UNCOMMITTED);
五、JDBC 2.0新特性:
1、 Scrollability 结果集可滚动
滚动:可双向支持绝对与相对滚动,对结果集可进行多次迭代。
Con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
//上句的 SCROLL 再到 CONCUR;不可以写反,编译器无法检测到,因为他们都是int类型的。
TYPE_FORWARD_ONLY:(单向,一般不用)该常量指示指针只能向前移动的 ResultSet 对象的类型。
TYPE_SCROOL_INSENSITIVE:(双向、不敏感)可滚动但不受其他更改影响的 ResultSet 对象的类型。
TYPE_SCROLL_SENSITIVE:(双向、敏感)该常量指示可滚动并且通常受其他的更改影响的 ResultSet 对象的类型。
CONCUR_READ_ONLY:(只读)该常量指示只可以读取的 ResultSet 对象的并发模式。
CONCUR_UPDATABLE:(可更新)该常量指示可以更新的 ResultSet 对象的并发模式。
绝对定位:boolean absolute(int row)将游标移动到指定位置。(row指记录的序号,没有这位置则返回false)
void afterLast() 将游标指向最后一条记录的后一位(有这位置,但记录为空)。
void beforeFirst()将游标指向最前一条记录的前一位。
boolean first()将游标移动到结果集最前。
boolean last()将游标移动到结果集末尾。
相对定位:boolean next()指向下一个。
boolean previous()指向前一个。
boolean relative(int) 向next()方向移动 int 位(int 可负)。
判位函数:boolean isAfterLast() 是否在最后一条的后一位。
boolean isBeforeFirst() 是否最前一条记录的前一位。
boolean isFirst() 是否最前位置。
boolean isLast() 是否最后位置。
2、 Updatability 结果集可更新。(主要应用于桌面应用)
更新:rs.updateString(“name”,”Tony”);//前面一个是字段的名字或者序号
rs.updateInt(1,”122323”);修改
rs.deleteRow();删除
rs.updateRow();
注:只有在必要的时候(如桌面应用)才用结果集更新数据库,因为使用结果集更新数据库效率低下。
可更新结果集还要看数据库驱动程序是否支持,如Oracle就支持,MySql不支持。
并且只能针对一张表做结果集更新(不能子查询)。而且不能有join操作。
必须有主健,必须把所有非空没有默认值的字段查出。
处理可更新结果集时不能用select *来查询语句,必须指出具体要查询的字段。(不能使用通配符)
3、 Batch updates 可批量更新。
将多组对数据库的更新操作发送到数据库统一执行(数据库支持并发执行操作),以提高效率。
主要是通过减少数据(Sql语句或参数)在网络上传输的次数来节省时间。//数据有两组以上都应该用这批量更新
(1)对于Statement的批量更新处理:
stm.addBatch(Sql);
int[] ResultSet=stm.executeBatch();
(2)对于PreparedStatement的批量跟新处理
pstm.setInt(1,12);pstm.setString(2,”gaga”);……..
pstm.addBatch();
if(i%100==0) int[] ResultSet=pstm.executeBatch();//每个包50~200组数据,包太大也影响速度
注:int[] 中每一个数表示该Sql语句影响到的记录条数。
PreparedStatement的更新操作比Statement的更新操作多了一个设置参数的过程。
六、SQL 3.0规范中的新类型:
Blob,大的二进制数据文件,最多存储2G。
Clob,大文本文件对象,最多存储2G。
在使用上述大对象的时候,在使用JDBC插入记录时要先插入一个空的占位对象,
"insert into tableName valuse(?,?,empty_blob())"//在数据库制造一个空的blob对象字段值
然后使用"select blobdata from t_blob where id = ? for update"对获得的大对象进行实际的写入操作
Blod通过getBinaryOutputStream()方法获取流进行写入。
getBinaryStream()方法获得流来获取Blob中存储的数据。
Clob的操作也和、Blob相同。
getAsciiStream()用于读取存储的文本对象,getAsciiOutputStream()方法之获得流用来向文件对象写入的。
BLOB与CLOB的异同点:
① 都可以存储大量超长的数据;
② BLOB (Binary Large Object) 以二进制格式保存,特别适合保存图片、视频文件、音频文件、程序文件等;
③ CLOB (Character Large Object) 以Character格式保存于数据库中,适合保存比较长的文本文件。
七、JDBC 2.0扩展
(一)JNDI(命名目录服务器):
定义:是Java的命名目录服务器。而JDBC是Java的数据库访问接口。
跟JDBC是平级的关系,是两个独立的JNDI;JDBC存储的数据都是以二维表的接口来大规模存储数据。
而JNDI存储的是差异性比较大的Java对象。JDBC取数据时用Sql语言访问数据。JNDI只用lookup和bind读写
JDBC API依赖于驱动程序,而JNDI依赖于服务提供者。
JDBC一般把数据存储到关系型数据库,而JNDI一般把数据存储到小型数据库、文件、甚至是注册表中。
JNDI相当于一个电话本。允许程序将一个对象和一个命名绑定到目录树上。
(JNDI的方法是在javax.naming包下,接口是Context实现类是InitialContext)
bind(String name, Object obj) 将名称绑定到对象资源,建立指定的字符串和对象资源的关联
lookup(String name) ,通过指定的字符串获得先前绑定的资源
/*********以下是将资源和JNDI命名绑定的方法**************/
public static void bind(String context, Object obj) throws NamingException{
Properties pro = new Properties();
//Weblogic的JNDI服务器参数
pro.put(InitialContext.INITIAL_CONTEXT_FACTORY,"weblogic.jndi.WLInitialContextFactory");
pro.put(InitialContext.PROVIDER_URL, "t3://localhost:7001");
Context ctx = new InitialContext(pro);//连接服务器
ctx.bind(context, obj);//存储
}
(二)DataSourse(数据源)
1、包含了连接数据库所需的信息,可以通过数据源获得数据库连接,
有时由于某些连接数据库的信息会变更,所以经常使用包含数据库连接信息的数据源。
2、一个标准的数据库连接工厂,作为DriverManager的替代项,保存与数据库相关的信息,
可以将数据库的连接信息放在一个共享的空间进行提取,不用在本地安装。
支持JNDI的绑定,支持连接池,支持分布式服务,用getConnection方法可获得与数据库的连接。
数据源应该由管理员创建(目的是为了保证数据库的安全)。所以数据源对象一般放在JNDI服务器中。
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -