JDBC学习
JDBC核心思想
JDBC(Java Database Connectivity) Java 连接数据库的规范(标准),可以使用 Java 语言连接数据库完成 CRUD 操作
JDBC 核心思想:Java 中定义了访问数据库的接口,可以为多种关系型数据库提供统一的访问方式。由数据库厂商提供驱动实现类(Driver 数据库驱动)。
管理Driver的类DriverManager由Java为我们提供,Driver是一个接口,Java提供,各自厂商实现接口
JDBC开发步骤
/**
*JDBC开发步骤:
* 0、准备工作
* a、在 当前工程下创建一个lib文件夹
* b、将MySQL的驱动jar包复制到这个文件夹中
* c、右击jar包,选择 add as library(将jar包中内容添加到编译的class路径下)
* 1、加载mysql数据库驱动
* a、Driver driver = new Driver();
* DriverManager.registerDriver(driver);
* b、Class.forName("com.mysql.jdbc.Driver");
* 2、获取数据库连接
* Connection conn = DriverManager.getConnection(url,user,password);
* 3、获取数据库操作对象
* Statement stat = conn.createStatement();
* 4、通过Statement对象执行sql语句
* int count = stat.executeUpdate("delete from emp where empno = 10000");
*
* 5、处理结果
*
* 6、释放资源
* stat.close();
* conn.close();
*/
1、 加载驱动
try {
//方式1、加载mysql数据库驱动
//通过源码发现Driver类中有个静态代码块,已经加载了驱动。
Driver driver = new Driver();
DriverManager.registerDriver(driver);
} catch (SQLException e) {
e.printStackTrace();
}
try {
//方式2、触发这个类加载,进而加载驱动
Class.forName("com.mysql.jdbc.Driver");
} catch (SQLException e) {
e.printStackTrace();
}
//类加载的方式:
//1、通过new关键字来加载
//2、通过调用静态属性加载
//3、通过调用静态方法加载
//4、利用反射加载Class.forName("全限定类名");
2、获取数据库连接
/**
* https://www.baidu.com/
* 协议: https://
* ip地址: www.baidu.com
* 端口号:80
*
* url:表示连接数库的地址
* jdbc:mysql://localhost:3306/数据库名
* 简写方式:jdbc:mysql:///数据库名
* user 用户名
* password 密码
* 注意此处的localhost代表本地连接127.0.0.1,如果链接本地数据库
* 在没有网络的情况下只能写127.0.0.1,因为localhost需要域名解析器
* 联网的时候才能解析
*
*/
String url = "jdbc:mysql://localhost:3306/java2006?useSSL=false";
String user = "root";
String password = "123456";
Connection conn = DriverManager.getConnection(url, user, password);
3、获取数据库操作对象Statement
//3、获取数据库操作对象
Statement stat = conn.createStatement();
4、通过Statement对象执行SQL语句
//4、通过Statement对象执行sql语句,返回受影响的行数
int count = stat.executeUpdate("delete from emp where empno = 10000");
5、处理返回结果
//5、处理结果
if(count > 0){
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
6、关闭资源
//6、释放资源
stat.close();
conn.close();
JDBC开发案例
(查询tb_student表的数据)
public class JDBCDemo03 {
/**
* 0、导包
* 1、注册数据库驱动
* 2、获取数据库连接 Connection
* 3、获取数据库操作对象 Statement
* 4、执行SQL语句,返回一个结果(a、受影响行数 b、结果集)
* 5、处理结果
* 6、释放资源
*/
public static void main(String[] args) {
Connection conn = null;
Statement stat = null;
ResultSet rs = null;
try {
// 1、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取数据库连接 Connection
conn = DriverManager.getConnection("jdbc:mysql:///java2006", "root", "123456");
//3、获取数据库操作对象 Statement
stat = conn.createStatement();
//4、执行SQL语句,返回一个结果集
String sql = "select * from emp";
rs = stat.executeQuery(sql);
//5、处理结果集
/**
* next() 判断是否有下一个元素,如果有返回true,并将游标向下移动。如果没有返回false
* getXXX(参数);XXX指的是数据类型。
* 参数:分为两种情况
* 1、直接写下标(从1开始)
* 2、写字段名 (推荐)
*
*/
while(rs.next()){
int empno = rs.getInt(1);
System.out.print("empno = " + empno);
String ename = rs.getString("ename");
System.out.print("ename = " + ename);
String job = rs.getString("job");
System.out.print("job = " + job);
double sal = rs.getDouble("sal");
System.out.print("sal = " + sal);
Date hiredate = rs.getDate("hiredate");
System.out.println("hiredate = " + hiredate);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally{
try {
//6、释放资源
if(rs!=null){
rs.close();
}
if(stat!=null){
stat.close();
}
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
1、ResultSet结果集
-
next() 判断是否有下一个元素,如果有返回true,并将游标向下移动。如果没有返回false
-
getXXX(参数);XXX指的是数据类型。
-
参数:分为两种情况
* 1、直接写下标(从1开始)
* 2、写字段名 (推荐)
使用statement对象操作数据库的问题
- sql注入问题,statement对象执行sql语句时,使用的是字符串拼接,会导致拼接问题,常见于登录操作
- 用户输入的数据中有 SQL 关键字或语法并且参与了 SQL 语句的编译,导致 SQL 语句编译后的条件含义为 true,一直得到正确的结果。这种现象称为 SQL 注入。
- 字符串的拼接操作也是非常的不方便
引入PreparedStatement
PreparedStatement 继承了 Statement 接口,执行 SQL 语句的方法无异。
作用:
- 预编译SQL 语句,效率高。
- 安全,避免SQL注入 。
- 可以动态的填充数据,执行多个同构的 SQL 语句。
1、使用PreparedStatement完成的登录案例演示
public class LoginDemo2 {
/**
* 0、导包
* 1、注册数据库驱动
* 2、获取数据库连接 Connection
* 3、获取数据库操作对象 PreparedStatement
* 4、执行SQL语句,返回一个结果(a、受影响行数 b、结果集)
* 5、处理结果
* 6、释放资源
*/
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine();
System.out.println("请输入密码");
String password = sc.nextLine();
//1、注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2、获取数据库连接 Connection
Connection conn = DriverManager.getConnection("jdbc:mysql:///java2006", "root", "123456");
//3、获取数据库操作对象 PreparedStatement
String sql = "select * from tb_user where username = ? and password = ?";
PreparedStatement ps = conn.prepareStatement(sql);
/*
3.1 设置占位符的值
setXXX(参数1,参数2)方法 XXX表示数据类型
参数1:表示第几个问号
参数2:参数的值
*/
ps.setString(1,username);
ps.setString(2,password);
System.out.println(ps);
//4、通过PreparedStatement 执行SQL语句,返回一个结果
ResultSet rs = ps.executeQuery();
//5、处理结果
if(rs.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//6、释放资源
rs.close();
ps.close();
conn.close();
}
2、PreparedStatement的使用
- 将要查询的数据用问号(?)代替,此时的sql语句会预加载到PreparedStatement对象中,然后根据数据类型调用PreparedStatement对象中的相应的set方法去设置值,且会给赋的值自动加引号(有需要加的才会加),最后PreparedStatement会将赋好值的sql语句拼接好再去执行