深入浅出学Oracle&JDBC 之 第二部分:SQL(2)【私塾在线原创】
2012-02-29 11:49
375 查看
事务
事务是什么用来维护数据库完整性,它保证成批的 SQL 要么全做,要么全不做。
1 、事务特性( ACID )事务必需满足 ACID ,缺一不可
原子性( Atomicity ):即事务是不可分割的最小工作单元,事务内的操作要么全做,要么全不做;
一致性( Consistency ):在事务执行前数据库的数据处于正确的状态,而事务执行完成后数据库的数据还是处于正确的状态,即数据完整性约束没有被破坏;如银行转帐,A转帐给B,必须保证A的钱一定转给B,一定不会出现A的钱转了但B没收到,否则数据库的数据就处于不一致(不正确)的状态;
隔离性( Isolation ):并发事务执行之间无影响,在一个事务内部的操作对其他 事务是不产生影响,这需要事务隔离级别来指定隔离性;
持久性( Durability ):事务一旦执行成功,它对数据库的数据的改变必须是永久的,不会因为如遇到系统故障或断电造成数据不一致或丢失。
事务处理
事务( transaction ):一组 SQL 语句;
回滚( rollback ) :撤销指定 SQL 语句的过程;
提交( commit ) :执行指定 SQL 语句;
保留点( savepoint ):事务处理中设置的临时占位符,可以对保留点执行回滚
示例如下:
delete from tbl_student;
commit;-- 提交事务,全部删除了
delete from tbl_student;
rollback;-- 回滚了事务,删除被撤销了
SQL实战
1 、不连续数谜题 : 找到表中没有的最小的 TBL_NUM ( num )Num
1
3
4
7
7
select min(num1.num+1) from TBL_NUM num1
where num1.num+1 not in (select num2.num from TBL_NUM num2);
2 、删除重复行 , 删除最先插入的
delete from tbl_num
where rowid not in (select max(rowid) from tbl_num group by num)
3 、分页
--3 、分页
select s2.* from
--2 、为检索出的数据加行号
(select s1.*, rownum r from
( --1 、最内层检索真正的数据
select * from tbl_student where 1=1
) s1
) s2
-- 分页条件
where s2.r>=1 and s2.r<3
分页三步曲:
1、检索记录
2、加行号
3、根据行号对结果分页
1 、检索张三所有孩子
Select * from tbl_tree where puuid=(select uuid from tbl_tree where name ='张三')
2 、检索张四的兄弟
Select * from tbl_tree where puuid=(select puuid from tbl_tree where name ='张四')
3 、检索张三的孙子
Select * from tbl_tree where puuid in (
select uuid from tbl_tree where puuid =(
select uuid from tbl_tree where name ='张三'))
4 、检索张三的孩子和孙子
Select * from tbl_tree where puuid=(select uuid from tbl_tree where name ='张三')
union
Select * from tbl_tree where puuid in (
select uuid from tbl_tree where puuid =(
select uuid from tbl_tree where name ='张三'))
5 、找张三的子子孙孙(包括重孙等)(递归查询)
select * from tbl_tree
where name!='张三‘
start with name='张三'
connect by prior uuid = puuid
--1 、递归开始:根结点的限定语句,当然可以放宽限定条件,以取得多个根结点,实际就是多棵树。 如 start with name= ‘ 张三 ’ 表示从张三开始
--2 、连接条件:[connect by] [prior] uuid = puuid,其中用prior表示上一条记录,比如 connect by prior uuid = puuid就是说上一条记录的uuid是本条记录的puuid,即前一条记录是当前记录的父亲。
--3 、递归方向: prior运算符在一侧表示父节点,在另一侧表示子节点,从而确定查找树结构是的顺序是自顶向下还是自底向上。
--4 、过滤条件:where子句,用于对返回的所有记录进行过滤
-- 加层次 level
select lpad(name, level*2+2,' ') from tbl_tree
connect by prior uuid = puuid
start with name='张三'
5 、前边递归做法是 oracle 特有的,再介绍个通用的 code 法 ( 无递归 )
地区表
java代码:
create table TBL_AREA2 (UUID NUMBER not null, NAME VARCHAR2(100), CODE VARCHAR2(100), constraint PK_AREA primary key (UUID), constraint INDEX_AREA_CODE unique (CODE) using index); insert into tbl_area2 values(1,'中国','01'); insert into tbl_area2 values(2,'上海','0101'); insert into tbl_area2 values(3,'深圳','0102'); insert into tbl_area2 values(4,'北京','0103'); insert into tbl_area2 values(5,'海淀','010301'); insert into tbl_area2 values(6,'朝阳','010302');
Code组成:由父的code+自己在兄弟里的大排名,每进入一层code长度加2
code列是唯一索引
6 、前边递归做法是 oracle 特有的,再介绍个通用的 code 法
1 、检索中国的孩子
Select * from tbl_area where code like '01__'
2 、检索中国的孙子
Select * from tbl_area where code like '01____'
3 、检索中国的子和孙(不包括重孙)
Select * from tbl_area where code like '01__' or code like '01____'
4 、检索中国的子孙(包括重孙)
Select * from tbl_area where code like '01__%'
5 、查询厂洼属于的城市 ( 不好向上递归,在 java 里做 )
Select * from tbl_area
where code =(select substr(code,0, 4) from tbl_area where name='厂洼')
6、查询厂洼所属城市的所有区
Select * from tbl_area
where code like (select substr(code,0, 4) || '__' from tbl_area where name='厂洼')
Oracle 递归支持和 Code 法比较
--1、puuid只有在Oracle里才好用,从通用性上来看code更好
--2.1、puuid number(10)
--2.2、code varchar2(100) 层数和一个父最多有多少个子有限制
--2.3、code列的规则一旦定下来很难改变
--3、移动节点(包括子节点)
puuid简单,只需更新父亲即可;
code麻烦,不仅需要更新父亲,连孩子都得修改;
oracle 内部支持法:把张四移到张五
update tbl_tree set puuid=(select uuid from tbl_tree where name='张五')
where name='张四';
code 法:如把北京移动到上海下边 ( 首先把北京移动到上海下,然后更新北京的孩子 )
update tbl_area set code='010101'||substr(code,5) where code like '0103%';
数据库设计优化
JDBC
是什么?JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。
JDBC为工具/数据库开发人员提供了一个标准的API,据此可以构建更高级的工具和接口,使数据库开发人员能够用纯 Java API 编写数据库应用程序。
能干什么?
标准的数据访问接口,可以连到不同的数据库;
发SQL查询字符串到数据库;
在Java应用程序中进行数据库的增删改查
有什么?
驱动程序 Driver
连接 Connection
语句 Statement/PreparedStatement
HelloWorld
1 、开发环境和运行环境准备
开发环境: java 工程 +oracle 数据库
运行环境: java SE+oracle 数据库
2 、准备 jar 包: ojdbc14.jar ( Oracle 驱动包)
3 、写客户端测试
java代码:
import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; public class ClientTest { public static void main(String[] args) throws ClassNotFoundException { //1. 注册加载一个 driver 驱动 Class. forName ("oracle.jdbc.driver.OracleDriver"); Connection conn = null; try { //2 创建数据库连接 String url = "jdbc:oracle:thin:@localhost:1521:orcl"; String username = "test"; String password = "test"; conn = DriverManager. getConnection (url, username, password); //3 创建一个 Statement (发送 sql ) Statement stat = conn.createStatement(); //4 执行 SQL stat.execute("insert into tbl_student values(11,'zhang', 1, '1')"); //5 处理结果(无) //5 关闭 Statement stat.close(); } catch (SQLException e) { e.printStackTrace(); } finally { try {//6 关闭连接 conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } }
Statement 与 PreparedStatement 区别
1 、 PreparedStatement 能防止 SQL 注入问题,而 Statement 是动态拼出SQL ,因此不 能解决;
2 、 PreparedStatement 对 SQL 进行预编译,因此如果我们采用绑定变量的SQL (语句 类似,数据不同)数据库只需解析一次(生成执行计划),因此效率要高;
3 、 Statement 由于没有采用绑定变量,因此可能每次都需要编译(生成执行计划),因 此对于那种语句类似但数据不同的 SQL 每次都需要编译,效率低;
4 、 PreparedStatement 开销要比 Statement 高, 因此如果 SQL 只执行一次,应该使用 Statement 。
5 、在大多数情况下都应该使用 PreparedStatement 。
java代码:
–Driver –DriverManager –Connection –Statement –PreparedStatement –CallableStatement –ResultSet –DatabaseMetadata –ResultSetMetadata –Types
数据库元数据
数据库元数据和结果集元数据
1 、 DatabaseMetadata
使用conn.getMetadata方法获得;
提供了获取数据库相关数据信息的能力(如数据库对象)。
2 、 ResultSetMetadata
使用 ResultSet.getMetaData方法获得;
提供了各种方法去获得结果集元数据的相关数据信息,包括结果集的总行数
批量更新
批量更新,即一次提交多条同构更新操作语句给数据库
JDBC API 在批量更新之后只产生一个结果集对象
以下均支持批量更新
Statement
PreparedStatement
CallableStatement
Statement 批量更新
语法
java代码:
Statement stmt = con.createStatement(); stmt.addBatch(sqlStr);
示例
java代码:
con.setAutoCommit(false); Statement stmt = con.createStatement(); stmt.addBatch(“insert into tbl_users values(1, ‘z1’, 1, ‘1’)”); stmt.addBatch(“insert into tbl_users values(2, ‘z2’, 1, ‘1’)”); int[] results = stm.executeBatch(); con.commit();
PreparedStatement 批量更新
PreparedStatement 中使用批量更新时,一定要先设置好参数后,再使用addBatch() 方法加入缓存,最后一起发送到数据库。
语法
java代码:
PreparedStatement pstmt = con.prepareStatement(sqlStr); pstmt.setXXX(..); pstmt.addBatch(); pstmt.excuteBatch();
示例
java代码:
String sql = “ insert into tbl_student values(?,?,?,?) ” ; PreparedStatement pstm = con.prepareStatement(sql); pstm.setInt(1, 1); pstm.setString(2, “zhang1”); pstm.setInt(3,1); pstm.setString(4,’1’); pstm.addBatch(); int[] counts = pstm.excuteBatch(); con.commit(); Blob 和 Clob
1 、需要存储如图片、 word 文件等字节类型数据,请使用 Blob
2 、需要存储大文本数据,请使用 clob
java代码:
//1 、插入(通过 empty_clob() 来初始化 resourceValue ) String insertSql = "insert into tbl_resource" + "(uuid, title, resourceValue) values(?,?, empty_blob() )"; PreparedStatement pstat = conn.prepareStatement(insertSql); pstat.setInt(1, 1); pstat.setString(2, "test"); pstat.executeUpdate(); pstat.close(); //2 、锁定要修改的数据行进行更新,注意 "for update" 语句 String selectForUpdateSql = "select resourceValue " + "from tbl_resource where uuid=? for update"; pstat = conn.prepareStatement(selectForUpdateSql); pstat.setInt(1, 1); ResultSet rs = pstat.executeQuery(); // 读取 blob 数据 Blob blob = null; if(rs.next()) { blob = rs.getBlob("resourceValue"); } // 将图片字节数据输出到 Blob 对象里 String fileName = "D:/Blue hills.jpg"; FileInputStream fis = new FileInputStream(fileName); byte[] bytes = new byte[fis.available()]; fis.read(bytes); fis.close(); OutputStream os = blob.setBinaryStream(0); os.write(bytes); os.close(); pstat.close(); String selectSql = "select * from tbl_resource where uuid=?"; PreparedStatement pstat = conn.prepareStatement(selectSql); pstat.setInt(1, 1); ResultSet rs = pstat.executeQuery(); // 读取 blob 数据 if(rs.next()) { String title = rs.getString("title"); Blob blob = rs.getBlob("resourceValue"); byte[] bytes = blob.getBytes(1, (int) blob.length()); File file = new File("D:\\Backup\\" + title + ".jpg"); FileOutputStream fos = new FileOutputStream(file); fos.write(bytes); fos.close(); } pstat.close();
Clob 新增 & 修改
java代码://1 、插入(通过 empty_clob() 来初始化 resourceValue ) String insertSql = "insert into tbl_content" + "(uuid, title, content) values(?,?, empty_clob() )"; PreparedStatement pstat = conn.prepareStatement(insertSql); pstat.setInt(1, 1); pstat.setString(2, "test"); pstat.executeUpdate(); pstat.close(); Clob 新增 & 修改 //2 、锁定要修改的数据行进行更新,注意 "for update" 语句 String selectForUpdateSql = "select content " + "from tbl_content where uuid=? for update"; pstat = conn.prepareStatement(selectForUpdateSql); pstat.setInt(1, 1); ResultSet rs = pstat.executeQuery(); // 读取 blob 数据 Clob clob = null; if(rs.next()) { clob = rs.getClob("content"); } //3 、更新 Clob 内容 clob.setString(1, "test 中文 "); pstat.close(); Clob 查询 String selectSql = "select content from tbl_content where uuid=?"; PreparedStatement pstat = conn.prepareStatement(selectSql); pstat.setInt(1, 1); ResultSet rs = pstat.executeQuery(); // 读取 C lob 数据 Clob clob = null; if(rs.next()) { clob = rs.getClob("content"); } System. out .println(clob.getSubString(1, (int) clob.length())); pstat.close();
视频配套PPT,视频地址【Oracle数据库开发及SQL基础视频 】原创内容 转自请注明【http://sishuok.com/forum/blogPost/list/0/3775.html#8875】
相关文章推荐
- 深入浅出学Oracle&JDBC 之 第一部分:关系数据库基础【私塾在线原创】
- 深入浅出学Oracle&JDBC 之 第二部分:SQL(1)【私塾在线原创】
- Java WEB开发实战 之 第二部分:Web应用基础知识【私塾在线原创】
- 【第七章】 对JDBC的支持 之 7.4 Spring提供的其它帮助 ——跟我学spring3【私塾在线原创】
- ORACLE SQL and SQL*PLUS 第二部分
- Shiro的Web——深入浅出学Shiro细粒度权限开发框架——私塾在线原创
- 【第七章】 对JDBC的支持 之 7.5 集成Spring JDBC及最佳实践 ——跟我学spring3【私塾在线原创】
- Java WEB开发实战 之 第三部分:Servlet开发(1)【私塾在线原创】
- ORACLE SQL and SQL*PLUS 第二部分
- Oracle SQL*Loader 使用指南(第二部分)
- 【第七章】 对JDBC的支持 之 7.4 Spring提供的其它帮助 ——跟我学spring3【私塾在线原创】
- oracle(sql优化)- 第二部分 常用sql用法和注意事项
- 无法加载oracle in oradb10g_home2 odbc驱动程序,系统错误代码998解决方法(转载+部分原创)
- Oracle 11g 新特性-PL/SQL部分
- Tomcat配置JNDI提示:org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot load JDBC driver class 'oracle
- 原创:oracle:sql介绍及SQL基本查询 (四)
- SQL DDL & DML from Oracle JDBC toturial
- 用Apache Spark进行大数据处理——第二部分:Spark SQL
- 如何编写更好的SQL查询:终极指南-第二部分
- Java通过JDBC连接Oracle之后查询结果和在sqlplus查询结果不一样