JDBC:Java DataBase Connectity
引入JDBC的原因:作为持久化层和不同数据之间进行交互操作。
2、JDBC API
为Java开发人员访问数据库提供统一的编程接口,即JDBC,方便以一致的方式去访问不同的数据库。
JDBC API 分两个部分
应用程序开发接口:提供给应用开发人员使用。
驱动程序开发接口:提供给数据库驱动开发人员使用。
3、使用JDBC的目的
与数据库建立连接、发送sql语句到数据库端并执行、处理返回的执行结果。
4、JDBC Driver
JDBC提供了一个数据库驱动的接口java.sql.Driver
每个数据库厂家会去实现这个接口。
不同的数据库去实现这个接口
5、JDBC驱动类型
(1)jdbc桥接odbc 将jdbc调用转换为odbc
(2)本地api部分用java编写的驱动 jdbc驱动由两部分组成,一部分用java编写,一部分是其他语言编写的二进制代码。
(3)基于网络的纯Java驱动
(4)基于本地协议的纯java的驱动 将jdbc调用后直接和数据库进行交互。
6、oracle的jdbc包
ojdbc6.jar
![](/images/smiles/icon_surprised.gif)
7、Driver:数据库驱动接口
DriverManager类:管理多个加载的驱动程序。
Connection接口:代表一个和数据库的连接 通过 DriverManager.getConnection(String url,String user,String password).可以获得一个connection实例,然后调用createStatement创建Statement对象,然后在调用execute(String sql)执行sql语句。或是调用prepareStatement(String sql)返回PreparedStatement对象。也就是说使用createStatment比preparestatement多了一步。
Statement:用于执行sql语句,执行的sql语句不能加分号。
PreparedStatement:statement的子接口 CallabeStatement:Statement的子接口
ResultSet:封装Select语句执行返回的结果集,并提供方法对结果集中的内容进行获取和其他操作。DML操作返回的是int类型,代表执行的行数。
最后释放jdbc资源:close().先关结果集,再关statement,再关connection。
8、开发流程
(1)注册驱动并实例化
使用类装载器(最常用) Class.forName(driverName)
直接实例化
Driver driver = new oracle.jdbc.driver.OracleDriver()
使用jdbc.drivers属性
java -Djdbc.drivers = driverName[driverName]
(2)建立和数据库的连接
DriverManager.getConnection()
一般使用带三个参的getConnection(String url , String user,String password)
常见的数据库URL
Oralce jdbc:oracle:thin:@localhost:1521:SID
Mysql jdbc:mysql://localhost:3306/SID
示例:Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe","hr","hr");
(3)创建statement对象
Statement sta=conn.createStatement();执行不带参数的
PreparedStatement ps= conn.prepareStatement(String sql);带参数的。
(4)ResultSet rs =sta.executeQuery(sqlString);
执行查询语句,返回查询结果集ResultSet,执行sql语句的时候如果用到了列别名,那么在后续的遍历中也必须用别名。
int rows =sta.executeUpdate(sqlString);
执行DML和DDL语句,返回受影响的记录数
boolean flag=sta.execute(sqlString);
(5)处理结果集
查询语句返回结果集ResultSet
结果集中的内置游标指向第一条记录前面 rs.next()
通过ResultSet的相关方法来遍历结果集
(6)释放资源
关闭ResultSet、相应的Statement、和Connection。
9、配置文件
新建一个file文件 后缀为.properties 里面存放的是键值对 key=value 而且value不加双引号
在某个类A中调用方法:
获取流配置文件流:InputStream is=A.class.getResourceAsStream("配置文件名").
创建properties对象:Properties pop =new Properties() ;
加载配置文件流:pop.load(is);
值=pop.getProperty(键)
10、占位符?
创建preparedStatment对象的时候,在执行带列名的sql语句的时候可以用?代替列名。
比如说 insert into table values(?,?,?,?);
其中的占位符就可以用preparedStatment对象相对应的set方法去复制。比如说setInt(a,b)a代表是第几个占位符,b是相对应的值。
11、commonDao
比如说插入语句 insert into table values(?,?,?,?)
(1)table可能会有很多,也就意味着sql语句不一样
(2)插入数据个数及数据类型可能不同,意味着占位符不一样。主要是占位符数量不一样,就得用可变的参数列表,而且数据类型不一样,就想到了 Object...param param其实就是个可变大小的数组。里面存放object类型的参数。
也就意味着抽象出来的方法不能写死。
举例:以下代码可以执行增、删、改,不能查。
public class CommonDao {
public int executeUpdate(String sql,Object...param){
Connection conn=null;
PreparedStatement pst=null;
try {
//静态工厂获取连接
conn = ConnectionFactory.createConnection();
//创建preparedStatement对象
pst = conn.prepareStatement(sql);
//利用循环复制
if(param!=null && param.length>0){
for(int i=0;i<param.length;i++){
pst.setObject(i+1, param[i]);
}
}
//执行sql语句
int i=pst.executeUpdate();
return i;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
//关闭jdbc连接
ConnectionFactory.closeConnection(conn, pst, null);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return 0;
}
}
(3)查询语句
查询属于DQL语句,它不同于DML语句,它返回的是结果集。在jdbc中我们需要对结果集进行处理,将其解析成一个个的对象,因此所用方法和增、删、改不一样,需要重新写。
//解析结果集的方法,但是不具体实现,因为不同的类会有不同的解析结果。
public abstract <T> T getDataFormRs(ResultSet rs);
//执行查询
public <T> List<T> executeQuery(String sql,Object...param){
//定义一个存放解析结果的集合,里面存放的是具体的某个对象
List<T> list =new ArrayList<T>();
try {
conn = ConnectionFactory.createConnection();
pst = conn.prepareStatement(sql);
if(param!=null && param.length>0){
for(int i=0;i<param.length;i++){
pst.setObject(i+1, param[i]);
}
}
rs=pst.executeQuery();
//调用方法去解析,具体的实现交给子类
while(rs.next()){
//将结果集中解析出来的记录交给某个子类去解析返回其对象,因为对象类型不确定,故此使用泛型。
T t= getDataFormRs(rs);
list.add(t);
}
return list;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
try {
ConnectionFactory.closeConnection(conn, pst, null);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return null;
}
子类的实现:
public class StuDao extends CommonDao{
@SuppressWarnings("unchecked")
@Override
public <T> T getDataFormRs(ResultSet rs) {
Student stu =new Student();
try {
stu.setId(rs.getInt(1));
stu.setName(rs.getString(2));
stu.setAge(rs.getInt(3));
stu.setSchool(rs.getString(4));
return (T) stu;
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null;
}
}
11、批处理
addBatch和executeBatch()