JDBC
概念
JDBC(Java Database Connective)指的是数据库连接技术,是一组接口的组成。
四种Java数据库操作形式
- JDBC-ODBC桥接技术:ODBC(开放数据库连接)是Windows中提供的数据库连接应用,利用JDBC间接操作ODBC技术,从而实现数据库的连接。
- JDBC直接连接:直接由不同的数据库生产商提供指定的数据库连接驱动程序,实现对数据库的连接。
- JDBC网络连接:使用专门的数据库的网络指令进行指定主机的数据库操作。
- 模拟指定数据库的通信协议自己编写数据库操作。
连接Oracle数据库
Java中,所有数据库操作的雷和接口都保存在了java.sql包里:
- 一个类:DriverManager类
- 四个接口:Connection、Statement、ResultSet、PreparedStatement.
流程
- 加载数据库的驱动程序(向容器加载);
- 进行数据库连接(通过DriverManager类完成,Connection表示连接);
- 进行数据的CRUD(使用Staement、PreparedStatemet、ResultSet);
- 关闭数据库操作以及连接。
步骤一:加载驱动程序
- 驱动程序:C:\app\Rhine\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar
- Oracle驱动程序类:oracle.jdbc.driver.OracleDriver
- 加载类使用:Class.forName(“oracle.jdbc.driver.OracleDriver”);
步骤二:连接数据库
前提
打开两个必要服务:
- OracleServiceMLDN(主服务)
- OracleOraDb11g_home1TNSListener(监听服务)
导入ojdbc6.jar包:
右键项目 -> Build Path -> Add External Archiver,选中导入即可。
连接数据库的必要信息
- 数据库的连接地址:jdbc:oracle:连接方式:@主机名称:端口名称:数据库的SID
- 本地mldn数据库地址:jdbc:oracle:thin:@localhost:1521:mldn
- 数据库的用户名:scott
- 数据库的密码:tiger
连接方法
通过DriverManager类提供的如下方法进行数据库连接:
public static Connection getConnection(String url, String password) throws SQLException
public class TestMain {
private static final String DBDRIVER = "oracle.jdbc.driver.OracleDriver";
private static final String DBURL = "jdbc:oracle:thin:@localhost:1521:mldn";
private static final String USER = "scott";
private static final String PWD = "tiger";
public static void main(String[] args) throws Exception {
//第一步:加载数据库驱动程序
Class.forName(DBDRIVER);
//第二步:连接数据库
Connection conn = DriverManager.getConnection(DBURL, USER, PWD);
System.out.print(conn); //如果有输出结果,则表示连接成功
conn.close();
}
}
连接不上数据库的情况
1)监听服务出现错误
监听如果出现错误,会打印出如下的错误信息:
Listener refused the connection with the following error:
ORA-12505, TNS:listener does not currently know of SID given in connect descriptor
【解决方法】:
监听的主机名称(Host)不是本机的计算机名称,也不要使用IP地址。
监听位置文件目录:C:\app\Rhine\product\11.2.0\dbhome_1\NETWORK\ADMIN
- 监听文件:listener.ora
- 监听名称文件:tnsnames.ora
- 检查两个文件中的Host名称是否和本机的计算机名称相同。
- 修改完成后,重新启动两个Oracle数据库服务。
2)不能找到指定的SID
数据库的名称 = SID的名称,有时候该名称不会自动注册,所以就会存在只有数据库名称,不存在SID名称。
【解决方法】:
打开菜单中的Oracle Net Manager,打开本地->监听程序->LISTENER->选择添加地址(全局数据名与SID同名即可)->完成。添加完成后,会自动修改listener.ora文件,在其中插入新的SID。
关闭数据库
Connection接口提供了Close()方法
public void close() throws SQLEXception
Statement接口
Statement可以对数据库进行操作,但实际开发中几乎不使用这个接口。
实例化Statement对象
需要依赖Connection接口提供的方法:
public Statement createStatement() throws SQLException
数据库操作的两个方法
1)数据更新(增、删、改):
返回更新行数
public int executeUpdate(String sql) throws SQLException
2)数据查询:
public ResultSet executeQuery(String sql) throws SQLException
实例
创建member表:
DROP TABLE member PURGE;
DROP SEQUENCE myseq;
CREATE SEQUENCE myseq;
CREATE TABLE member(
mid NUMBER,
name VARCHAR2(20),
birthday DATE DEFAULT SYSDATE,
age NUMBER(3),
note CLOB,
CONSTRAINT pk_mid PRIMARY KEY(mid)
);
数据更新
1)数据增加:
//取得Statement实例
Statement stmt = conn.createStatement();
String addSql = "INSERT INTO member(mid, name, birthday, age, note) VALUES (myseq.nextval, 'Cyy', TO_DATE('1997-07-27','yyyy-mm-dd'), 17, 'Peopele')";
int len = stmt.executeUpdate(addSql); //执行SQL并返回更新
System.out.print(len);
2)数据修改
Statement stmt = conn.createStatement();
String updateSql = "UPDATE member SET name = 'CJP', birthday = SYSDATE, age = 30 WHERE mid IN(2, 3)";
int len = stmt.executeUpdate(updateSql); //执行SQL并返回更新
System.out.print(len);
3)数据删除
Statement stmt = conn.createStatement();
String sql = "DELETE FROM member WHERE mid IN(2)";
int len = stmt.executeUpdate(sql); //执行SQL并返回更新
System.out.print(len);
只有sql语句改变,其他不变。
数据查询
ResultSet接口
1)移动指针,判断是否有数据行:
public boolean next() throws SQLException
2)取数据类:getInt()、getDouble()、getString()、getDate()。
3)实例
Statement stmt = conn.createStatement();
String sql = "SELECT mid, name, age, birthday, note FROM member";
ResultSet rs = stmt.executeQuery(sql);
//循环取出数据
while(rs.next()) {
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthday = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println(mid+ " " + name +" " + age + " " + birthday + " " + note );
}
4)注意
- 使用getXXX()取出列数据的时候,建议给定按照顺序去;
- 每一列的数据只能够按照顺序去一次;
PrepareSatement接口
Statement缺陷
由于statement采用的字符串拼凑的方式生成SQL语句,如果statement输入的内容存在单引号会导致SQL语句出错,而且存在sql注入风险。
PrepareStatement操作
执行的是一个完整的具备特殊标记的SQL语句,并且可以动态的设置所需要的数据。
PrepareStatement是Statement的子接口,需要依赖Connection接口提供的方法:
public PrepareStatement preparStatement(String sql) throws SQLException
传入的这个方法主的sql语句是一个完整的具备特殊标记的完整SQL,但是此时没有内容,当,需要使用一系列的setXxx()方法用于设置所使用的标记设置的具体内容,而后面执行操作时不再传入sql语句。
数据更新
public int executeUpdate() throws SQLException
1)添加操作
//第三部:进行数据库的数据操作
//将要插入的数据
String name = "Mr'Jack";
Date birthday = new Date();
int age = 18;
String note = "Star";
String addSql = "INSERT INTO member(mid, name, birthday, age, note) VALUES (myseq.nextval, ?, ?, ?, ?)"; //使用?来占位
//实例化对象
PreparedStatement stmt = conn.prepareStatement(addSql);
//设置数据
stmt.setString(1, name);
stmt.setDate(2, new java.sql.Date(birthday.getTime()));
stmt.setInt(3, age);
stmt.setString(4, note);
//执行sql
int len = stmt.executeUpdate();
System.out.println(len);
删、改格式和以上相同
数据查询
public ResultSet executeQuery() throws SQLException
1)查询全部数据
//第三部:进行数据库的数据操作
String addSql = "SELECT mid, name, age, birthday, note FROM member";
PreparedStatement stmt = conn.prepareStatement(addSql);
ResultSet rs = stmt.executeQuery();
while(rs.next())
{
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthday = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println(mid+ " " + name +" " + age + " " + birthday + " " + note );
}
2)模糊查询
//第三部:进行数据库的数据操作
String keyWord = "Jack";
String addSql = "SELECT mid, name, age, birthday, note FROM member WHERE name like ?";
PreparedStatement stmt = conn.prepareStatement(addSql);
stmt.setString(1, "%" + keyWord + "%");
ResultSet rs = stmt.executeQuery();
while(rs.next())
{
int mid = rs.getInt("mid");
String name = rs.getString("name");
int age = rs.getInt("age");
Date birthday = rs.getDate("birthday");
String note = rs.getString("note");
System.out.println(mid+ " " + name +" " + age + " " + birthday + " " + note );
}
3)计算记录数量
//第三部:进行数据库的数据操作
String keyWord = "Jack";
String addSql = "SELECT Count(mid) FROM member WHERE name like ?";
PreparedStatement stmt = conn.prepareStatement(addSql);
stmt.setString(1, "%" + keyWord + "%");
ResultSet rs = stmt.executeQuery();
//当只有一个返回值的时候,可以使用if
if(rs.next())
{
int count = rs.getInt(1);
System.out.println("Count = " + count);
}