JDBC
第一章 JDBC基础
1.1 什么是JDBC
Java Database connectivity: JAVA访问数据库的解决方案。该方案使用相同的原理和开发步骤去连接各种各样的数据库。JDBC定义了一套标准接口和方案,即访问数据库数据的JAVA API不同的数据库,使用不同的驱动即可。驱动由各个数据库厂商提供。
简言之,JDBC就是JAVA连接数据库并执行SQL查询以及更新数据的接口和方法。JDBC API是一个标准编程接口,可以用来连接任何的数据库。
1.2 JDBC有哪些接口以及方法
1.2.1 主要的接口
a DriverManger ----> 管理驱动的
b Connection -----> 连接数据库
c Statement --------> 执行SQL语句的类
d ResultSet --------> 查询结果的类
1.3 JDBC 工作原理
JAVA程序 -----> 调用 JDBC API ----->更新数据库
JAVA程序:通常开发的业务逻辑程序,通过调用JDBC的类和方法来实现任何数据的更新与查询。
JDBC API中的重要接口DriverManager类管理和使用
不同的JDBC驱动来实现连接不同的数据库。
JDBC驱动实现了JAVA API的接口,用来连接数据库服务器端口,从而进行数据通信交互的。
类似于PC声卡和显卡驱动。
备注:
1 驱动从何而来?
从数据库厂商的官网下载。
2 JDBC API 除了主要的接口类,
还有哪些?方法呢?
查在线JAVA帮助手册
原版英文版 ORACLE的官网即可
http://www.oracle.com/technetwork/java/api-141528.html
中文版
http://tool.oschina.net/apidocs/apidoc?api=jdk-zh
1.4 JAVA JDBC 开发步骤
1.4.1 JDBC API
JDBC API 主要功能:连接数据库,执行SQL处理返回结果
DriverManger 依据不同的数据库,加载不同的 JDBC驱动
Connection : 驱动加载完毕后,负责连接数据库 并形成数据库和程序通信通道
Statement : 由Connect通道产生SQL语句对象并查询和更新数据表中的数据
ResultSet: 负责保存Statement执行之后返回的结果集。
1.4.2 开发具体步骤
第一步 加载指定数据库的JDBC 驱动Class.forName("oracle.jdbc.driver.OracleDriver");
第二步 建立与ORACLE数据库的连接
Connection con = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.228.2:1521:ora10g", //连接ORACLE主机路径
"jsd1705",
"jsd1705"
)
(重点,主体)
第三步 查询数据库,创建statement对象,并执行
SQL语句,返回结果集
Statement state = con.createStatement();
第四步 处理返回结果
ResultSet rs = stat.executeQuery(sql);
第五步 释放资源,完成SQL操作
关闭查询语句及数据库连接。
如果有结果集,也要关闭。
顺序 1 先关闭结果集2 在关闭STATEMETN
3 最后关闭整个数据库连接通道
1.4.3 JDBC之helloworld
lab 1 测试输出员工编号为7839 的员工姓名,
工作岗位及工资待遇
lab 2
和MARTIN一个部门的员工最高的薪水是多少?
且收入超过2500的不纳入统计范围.
JDBC
结果1600
select max(sal) as 部门最高薪酬
from emp where sal <=2500 and deptno =
(select deptno from emp whereename='MARTIN');
lab 3 查询EMP全部的数据
1.5 Statement 常用方法
a ResultSet rs = sta.executeQuery(sql);
--> 查询 返回查询结果集
b int count = sta.executeUpdate(sql);
-->新增,更改及删除 返回更新的行数
c boolean flag = sta.execute(sql)
---> 可以执行任意的SQL语句,然后一个true or false
true: 有结果集返回 false: 相反
1.6 ResultSet 常用方法
1 boolean next() 读取下一条记录,
如果没有下一条返回FALSE
2 rs.getString rs.getInt rs.getDate rs.getTimeStamp
rs.getFloat rs.getDouble
(列名 or 列序号)
案例: select enane, job, sal from emp;
rs.getString("ename") or rs.getString(1);
rs.getString("job") or rs.getString(2);
rs.getFloat("sal"); or rs.getFloat(3);
1.7 新增,更新,删除
lab 4,5,6
先把deptno 30 员工全部加薪10000美金
在增加一条记录 员工信息 黄鳝 xxxxxx
全部删除
1.8 PreparedStatement
开发心得:
A
建议在用Scanner,使用nextLine()读取一行的字符串
之后再JAVA后台用JAVA的方法去转换数据
不建议使用 scanner.nextInt()
建议使用 Integer.parseInt(scanner.nextLine());
B
float & double 使用区分
32 int 32.55 float 32.5555555 double
orable column number
Double.parseDouble(); Integer.parseInt();
Float.parseFloat();
PreparedStatement 预编译的SQL语句对象
当SQL语句国语复杂,需要对接3个以上的变量
SQL字符串注入变量会变得相当复杂且不易差错
所以引入PreparedStatement(建议以他使用为主)
无论有多少个变量,只要给对接的位置保留一个?
作为占位符即可。
每个问号的值必须在执行之前,通过setInt,setString,setDate
等方法赋值绑定。setInt(1,100) 索引从1开始
1) preparedstatement 和 statement 的关系?
它继承于statement接口,statement有的,它都有;它比statement对象使用起来更加灵活和高效
2) preparedstatement 优势
Statement通常用于执行静态SQL语句,固定不变的或者对接变量2个以下的。而Preparedstatement可以对接N个变量。提高了SQL语句的可读性和可维护性。提高了SQL和JAVA代码的执行性能。
lab 1 使用prepardStatemnt做高级查询
和King不在一个部门的其他部门的平均工资,且不统计
SCOTT, 工作岗位是 manager不统计
king, scott, manager
select deptno, avg(sal) from martin123
where deptno not in
(select deptno from martin123
where ename='KING') and ename <>'SCOTT'
and job != 'MANAGER' group by deptno
order by deptno desc;
select deptno, avg(sal) from martin123
where deptno not in
(select deptno from martin123
where ename=?) and ename <>?
and job != ? group by deptno
order by deptno desc;
lab 2 循环插入记录100条 perparedstatement
员工编号2000~2100 名字:鬼谷子01~鬼果子100 sysdate
9000 null 60 法师
1.9 批处理
1.9.1 实际需求,如何需要建立10000个测试记录
当使用p.executeUpdate();语句的时候,会消耗 很大的通信通道资源,产生10000个执行语句的命令由于命令类似,但是也是执行10000次,占据数据库服务器执行命令队列,影响数据操作效率。因此,在单一程序逻辑块中,提交多次SQL语句执行时,通常采用批处理解决方案。
场景案例:
中饭外卖, JSD1705班买了40份盒饭。
如果是用p.executeUpdate(), 类似40个车手,
送了40次一个商家的盒饭
如果是批处理,类似一个车手,同时送来40份盒饭
1.9.2 定义
批处理是指将关联的SQL语句组合成一批处理,并将 这一批SQL语句命令当成一个命令交给数据库服务器处理。这样减少了数据库通信的资源消耗,从而极大的提高了
数据操作性能。
1.9.3 主要方法
a addBatch() ---> 添加SQL语句至批处理队列
语法: SQL语句对象.addBatch(str_sql); state,pre
b executeBatch() ---> 执行批处理
语法: SQL语句对象.executeBatch();
启动执行所有组合在一起的SQL语句命令,并返回一个
整数的数组,数组中的每一个整数对应着批处理的SQL语句
执行后影响的记录数。
cclearBatch(); 清空当前批处理队列的SQL语句
语法: SQL语句对象.clearBatch();
lab5
JDBC_InsertRecords copy 改成批处理插入1000条
员工编号3000~3999 名字:貂蝉01~貂蝉1000 sysdate
10000 null 70 坦克
1.10 事务
1.10.1 什么是事务?
略,见ORACLE教学笔记
1.10.2 什么是事务的特性
略,见ORACLE教学笔记
1.10.3 JDBC事务
JDBC事务默认值是自动提交事务,所以每一句SQL命令
执行成功后,都自动提交事务。
如果希望把若干SQL语句分组,
形成多个逻辑SQL执行单元,可以通过JDBC事务模式
在任意时间节点加以控制。
备注:
事务提交后,数据会立刻持久化更新至数据库
事务未提交,数据只在当前连接通信通道有效,数据保存在
当前用户在当前连接的临时表空间文件
1.10.4 JDBC事务主要方法
所有方法均属于数据库连接通信通道对象Connection
1)getAutoCommit()
获取当前事务提交的方式,默认值true
2)setAutoCommit()
设置事务提交方式 false为手动提交,true为自动提交
3)commit() 手动提交事务
4)rollback() 手动回滚事务
5)setSavepoint() 设置数据回滚记录点
事务
1 标准配置 执行体结束手动提交事务con.commit();
异常部分con.rollback();
2 设置记录点 根据业务逻辑回退到某个记录点并提交事务
con.rollback(savepoint)
正常标准情况
setAutoCommit(flase); 必须手工提交commit()
否则数据无法更新。
若不然
1 修改用户模式的自动提交方式
2 修改本地ORACLE服务器的针对JDBC的事务纪律
第二章 JDBC高级
2.1 综合应用
1) 收入前10 提示:rownum emp;
select ename,sal,job from
(select ename,sal,job as from
martin123 order by sal desc)
where rownum <=10;
2) 多表查询
lab 7 查询KING的薪水,部门,以及在哪工作?
关联 emp dept
1) 声明2个表进行查询 类似多字段,加逗号即可
2) 多表查询必须建立在某一个字段对应上
通常是某一个普通字段对应着另一张表的主键
1) 先查所有人的信息,部门,地址等
2) 追加条件KING即可
select t1.ename,t1.sal,t2.dname,t2.loc
from scott.emp t1, scott.dept t2 where
t1.deptno = t2.deptno and t1.ename = 'KING';
3) 复杂查询综合练习 lab 8 仅SQL
1) 收入最低的10个员工的薪水,工作地址?
select t1.ename,t1.sal,t2.loc
from emp t1,dept t2 where
t1.deptno = t2.deptno and rownum <=10
order by t1.sal asc;
2) 收入最高的20个员工的薪水,工作地址,
今天增加的记录不作为统计范围 date是24日
(今天添加信息,部门编号,增加几天部门记录信息)
50,60,70, 对应在DEPT insert 地址新加坡,香港,上海
select t1.ename,t1.sal,t2.loc
from martin123 t1,martin_d_123 t2 where
t1.deptno = t2.deptno and rownum <=20 and
to_char(t1.HIREDATE,'dd') != '27'
order by t1.sal desc;
3) 收入最高的3个员工的薪水,工作地址,
6月份增加的记录不作为统计范围,
且不统计和SCOTT一个部门
select * from martin123 t1,martin_d_123 t2
wheret1.DEPTNO= t2.DEPTNO and rownum <=3
andto_char(t1.HIREDATE,'mm')<>'6'
andt1.DEPTNO not in (select deptno from
martin123 t3 where t3.ename='SCOTT')
orderby t1.sal desc;
4) 先查后更新 SQL+JDBC代码
lab 9
1scanner 录入员工编号
2 和员工同一个部门的加薪双倍
3 不和该员工部门的薪水减半
使用批处理,
分别打印2,3批处理执行返回的更新行数
备注:
Statement
1 优点: 可以批处理不同的SQL语句
2 缺点: 必须是固定的SQL语句
建议为一批 50000条。
PreparedStatement
1 优点“发送的是预编译SQL语句,执行高效
2 缺点 直营应用在相同的SQL语句,通常是这对
同一张表同一个SQL进项大量的相同操作,操作上限
建议为一批 50000条。
批处理完毕之后,记得清除批处理队列
语句对象.clearBatch();
批处理无法执行select查询批处理
2.2 分页
2.2.1分页查询的定义
在实际应用中我们经常喷碰到分页的问题,比如一张表数据很多,我们只要先查看某几条记录,如果感兴趣,在往后翻页查看更多。这就是分页处理数据。
2.2.2分页查询的工作原理
每次向数据库请求一页的数据量,内存压力小,但是访问次数过多,造成数据库资源消耗。一次把数据全部取出放在临时表空间,根据用户输入的页数和设置的每页显示的记录数,来计算显示相应的记录。
简言之,分页就是定位显示第几条至第几条的数据,基于
定义了每页显示数据的固定行数。
场景案例: 1章表 100条数据,每页显示10天,共分10页。
如果我想直接查看第7页的数据,就是查看第61~70条记录。
计算分页结果集的起点和终点的通用公式,用来替代SQL的?占位符。
int begin(61) = (page-1)*pagesize + 1
int end(70) = begin + pagesize -1;
lab 1 一张表 876条记录 每页显示15条
我想查第9页数据 从第? 121 到 第 ?135
2.2.3 如何实现jdbc oracle分页查询
不同的数据库,分页关键字有所不同。在ORACLE中我们要用到rownum 伪列;假设表中有10条记录,我只想查询5条
select * from emp where rownum <=5 即可
伪列只支持 < <=
我只想查看第5条至第10条记录?
如果想要使用rownum > 5,也就是找后5条记录。
那么我们需要使用嵌套语句,先把rownum生成真实列
然后对他进行定位查询方可。
因为rownum是对结果集加一个伪列,即查询到结果集之后在增加一个伪列,强调现有结果集。
语法:
select * from (实际查询的结果集)
where abc_rn between ? and ?;
lab 1 一张表 876条记录 每页显示15条
我想查第9页数据 从第? 121 到 第 ?135
查emp表 第5条至第10条记录
select * from
(select rownum as vv_cn,* from emp)wherevv_cn between 5 and 10;
lab 2 分页高级查询练习
查询EMP表中位置在第10至第13的记录,按照薪水排序
且本月增加的记录不在统计范围之内
10mins 仅仅SQL
select * from(
select rownum myrn, t1.* from (
select t2.* from martin123 t2
where to_char
(t2.hiredate,'mm')<>6
order by t2.sal desc
)t1
)where myrn between 10 and 13;
2.3 DAO模式与分层开发
2.3.1 什么DAO
DAO data access object 数据存取对象
位于业务逻辑和数据库之间
实现对数据库数据的访问与管理,并转换成业务逻辑所需要的数据对象。
换句话说,就是在业务逻辑和数据库之间加入了一层DAO层,也称为数据库访问层。
2.3.2 什么是DAO模式?或者什么是数据库访问层?
1 隔离业务逻辑代码和数据访问代码
2 隔离不同的数据库实现
业务程序 -----> DAO层 -------> 数据库
2.3.3 DAO层包含哪些内容?
定义:主要有DAO接口,DAO实现类,实体类组成
通常还会附带数据库访问工具类。
2.3.4 如何设置DAO层?
1) 定义数据实体类,转化数据使用
前端需要数据库层查询结果集来显示,需要用实体类
进行组装打包,负责无法实现数据对象显示。
实体类 —> 对应数据库一张表
实体类的实例对象 ----> 对应一行记录
2) 定义一个DAO接口 ----> 定义数据库访问方法
3) 定义实现DAO接口的实现类 ---> 实现数据库访问方法
1 是为了设计结构更加合理 先定接口,在去实现
2 也是为了影藏实际的处理方法内容
4) 定义数据库通用工具类
---> 通常被包含在DAO层,但是是独立的,
仅仅为了代码的复用,通常只有2个方法,连接数据库
关闭数据库连接。
lab 3 查询EMP表的前20个数据,按照部门升序排序
2.4 什么是分层开发
一种话大为小,分而治之的软件工程开发模式
一种专业分工,各司其职的开发理论
分层的特点
1 每一层都有自己的职责
2 上一层不用关心下一层实现细节,上一层通过使用下一层
提供的方法完成当前业务逻辑
分层开发的好处
1 各层专注于自己功能的实现,便于提高质量
2 便于分工协助,提高开发效率
场景案例
餐厅: 服务员,厨师,收银员
学校: 班主任,助教,老师,咨询顾问等,各司其职
第三章 XML&DOM4J
3.1 XML
3.1.1 什么是XML
XML是指可扩展标记语言,被设计用来传输
和存储数据,标签可以自定义,应用于WEB开发的许多
方面
3.1.2 一个XML的案列
参见本课案例和W3Cschool案例
3.1.3 XML语法
a 所有XML元素都须有关闭标签
<我的标签></我的标签>
b 必须正确的嵌套
<abc><b></b></abc>correct
<abc><b></abc></b>wrong
c XML文档必须由根元素,最大的元素,树结构的顶点
d XML的属性须加引号
e 实体应用
f 注释
HTML文档就是标准的XML类型的文档
XML和HTML语法完全一致,
只不过XML是自定义没有意义的标签
目的传输和保存数据。
3.1.4 XML编程
目前主流有4个开发工作包
1 DOM 2 JDOM 3 SAX
4 DOM4J (DOM4J是应用最广的,业界公认四个当中最优秀的处理XML文件的工具包)
3.2 DOM4J
3.2.1 什么是DOM4J
DOM4J是一个JAVA的XML API,类似于JDBC API,提供一组类接口和方法来读写管理XML文件。它是一个非常优秀的JAVA XML API,性能优异,功能强大。
3.2.2 DOM4J的开发环境准备
类似于JQuery,需要去官网下载工具包和帮助手册
官网下载: http://www.dom4j.org/dom4j-1.6.1/
http://tool.oschina.net/
下载DOM4J JAR 安装进入项目工程
3.3 常用方法集合
3.3.1 如何创建编辑一个XML文件
a 创建XML文件
DOM4J通过DocumentHelper的方法创建一个XML文件
Document d = DocumentHelper.createDocument();
b 创建XML最重要一个节点,根节点(唯一的)
Element e = d.addElement(名字);
c 如何自由创建节点
Element对象.addElement("名字");在任意节点增加子节点
d 想当前元素添加指定属性和值,返回值为当前对象
Element对象.addAtrribute(属性名,属性值);
e 给当前节点添加文本内容
Element对象.addText(文本内容)
f 文件流输出,形成文件
XMLWriter对象.write(document对象);