一、什么是jdbc ?
Java database connectivity: Java连接数据库技术
1.Sun公司研发java语言的程序员,他们定义出来的java连接数据库的一些接口。这些接口就是jdbc。
2.接口没有具体的功能,但是他统一了java连接各个数据库的标准。具体的实现类有各个数据库厂商去实现。
3.数据库厂商写好这些实现类后,把这些类打成压缩包,放到官网上,供java程序员下载使用。这些压缩包被称为jdbc驱动。
4.Java程序员想连接某个数据库,需要从该数据库官网上把jdbc驱动下载下来引入到自己的项目中,然后通过jdbc的接口提供的方法就可以连接到该数据库上了。
二、Jdbc的api(application program interface)
之前使用plsqldev或者navicat工具连接到数据库的过程:
1.输入账号,密码,数据库,连接到数据库服务器上。
2.连接到数据库上后,我们需要打开一个sql窗口,在sql窗口里面去写sql语句。
3.点击执行按钮
4.如果是dql语句,会得到一个查询结果,如果是dml,没有结果执行结束。
5.关闭窗口,整个过程结束。
使用java连接数据库需要的类或接口:
Connection:封装了数据库的连接,该对象一旦被创建,java代码就连接到了oracle数据库上。
PreparedStatement:执行器对象,当你要执行sql脚本时,你需要把sql脚本放入到该对象里面。
ResultSet:结果集对象,该对象封装的是dql的查询结果。
上面这些接口都在java.sql这个包里面。
Driver:jdbc驱动。各个数据库厂商实现的jdbc实现类。这些驱动是以压缩包的形式存在的。格式jar。这些jar包需要到各个数据库官网上下载。
DriverManager:各个数据库驱动的管理者。他是来管理众多的数据库驱动的。
三、使用jdbc连接Oracle数据库实例
让java连接到数据库上,创建出Connection conn对象。
前提准备:
1.下载jdbc驱动。
C:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar
2.把jar包放入到我们的项目中。在项目上面右键—》新建—》folder—》lib
3.让项目识别jar包。在jar上面右键—》bulid path—>add jar to bulid path
数据库连接步骤为:
1.加载驱动。
2.建立连接
3.写sql语句。
4.创建ps对象。
5.执行
6.释放资源。
例如:
package testconn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author 超伟
* @2019年5月26日 上午10:13:08
* @博客:https://blog.csdn.net/MacWx
*/
public class conn {
/**
* @param args
* @throws ClassNotFoundException
* @throws SQLException
*/
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// TODO Auto-generated method stub
//1,加载数据库连接驱动
Class.forName("oracle.jdbc.OracleDriver");
//2,创建连接
/*getConnection需要三个参数:
* 第一个参数是数据库信息,
* jdbc:oracle:thin指的是两台电脑之间连接的协议
* @localhost:1521:指的是 要找哪台计算机上的数据库,并且指明端口号,localhost指的是自己的本机电脑
* 第二个参数是连接数据库的账号
* 第三个参数是连接数据库的密码
*/
Connection conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
System.out.println(conn);
//创建出prepareStatement对象,向数据库中插入一条数据
String sql = "insert into t_student(student_id,student_name,age,sex) values (seq_student.nextval,'macw',18,'男') ";
PreparedStatement ps = conn.prepareStatement(sql);
//执行ps里面 的sql脚本,如果是增删改dml语言,则调用ps 的executeUpdate方法;
ps.executeUpdate();
//关闭ps资源,后创建的对象先关闭
ps.close();
//3,关闭数据库连接
conn.close();
}
}
1.rs对象是对结果集的封装。
2.Rs调用一次next方法,光标就往下移动一行。
3.Next方法是有返回值的。返回值表示移动后,指向的行是否有数据。
4.从rs里面获取数据需要用到rs.getXxx(“字段名”)。其中xxx表示数据类型,参数表示字段名。
5.注意不要在while循环里面试图调用两次next方法。这样展示的数据就会有漏掉的。
这是一个对于数据库的DML (Data Manipulation Language) 数据操纵语言,插入一条数据,是没有返回值的,其他增删改也是一样没有返回值,但是查询就不一样了,查询有返回值,
查询操作的示例代码如下:
package testconn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* @author 超伟
* @2019年5月26日 下午3:15:53
* @博客:https://blog.csdn.net/MacWx
*/
public class connQuery {
/**
* @param args
* @throws ClassNotFoundException
* @throws SQLException
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1,加载数据库连接驱动
Class.forName("oracle.jdbc.OracleDriver");
// 2,创建连接
/* getConnection需要三个参数: 第一个参数是数据库信息, jdbc:oracle:thin指的是两台电脑之间连接的协议
* @localhost:1521:指的是 要找哪台计算机上的数据库,并且指明端口号,localhost指的是自己的本机电脑
* 第二个参数是连接数据库的账号 第三个参数是连接数据库的密码
*/
conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
// 创建出prepareStatement对象,并查询student表中所有数据
String sqlQuery = "select * from t_student";
// 执行ps里面 的sql脚本,如果是查询语言dql,则调用ps 的executeQuery方法;
ps = conn.prepareStatement(sqlQuery);
rs = ps.executeQuery(sqlQuery);
// 从rs中获取数据
// 让rs结果集光标从第一行的上一行指向第一行数据, 返回值表示如果第二行有数据, rs.next();就是true。否则为false
// 所以,循环遍历t_student表中所有数据,让rs光标往下移,如果有数据就继续打印,没有就不进入循环
while (rs.next()) {
// 获取id
int id = rs.getInt("student_id");
// 获取name
String name = rs.getString("student_name");
System.out.println(id + "\t" + name);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭ps资源,后创建的对象先关闭
//这里建议每一个关闭操作都单独抛出一个异常,保证每一个都可以正常关闭
try {
if (rs != null) {
rs.close();}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
ps.close(); }
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
conn.close(); }
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
四、prepareStatement的占位符:
为什么要使用占位符?
1.字符串拼接后,代码的可读性差。
2.字符串拼接后,代码容易出现sql注入。安全性出现问题。
例如:假如说要实现一个简单的登录操作,如果用户密码都正确则输出登录成功,否则登录失败!
数据库设计如下:
--创建用户表
CREATE TABLE t_USer(
user_id NUMBER(5) primary key,
username VARCHAR2(30),
password VARCHAR2(30)
);
--建立索引
create sequence seq_uid;
--插入数据
INSERT INTO t_user VALUES (seq_uid.nextval,'aaa','111');
INSERT INTO t_user VALUES (seq_uid.nextval,'bbb','222');
INSERT INTO t_user VALUES (seq_uid.nextval,'ccc','333');
SELECT * FROM t_user;
java 实现登录操作如下:
package testconn;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
/**
* @author 超伟
* @2019年5月26日 下午4:26:25
* @博客:https://blog.csdn.net/MacWx
*/
public class testLogin {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入账号:");
String name = sc.nextLine();
System.out.println("请输入密码:");
String pwd = sc.nextLine();
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
try {
// 1,加载数据库连接驱动
Class.forName("oracle.jdbc.OracleDriver");
// 2,创建连接
conn = DriverManager.getConnection( "jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");
// 创建出prepareStatement对象
String sqlQuery = "select * from t_user where username = ? and password = ?";
// 执行ps里面 的sql脚本,如果是查询语言dql,则调用ps 的executeQuery方法;
ps = conn.prepareStatement(sqlQuery);
ps.setString(1, name);
ps.setString(2, pwd);
rs = ps.executeQuery();
// 从rs中获取数据
if (rs.next()) {
// 获取id
int id = rs.getInt("user_id");
// 获取name
String usa = rs.getString("username");
String pwds = rs.getString("password");
System.out.println(id + "\t" + usa + "\t" + pwds);
System.out.println("登录成功");
}else {
System.out.println("登录失败!");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭ps资源,后创建的对象先关闭
try {
if (rs != null) {
rs.close();}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
ps.close();}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (rs != null) {
conn.close(); }
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
注意事项:
1.占位符可以用到dql,dml
2.占位符只可以表示一个具体的值,不能表示sql中的关键字。
3.给占位符赋值一定要写在执行之前。