本章内容
目录
一、JDBC简介
1.JDBC工作原理
JDBC简介
- JDBC(Java Data Base Connectivity)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成
- JDBC为程序开发人员提供了一个标准的API,程序开发人员能够用纯 Java API 编写应用程序操作数据库
- 有了JDBC,在编写程序时,就不必为程序可以支持不同的数据库而写一套针对不同数据库的连接、操作代码,只需用JDBC API写一套代码就够了
2.JDBC驱动类型
JDBC工作原理
JDBC API是集成在JDK中的,提供了Java应用程序和各种不同类型的数据库之间交互的标准接口,程序开发人员通过这些接口可以操作各类数据库
1、Connection接口:负责数据库连接并担任传送数据的任务
2、Statement接口:负责执行SQL语句,由Connection接口产生
3、ResultSet接口:负责保存和处理查询结果集,由Statement接口产生
4、PreparedStatement接口:Statement接口的子接口,也是由Statement接口产生,具体不同支出后面内容会详细介绍
JDBC Driver Manager
JDBC Driver Manager是集成在JDK中的,由Sun提供,它负责管理各种不同的JDBC驱动;可以通过操作DriverManager类,根据数据库的不同,管理相应的JDBC驱动
JDBC驱动
JDBC驱动是由各个数据库厂商提供的,负责连接不同类型的数据库。因为不同厂商针对不同类型的数据库,提供了不同类型的驱动,解决了各个数据库之间的差异,所以JDBC API才能操作不同类型的数据库
JDBC驱动类型
JDBC-ODBC桥驱动
本地API驱动
网络协议驱动
本地协议驱动(纯Java驱动)
- JDBC操作数据库步骤
JDBC操作数据库代码模版
try {
//1、加载驱动
Class.forName(JDBC驱动类);
} catch (ClassNotFoundException e) {System.out.println("加载驱动不成功");}
try {
//2、创建JDBC连接,其中有三个参数,分别是JDBC URL、数据库用户名和密码
Connection conn = DriverManager.getConnection(JDBC URL,数据库用户名,密码);
//3、创建Statement对象,准备执行SQL语句
Statement stmt = conn.createStatement();
//4、执行SQL语句,返回结果(可能是结果集)
ResultSet rs = stmt.executeQuery("SELECT id, name FROM users");
//5、操作结果集
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
}
//6、关闭连接
conn.close();
} catch (SQLException e) {e.printStackTrace();}
MySQL和Oracle的Driver和URl
//加载mysql数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//连接mysql数据库
String url = "jdbc:mysql://localhost:3306/jdbctest?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC" ;
//加载oracle数据库驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//连接oracle数据库
String url= "jdbc:oracle:thin:@127.0.0.1:1521:orcl";
JDBC操作数据库步骤
- 把驱动包放到tomcat的lib文件夹
- 把驱动包引入项目
- 加载驱动
- JDBC连接
- 连接
二、JDBC接口及类
DriverManager
Connection
Statement
PreparedStatement
ResultSet
1.DriverManager类
DriverManager类是JDBC的管理层,作用于用户和驱动程序之间。
2.Connection接口
Connection对象代表和数据库的连接,用于获得连接对象。
案例1: 使用jdbc测试oracle是否成功
3.Statement接口
Statement是提供在基层连接上运行sql语句的,Connection接口中提供了生成Statement的方法.
Statement接口方法
方法 | 描述 |
executeQuery | 执行SQL查询并返回ResultSet对象 |
executeUpdate | 可以执行插入、删除、更新等操作,返回值是执行该操作所影响的行数 |
execute | 可以执行任意SQL语句,返回一个布尔值,表示是否返回ResultSet |
-
- ResultSet接口
在Statement执行了SQL语句以后,结果值是以结果集的方式返回的。ResultSet就是包含查询结果的结果集。
ResultSet接口方法
方法 | 描述 |
next | 将游标从当前位置向下移动一行,返回值为布尔类型 |
previous | 将游标从当前位置向上移动一行,返回值为布尔类型 |
getRow | 得到游标当前所在行数 |
absolute | 游标移动到指定的行,输入参数为指定的行数 |
close | 关闭ResultSet对象 |
getInt | 获取结果集当前行指定字段号(或字段名)值,输入参数可以是字段的序号,也可以是字段名称,返回值为int数据类型 |
getFloat | 与getInt类似,返回值为float数据类型 |
getString | 与getInt类似,返回值为String类型 |
案例2: 使用Statement对象读取emp表数据
案例3: 使用Statement模拟登录操作
注意:Statement带来的SQL注入问题
-
- PreparedStatement接口
PreparedStatement 接口创建表示预编译的 SQL 语句的对象。 SQL 语句经过预编译,并存储在 PreparedStatement 对象中。然后,此对象可用来有效地多次执行此语句。
案例4:使用PreparedStatement解决SQL注入问题
SQL注入:
select * from tb_name where username= '随意' and passwd = '' or '1' = '1';
PreparedStatement和Statement的用法区别
PreparedStatement接口继承Statement,prepareStatement会先初始化SQL,先把这个SQL提交到数据库中进行预处理,多次使用可提高效率.
作为 Statement 的子类,PreparedStatement 继承了 Statement 的所有功能。三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数
在JDBC应用中,如果你已经是稍有水平开发者,你就应该始终以PreparedStatement代替Statement.也就是说,在任何时候都不要使用Statement.
//1加载驱动
Class.forName("oracle.jdbc.driver.OracleDriver");
//2 创建连接
String url="jdbc:oracle:thin:@localhost:1521:orcl";
String user="scott";
String password="123456";
Connection conn=DriverManager.getConnection(url, user, password);
System.out.println(conn);
// 3通过连接创建Statement对象
String sql="select * from emp where deptno = ? and job= ?";
PreparedStatement pstm=conn.prepareStatement(sql);
//Statement stm=conn.createStatement();
// 4 通过Statement对象执行SQL语句并返回结果集
//String sql="select * from emp";
int deptno=10;
String job="MANAGER";
pstm.setInt(1, deptno);
pstm.setString(2, job);
ResultSet rs=pstm.executeQuery();
// 5 处理结果集
while(rs.next()) {
System.out.println(rs.getInt(1)+" "+rs.getString("ename"));
}
// 6 关闭资源
rs.close();
pstm.close();
conn.close();
实体类
package lanqiao.jdbc;
//对应数据库
import java.util.Date;
public class User {
private int id;
private String name;
private String sex;
private String tiem;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getTiem() {
return tiem;
}
public void setTiem(String tiem) {
this.tiem = tiem;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", sex=" + sex + ", tiem=" + tiem + ", birthday=" + birthday + "]";
}
}
package jdbcDome;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class DBUtil {
static {
try {
//加载驱动 放到静态块 只加载一次 提高效率
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static Connection getConn() {
try {
//连接数据库
Class.forName("com.mysql.jdbc.Driver");
String url="jdbc:mysql://localhost:3306/shof?useUnicode=true&characterEncoding=utf8"";
String user="root";
String password="123456";
Connection conn=DriverManager.getConnection(url, user, password);
return conn;
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return null ;
}
//关闭资源 重复代码 多次使用 可以提出来单独写成一个方法
public static void Close(ResultSet rs,Statement stm,Connection conn) {
try {
rs.close();
stm.close();
conn.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
package lanqiao.jdbc;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import jdbcDome.DBUtil;
public class UserDao {
//对数据库进行的操作
//根据id查询用户
public User getByid(int id) {
User user=null;
try {
Connection conn=DBUtil.getConn();
String sql="select * from user where id=?";
PreparedStatement pstm;
pstm = conn.prepareStatement(sql);
pstm.setInt(1, id);
ResultSet rs=pstm.executeQuery();//查询
// 5 处理结果集
if(rs.next()) {
user=new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setSex(rs.getString("sex"));
user.setTiem(rs.getString("tiem"));
user.setBirthday(rs.getDate("birthday"));
}
// 6 关闭资源
DBUtil.Close(rs, pstm, conn);
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return user;
}
//查询所有用户
public List<User> getAll(){
List<User> list=new ArrayList<User>();
Connection conn=DBUtil.getConn();
// 3通过连接创建Statement对象
Statement stm;
try {
stm = conn.createStatement();
String sql="select * from user";
// 4 通过Statement对象执行SQL语句并返回结果集
ResultSet rs=stm.executeQuery(sql);
// 5 处理结果集
while(rs.next()) {
User user=new User();
user.setId(rs.getInt("id"));
user.setName(rs.getString("name"));
user.setSex(rs.getString("sex"));
user.setTiem(rs.getString("tiem"));
user.setBirthday(rs.getDate("birthday"));
list.add(user);
}
DBUtil.Close(rs, stm, conn);
} catch (SQLException e) {
e.printStackTrace();
// TODO Auto-generated catch block
}
return list;
}
//修改用户
public Boolean upData(User user) {
boolean flag=false;
try {
Connection conn=DBUtil.getConn();
String sql="update user set name=?,tiem=?,birthday=? where id=?";
PreparedStatement pstm;//替换问号
pstm = conn.prepareStatement(sql);
pstm.setString(1,user.getName());
pstm.setString(2,user.getTiem());
pstm.setDate(3,new java.sql.Date(user.getBirthday().getTime()));
pstm.setInt(4, user.getId());
int rs=pstm.executeUpdate(); //修改删除插入
// 5 处理结果集
if(rs>0) {
flag=true;
}
// 6 关闭资源
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return false;
}
//根据id 删除用户
public void delete(int id) {
Connection conn=DBUtil.getConn();
String sql="delete from user where id=?";
PreparedStatement pstm;
try {
pstm = conn.prepareStatement(sql);
pstm.setInt(1,id);
pstm.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//添加用户
public void inser(User user) {
Connection conn=DBUtil.getConn();
String sql="insert into user value(null,?,?,?,?)";
PreparedStatement pstm;
try {
pstm = conn.prepareStatement(sql);
pstm.setString(1,user.getName());
pstm.setString(2,user.getSex());
pstm.setString(3,user.getTiem());
pstm.setDate(4,new java.sql.Date(user.getBirthday().getTime()));
pstm.executeUpdate();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
测试类
package lanqiao.jdbc;
import java.util.Date;
import java.util.List;
public class Test {
public static void main(String[] args) {
UserDao dao=new UserDao();
List<User> list=dao.getAll();
for(User u:list) {
System.out.println(u);
}
/*
User user1=new User();
user1.setName("ttt");
user1.setTiem("1998-10-1 12:30:30");
user1.setBirthday(new Date());
user1.setId(2);
dao.upData(user1);
User user = dao.getByid(3) ;
System.out.println(user);
*/
//dao.delete(2);
/*
User user1=new User();
user1.setName("ttt");
user1.setSex("女");
user1.setTiem("1998-10-1 12:30:30");
user1.setBirthday(new Date());
dao.inser(user1);
*/
}
}