导入ojdbc5.jar包-->oracle.jabc-->OracleDriver.class
JDBC中定义了一些接口:
1、驱动管理:
DriverManager
2、连接接口
Connection
DatabasemetaData
3、语句对象接口
Statement
PreparedStatement
CallableStatement
4、结果集接口
ResultSet
ResultSetMetaData
JDBC访问数据库的工作过程:
加载驱动,建立连接
创建语句对象
执行SQL语句
处理结果集
Driver接口及驱动类加载
要使用JDBC接口,需要先将对应数据库的实现部分(驱动)加载进来。
驱动类加载方式(Oracle):
Class.forName("oracle.jdbc.driver.OracleDriver");
Connection接口
Connection接口负责应用程序对数据库的连接,在加载驱动之后,使用url、username、password三个参数,创建到具体数据库的连接。
Connection conn=DriverManager.getConnection("jdbc:oracle:thin:@192.168.0.23:1521:orcl","jsd1503","jsd1503");
Statement接口
Statement接口用来处理发送到数据库的SQL语句对象,通过Connection对象创建。主要有三个常用方法:
Statement stmt=conn.createStatement();
//1.execute方法,如果执行的sql是查询语句且有结果集则返回true,如果是非查询语句或者没有结果集,返回false
boolean flag = stmt.execute(sql);
//2.执行查询语句,返回结果集
ResultSet rs = stmt.executeQuery(sql);
//3.执行DML语句,返回影响的记录数
boolean flag = stmt.executeUpdate(sql);
ResultSet接口
执行查询SQL语句后返回的结果集,由ResultSet接口接收。
常用处理方式:遍历 / 判断是否有结果(登录)。
String sql = "select * from emp";
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("empno")+",“
+rs.getString("ename") );}
数据库厂商实现:在Java程序中访问不同数据库,需要下载对应数据库的驱动
Oracle实现:Oracle数据库提供的驱动为ojdbc6.jar或者ojdbc14.jar,在开发时需要将驱动类加载到项目中,通过设置MyEclipse的Build Path选项
使用时就可以如下方式加载驱动类了:
Class.forName("oracle.jdbc.driver.OracleDriver");
MySQL实现:MySQL对应的数据库驱动名为mysql-connector-java-5.0.4-bin.jar(不同版本可能有不同名称),将驱动类加载到项目中同样通过设置
MyEclipse的Build Path选项
加载驱动类的方式:
Class.forName("oracle.jdbc.driver.OracleDriver");
JDBC基础编程
通过连接工具类获取连接
实现工具类的两种方式:
1,直接把数据配置写在工具类。
2,把数据库配置写在一个properties属性文件里,工具类读入属性文件,逐行获取数据库参数。
通过属性文件维护连接属性
保存在包中的配置文件用:ClassLoader API读取包中的资源
保存在文件系统中的配置文件可以使用文件流读取
从类路径中加载属性文件
利用配置文件db.properties保存数据库连接参数:配置文件的位置有两种
* 1,保存在操作系统文件路径中,使用文件流进行读取 newFileInputStream
* 2,保存在包(package)中,使用ClassLoader读取保存在包中的配置文件
* path=="day01/db.properties"
数据库连接池 接口:javax.sql.DateSource
主要方法:Connection getConnection()
1,java数据库连接,java程序与数据库的连接桥梁
2,JDBC结构:java定义了JDBC的API(很多接口,)
JDBC驱动,实现了JDBC标准的类
3,JDBC的使用:1,导入JDBC驱动(*.class)
2,注册驱动,注册一次就可以。
Class.forName(驱动的类名)
3,连接到数据库,使用DriverManager作为工厂创建Connection对象
4,执行SQL语句。三种方法分别执行DDL DML DQL
5,处理执行结果。
6,无比关闭数据库。
4,JDBC可以实现持久化的数据存储
5,数据可连接接池
数据库客户端存在并发访问数据库服务器时候,需要使用连接池。使数据库连接能够重用,保护数据库的连接总数
如果不松并发访问数据库,没必要使用数据库连接池
6,实现了DataSource接口,提供了getConnection方法Apache DBCP、
C3P0
1,连接池策略管理的属性设置方法不一样
2,利用API的参考手册,熟悉这些方法!
注意:任何时候使用第三方的API,都要拿到手册。
JDBC核心API
Statement执行查询
通过Connection对象创建Statement的方式:
Connection.createStatement();//利用Connection工厂方法Statement创建对象
执行INSERT, UPDATE和DELETE等DML操作:
Statement.executeUpdate();
执行SELECT:
Statement.executeQuery();
通过Statement对象返回SQL语句执行后的结果集:
String sql = "select empno, ename, sal, hiredate from emp";
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery(sql);
//对rs的处理
stmt.close();
Statement执行插入
Statement.executeUpdate(sql)方法将返回SQL语句执行后影响的记录数:
String sql = "insert into emp(empno, ename, job, sal) values(1001, ‘张三丰’,‘Manager’9500)";
int flag = -1;
try {
con = ConnectionSource.getConnection();
stmt = con.createStatement();
flag = stmt.executeUpdate(sql);
//处理结果
}catch(SQLException e){
//处理异常
}
Statement执行更改
和INSERT操作完全相同,只是SQL语句不同:
String sql = "update emp set sal = 9900 where empno = 1001";
int flag = -1;
try {
con = ConnectionSource.getConnection();
stmt = con.createStatement();
flag = stmt.executeUpdate(sql);
//处理结果
}catch(SQLException e){
//处理异常
}
PreparedStatement原理
不同的SQL对应不同的执行计划,哪怕一个字符变化,都会产生不同的执行计划
如何利用执行计划提高数据库的执行效率,尽可能执行效率
1,在使用Statement时候尽量保持SQL不变
2,SQL语句有参数变化时候使用PreparedStatement
通常批量处理时使用PreparedStatement
1,//SQL语句已发送给数据库,并编译好为执行作好准备
PreparedStatement pstmt = con.prepareStatement("UPDATE emp SET job= ? WHERE empno = ?");
2,//对占位符进行初始化
pstmt.setLong(1, "Manager");pstmt.setInt(2,1001);
3,//执行SQL语句
pstmt.executeUpdate();
总结有参数使用PreparedStatement,没参数使用Statement
ResultSetMetaData: 数据结果集的元数据,和查询出来的结果集相关,从结果集(ResultSet)中获取
eg:显示一个sql语句结果的列名
Connection conn=null;
try {
conn=DBUtil.getConnection();
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery(sql);//执行sql得到结果集
ResultSetMetaData metaData=rs.getMetaData();//获取结果及的元数据(MetaData)
int cols=metaData.getColumnCount();
//ColumnName列名,获取列名参数是列号
//col =1~cols 列号,就可以显示全部的列
for (int i = 1; i <=cols; i++) {
String name=metaData.getColumnName(i);
System.out.print(name+" ");
}
System.out.println();
rs.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
DBUtil.close(conn);
}
结果集的工作原理,ResultSet的查询结果是保存在服务器端的,性能好,便于缓冲数据,在getXXX时候才将数据传输到客户端
JDBC支持数据库事务:
1,事务是数据库提提供的
2,JDBC提供了API方法支持了数据库事物
3,JDBC利用conn实现了事务支持API
4,JDBC的默认事务是自动提交的,一个sql语句就是一个事务,执行后自动提交事务,
eg:insert xxxxxx 自动执行commit语句
5,如果需要将多个sql语句作为一个事务过程需要关闭自动提交
eg:转账操作 一个事物,两个操作:一方转出update,一方装入update
关闭自动提交:
conn.setAueoCommit(true)
参数是 true:自动提交; false:不自动提交(关闭自动提交)
在关闭自动提交以后,在同一个连接上执行的多个sql语句作为同一个事务
当执行conn.commit()时候可以提交一系列sql
当执行conn.rollback()时候可以回滚一系列sql
Connection.getAutoCommit() :获得当前事务的提交方式,默认为true
批量更新API
Statement类的方法
addBatch(String sql)//添加到客户端sql缓冲区
executeBatch()//客户端的一批sql一起法送数据执行
PreparedStatement类的方法
一个执行计划,没有批量sql,只有批量参数,将sql发送,创建执行计划
addBatch()添加批量参数到ps缓冲区
executeBatch()批量替换参数执行 执行计划
clearBatch()清空当前SQL语句列表
获取dept表的部门序号 dept.nextval (select dept.nextval fromdual)
JDBC返回自动主键API
getGeneratedKeys方法获取自增类型的数据,性能良好,只要一次SQL交互。
//1.插入主表SQL,使用序列作为主键
sql = "insert into dept (deptno, dname, loc) values(dept_seq.nextval,?,?)";
//2.定义stmt时,第二个参数是GeneratedKeys的主键的字段名列表,类型是字符串数组
stmt = con.prepareStatement(sql, new String[] { "deptno" });
//3.将占位符赋值
stmt.setString(1, “Research”);
stmt.setString(2, “beijing”);
//4.执行插入主表的insert语句
stmt.executeUpdate();
//5.获得主键值
rs = stmt.getGeneratedKeys();
rs.next();
int deptno = rs.getInt(1);
//6.将刚刚得到的主表主键值,作为外键插入到从表中。
String sql2 = “insert into emp(empno, ename, deptno) values(?,?,?)”;
--分页查询
select * from (
select rownum rn,t. * from(select * from lwsmoney) t)
where
between 6 and 10
--性能最好Oracle分页查询
select * from (
select a.*,rownum RN from (SQL) a where rownum <=MAX
) where RN >=MIN
eg:查询6到10页数据*******************************************************************************************
select * from (
select a.*,rownum RN from (
select * from lwsmoney
) a where rownum <=10
) where RN >=6
JDBC实现MySQL分页查询
select * from limit begin,pageSize;
工作中经常进行DRUD(增删改查)
将对象(emp对象)添加到数据库中
将对象从数据库中查询回来
将对象在数据库中进行修改
将数据库中的对象数据删除
DAO(Data Access Object)模式
将对象的CRUD方法(JDBC操作)封装起来,以后在使用CRUD的时候就直接“重用”DAO方法即可,不用再编写JDBC程序了。
为了建立一个健壮的Java应用,需将所有对数据源的访问操作抽象封装在一个公共API中,需要:
建立一个接口,接口中定义了应用程序中将会用到的所有事务方法
建立接口的实现类,实现接口对应的所有方法,和数据库直接交互
在应用程序中,当需要和数据源交互时则使用DAO接口,不涉及任何数据库的具体操作。DAO通常包括:
1. 一个DAO工厂类;
2. 一个DAO接口;
3. 一个实现DAO接口的具体类;
4. 数据传递对象(实体对象(Entity) 或 值对象(Value Object,简称VO)).