掌握JDBC的基本作用
可以使用JDBC连接Oracle数据库
使用java.sql包中的类和接口进行数据库开发
JDBC操作代码都很固定,同时的所有开发之中都围绕数据库进行的,那么JDBC必须会
JDBC简介
JDBC指的是java数据库连接,可以直接利用java程序进行各种数据库连接及操作。JDBC在java之中属于一个
服务的概念,所谓的服务指的是就是一组固定的类库以完成某些固定的操作,而所有的服务在使用的形式
上都很固定。
那么在进行JDBC操作的过程之中,重点在于数据库的连接上,而对于JDBCD的连接有三种
JDBC-ODBC桥连接
操作形式:程序=<JDBC=<ODBC=<数据库:
JDBC连接:
操作形式:程序=<JDBC=<数据库
网络连接:通过网络协议连接网络上的数据库服务。
在java.sql包之中提供有所有的JDBC开发类的支持,Connection,Statement,ResultSet,PrepareStatement
连接数据库(重点)
本次要连接的是Oracle的两个重要服务(监听,实例服务),随后还需要配置Oracle数据库的驱动程序,
Oracle和DB2的驱动程序都是随着安装包提供的
路径:D:\app\Teahcer\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6d_g.jar
JDBC操作数据库的标准流程
第一步:加载数据库驱动程序
驱动程序的加载向容器之中加载,通过Class.forName()加载;
Oracle的驱动程序名称:oracle.jdbc.driver.OracleDriver
第二步:根据给定的数据库连接地址,用户名,密码连接数据库;
连接需要的主要信息
连接地址:jdbc:oracle:thin:@主机名称:端口号:SID;
连接mldn:jdbc:oracle:thin:@localhost:1521:MLDN;
用户名:scott
密码:tiger
连接数据库主要是利用 DriverManager类完成,取得的连接对象使用Connection接口表示;
第三步,打开数据库之后可以通过SQL进行数据库操作
数据库的操作主要CRUD,利用Statement,PreparedStatement,ResultSet操作的SQL语句
第四步:数据库属于资源操作,操作的最后一定要使用close()方法关闭
Connection,Statement,PreparedStatement,ResultSet都有关闭方法
每一个数据库连接都使用一个Connection接口表示(一个数据库可以打开多个连接,那么就使用多个Connection接口对象表示)。
而所有的连接都需要通过DriverManager类打开,此类定义了如下方法:
连接数据库:public static Connection getConnection(String uel,String user,String password)throws SQLException;
范例:连接数据库
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class a {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
System.out.println(conn);
conn.close();
}
}
DriverManager类严格来讲就是一个工厂类,通过此类之中的getConnection()方法,只要传入了正确
的连接地址,用户名,密码,就可以取得一个指定的Connection接口对象(这个Connection子类完全使由各个子类
数据库商家Connection接口标准制定的)
Statement
当取得了Connection接口对象之后,下面就利用利用Connection打开数据库的操作接口Statement,在
Connection接口里面定义有一个Statement接口对象的方法:public Statement createStatement()throws SQLException
而取得了Statement接口后就可以进行两类操作:
数据库更新操作:public int executeUpdate(String sql)throws SQLException,返回更新行数
数据库查询操作:public ResultSet executeQuery(String sql)throws SQLException,
范例:编写数据库创建脚本
--删除对象
DROP SEQUENCE myseq;
DROP TABLE member;
--创建对象
CREATE SEQUENCE myseq;
CREATE TABLE member(
mid NUMBER,
name UARCHAR2(20) NOT NULL,
birthday DATE,
note CLOB,
CONSTRAINT mid_pk PRIMARY KEY(mid)
);
实现更新操作
更新操作一共分为三类:增加,修改,删除
范例:增加新数据
SQL语法:INSERTINTO 表名称(字段,字段,....)VALUES(值,值,..)
package jdbc;
//oracle
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class a {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
Statement stmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
stmt=conn.createStatement();//创建Statement对象
String sql= " INSERTINTO member(mid,name,birthday,note)"
+" VALUES(myseq.nextval,'我',"
+" TO_RATE('1911-11-11','yyyy-mm-dd'),'是')";
int len=stmt.executeUpdate(sql);//执行SQL
System.out.println("更新行数"+len);
conn.close();
}
}
范例:修改数据
SQL语法:UPDATE表名称 SET字段=值,...WHERE 修改条件
UPDATE member SET name='我我我', note='你你你',birthday=SYSDATE WHERE mid IN(5,7,9,10,20);
String sql=" UPDATE member SET name='我我我', note='你你你', "
+ " birthday=SYSDATE WHERE mid IN(5,7,9,10,20) ";//修改
就修改sql语句,其它都不用动
范例:删除数据
SQL:DELETE FROM 表名称 WHERE 删除条件;
String sql="DELETE FROM member WHERE mid IN(2,4,6,8,10)"
整个操作过程之中,唯一改变的是SQL语句
实现查询操作
更新操作主要的是返回更新的数据行数,但是如果是查询操作,则需要把查询结果返回,而查询结果一般都是以“行列集合”的
形式返回的,所有就必须有一种结构,可以容纳这些行和列,于是有了ResultSet接口,即:所有查询的返回值
都保存了ResultSet集合之中
范例:查询数据
package jdbc;
//oracle
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Date;
public class a {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
Statement stmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
stmt=conn.createStatement();//创建Statement对象
// String sql= " INSERT INTO member(mid,name,birthday,note) "
// +" VALUES(myseq.nextval,'我', "
// +" TO_RATE('1911-11-11','yyyy-mm-dd'),'是') ";
// String sql=" UPDATE member SET name='我我我', note='你你你', "
// + " birthday=SYSDATE WHERE mid IN(5,7,9,10,20) ";//修改
String sql=" SELECT mid,name,birthday,note FROM member ";
ResultSet rs=stmt.executeQuery(sql);//查询操作
//每行循环是操作返回的一行记录
while(rs.next()) {//移动游标,同时判断是否有数据
int mid=rs.getInt("mid");
String name=rs.getString("name");
Date birthday=rs.getDate("birthday");
String note=rs.getString("note");
System.out.println(mid+","+name+","+birthday+","+note);
}
conn.close();
}
}
但是很多时候在进行列访问的时候也会采用索引的形式取得数据
int mid=rs.getInt(1);
String name=rs.getString(2);
Date birthday=rs.getDate(3);
String note=rs.getString(4);
这种方法是最常用的
PreparedStatement(核心,第九个代码模型)
虽然可以利用Statement的操作数据库,但是如果在开发之中,Statement是不可能使用的,以增加数据为例
,在本表之中姓名,生日,介绍应该由用户自己输入
此时的程序由于要拼凑的原因,那么一旦用户输入了一些敏感的字符,就有可能造成错误,严重的就有可能
出现严重的安全漏洞,所以就得出结论,拼凑的SQL不能用
使用Statement的子接口:PreparedStatement(预处理)。提升操作的性能。那么现在如果要使用PreparedStatement
接口,则就必须通过Connection接口重的新方法实例化
方法:public PreparedStatement PrepareStatement(String sql) throws SQLException。
当取得了PreparedStatement接口对象之后,就可以利用新的方法操作:
更新操作:public int executeUpdate() throws SQLException
查询操作:public ResultSet executeQuery() throws SQLException
而最为重要的是,在创建PreparedStatement的时候所需要涉足的内容都要通过一个占位符“?”表示,
而在执行更新和查询之前,需要使用一系列的setXxx()方法设置“?”的数据
但是在setDate()方法操作的时候需要注意一点:操作的是java.sql.Date,而不是java.util.Date,java.sql.Date
是java.util.Date的子类,而在java.util.Date下一共有三个子类,而且这三个子类都是保存在java.sql包之中
:Date(保存日期),Time(保存时间),TimeStamp(日期+时间)。
范例:实现数据增加
package jdbc;
//oracle
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class b {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
String name="Mr'ds";
Date birthday=new Date();
String note="世界末日";
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql= " INSERT INTO member(mid,name,birthday,note)"
+" VALUES(myseq.nextval,?,?,?) ";
pstmt=conn.prepareStatement(sql);//创建PreparedStatement接口对象
pstmt.setString(1, name);
pstmt.setDate(2, new java.sql.Date(birthday.getTime()));
pstmt.setString(3, note);
int len=pstmt.executeUpdate();//执行SQL
System.out.println("更新行数"+len);
conn.close();
}
}
在开发之中为了保证更新的更新的质量,所有的操作一定使用的是PreparedStatement,以上做的只是一个增加
(修改和删除也一样),而重点在于下面的查询操作上
范例:查询全部数据
package jdbc;
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class c {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql=" SELECT mid,name,birthday,note FROM member ";
pstmt=conn.prepareStatement(sql);
ResultSet rs=pstmt.executeQuery();
while(rs.next()) {
int mid=rs.getInt(1);
String name=rs.getString(2);
Date birthday=rs.getDate(3);
String note=rs.getString(4);
System.out.println(mid+","+name+","+birthday+","+note);
}
conn.close();
}
}
范例:根据编号查询,查询制定编号的数据
此时只会返回单行多列数据
package jdbc;
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class c {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
int mid=10;//查询数据
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql=" SELECT mid,name,birthday,note "
+ " FROM member WHERE mid=? ";
pstmt=conn.prepareStatement(sql);
pstmt.setInt(1, mid);
ResultSet rs=pstmt.executeQuery();
if(rs.next()) {
mid =rs.getInt(1);
String name=rs.getString(2);
Date birthday=rs.getDate(3);
String note=rs.getString(4);
System.out.println(mid+","+name+","+birthday+","+note);
}else {
System.out.println("没有数据返回!");
}
conn.close();
}
}
范例:模糊查询
package jdbc;
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class c {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
String keyWord="我";
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql=" SELECT mid,name,birthday,note "
+ " FROM member WHERE name LIKE? ";
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "%"+keyWord+"%");//在此写%
ResultSet rs=pstmt.executeQuery();
while(rs.next()) {
int mid =rs.getInt(1);
String name=rs.getString(2);
Date birthday=rs.getDate(3);
String note=rs.getString(4);
System.out.println(mid+","+name+","+birthday+","+note);
}
conn.close();
}
}
如果在执行模糊的时候不设置任何的关键字,表示查询全部
范例:分页显示
package jdbc;
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class d {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
int currentPage=1;
int lineSize=5;
String keyWord="";
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql=" SELECT * FROM("
+ " SELECT mid,name,birthday,note,ROWNUM rn "
+ " FROM member WHERE name LIKE? AND ROWNUM<=? ) temp "
+" WHERE temp.rn>? " ;
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "%"+keyWord+"%");//在此写%
pstmt.setInt(2, currentPage* lineSize);
pstmt.setInt(3, (currentPage-1)*lineSize);
ResultSet rs=pstmt.executeQuery();
while(rs.next()) {
int mid =rs.getInt(1);
String name=rs.getString(2);
Date birthday=rs.getDate(3);
String note=rs.getString(4);
System.out.println(mid+","+name+","+birthday+","+note);
}
conn.close();
}
}
范例:统计数据行
package jdbc;
import java.sql.Connection;
import java.util.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class e{
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
String keyWord="";
Connection conn=null;//每一个Connection对象都表示一个连接
PreparedStatement pstmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
String sql=" SELECT COUNT(mid) FROM member WHERE name LIKE ?" ;
pstmt=conn.prepareStatement(sql);
pstmt.setString(1, "%"+keyWord+"%");//在此写%
ResultSet rs=pstmt.executeQuery();
if(rs.next()) {//永恒有数据返回
System.out.println(rs.getInt(1));
}
conn.close();
}
}
批处理与事务处理(重点)
以上所使用的开发模式是JDBC1.0提出来的,而JDBC2.0提多许多新的特征:可滚动结果集,使用结果集
更新数据,批处理,批处理指的是一次性向数据库之中发出多条更新指令,在Statement和PreparedStatement
接口都有定义的方法
Statement接口定义的方法:
增加批处理语句:public void addBatch(String sql)throws SQLException
执行批处理语句:public int[] executeBatch() throws SQLException
返回的是每一条SQL语句影响的数据行数量
PreparedStatement接口定义的方法
增加批处理语句:public void addBatch() throws SQLException
范例:利用Statement来观察问题
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class g {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
Statement stmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
stmt =conn.createStatement();
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
int result[]=stmt.executeBatch();
for(int x=0;x<result.length;x++) {
System.out.println(result[x]+",");
}
conn.close();
}
}
但是如果说现在有这样的一种情况,以上五个要执行SQL语句属于一个完整业务,即:要求所有的SQL一起
成功,或者一起失败,但是默认情况下,JDBC中的事务都是自动提交的,所以如果中间出现了错误,那么
之前没有错的正常执行,很明显这不符合要求,必须手工的进行事务处理,而所有的事务处理命令都在
Connection接口中定义
提交事务:pulic void commit() throws SQLException
回滚事务:public void rollback() throws SQLException
设置自动提交与否:public void setAutoCommit(boolean autoCommit)thorws SQLException
package jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class g {
private static String DBDRIVER="oracle.jdbc.driver.OracleDriver";
private static String DBURL="jdbc:oracle:thin:@localhost:1521:MLDN";
private static String DBUSER="scott";
private static String PASSWORD="tiger";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
Connection conn=null;//每一个Connection对象都表示一个连接
Statement stmt=null;//定义数据库操作对象
Class.forName(DBDRIVER);
conn=DriverManager.getConnection(DBURL,DBUSER,PASSWORD);
stmt =conn.createStatement();
conn.setAutoCommit(false);//取消自动提交
try {
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
stmt.addBatch("INSERT INTO member(mid,name) VALUES(myseq.nextval,'张三') ");
int result[]=stmt.executeBatch();
for(int x=0;x<result.length;x++) {
System.out.println(result[x]+",");
}
conn.commit();//提交事务
}catch(Exception e){
e.printStackTrace();
conn.rollback();
}
conn.close();
}
}
在日后的开发之中,事务都是自动处理的,用户只需要编写代码就行了
总结:
可以连接Oracle数据库
使用PrepatedStatement操作数据库的所有代码都必须熟练编写
任务
工厂设计模式
JDBC操作(PrepatedStatement)
类集
简单java类与数据表映射
对象序列化,包装类