JDBC
概念:
Java Data Base Connectivity (Java 连接数据库)
JDBC,其实就是Java定义的一套和数据库建立连接的规范(接口),
那么各家数据库厂商,想要Java去操作各家的数据库,
必须实现这套接口,
我们把数据库厂商写的这套实现类,称之为数据库驱动
在没有jdbc之前,
我们想用Java连接数据库,需要进行如下步骤:
虽然也不是非常麻烦,但是:
- 针对不同的数据库,我们需要编写不同的驱动代码
- 每当任意一家数据库更新时,维护起来也是十分麻烦的
正是因为上述两点致命麻烦,Java针对连接数据库,提出了一套机制 —— JDBC
因此,JDBC有如下优点:
优点:
- 维护方便
- 数据库厂商的底层实现改变,不影响Java应用程序
一般地,jdbc的接口,都存放在:
JDK提供的
- java.sql.*
- javax.sql.*
包下
那么,现在本人来讲解下使用JDBC的使用步骤:
使用步骤:
使用步骤:
- 导入数据库的驱动jar包
- 加载驱动jar包
- 获取连接对象
- 获取操作对象
- 开始操作
- 释放资源
那么,现在本人来展示下JDBC的使用:
package edu.youzg.about_jdbc.core;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class Demo {
public static void main(String[] args) throws Exception {
//2. 加载驱动jar包
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/dbstudy";
String userName = "root";
String password = "123456";
//3. 获取连接对象
Connection connection = DriverManager.getConnection(url, userName, password);
//4. 获取操作对象
Statement statement = connection.createStatement();
String sql = "update test set emp_fname='Youzg'";
//5. 开始操作
int i = statement.executeUpdate(sql);
if(i>0){
System.out.println(i);
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//6. 释放资源
connection.close();
statement.close();
}
}
本人先来展示下运行前的表内容:
现在,本人来展示下运行后的表中数据:
那么,本人对上述步骤的第2步进行下讲解:
- execute(sql):
用来执行所有的SQL语句
返回:
如果第一个结果为 ResultSet 对象,则返回 true;
如果其为更新、计数或者不存在任何结果,则返回 false- executeUpdate(sql):
用来执行DML语句
用来对表中数据进行增、删、改
返回值:
影响的行数- executeQuery(sql):
用来执行DQl语句
结果集对象 ResultSet:
概念:
结果集对象,是我们执行了查询语句之后返回的一个查询结果对象
ResultSet 对象具有指向其当前数据行的光标
最初,光标被置于第一行之前。
next()方法将光标移动到下一行;
因为该方法在 ResultSet 对象没有下一行时返回 false,
所以可以在 while循环中使用它来迭代结果集
例如:
现在我要查询表中数据:
package edu.youzg.about_jdbc.core;
import java.sql.*;
public class Demo2 {
public static void main(String[] args) throws Exception{
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbstudy", "root", "123456");
Statement statement = connection.createStatement();
String sql = "select * from test";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()) {
System.out.println(resultSet.getInt(1)
+ "==" + resultSet.getString(2)
+ "==" + resultSet.getString(3)
+ "==" + resultSet.getString(4));
}
connection.close();
statement.close();
resultSet.close();
}
}
那么,本人现在来展示下运行结果:
那么,还记得本人在《Java SE》专栏最后说的吗?
等我们学习了数据库的相关知识后,
用户登录信息就可以保存在数据库中,就不用用一张配置表来保存了
这样既简化了注册用户的问题,也保证了用户账号信息的安全性
本人来给出一张保存用户登录信息的表:
那么,现在本人仅来展示下检验用户信息的代码:
package edu.youzg.about_jdbc.core;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner;
public class LoginDemo {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine().trim();
System.out.println("请输入密码");
String password = sc.nextLine().trim();
//使用JDBC登录
Class.forName("com.mysql.jdbc.Driver");
//建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql:///dbstudy", "root", "123456");
//获取操作对象
Statement statement = conn.createStatement();
//发送sql语句判断是否登录成功
String sql="select * from users where username='"+username+"' and password='"+password+"'";
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//释放资源
conn.close();
statement.close();
resultSet.close();
}
}
那么,本人来展示下运行结果:
其实,上面的做法也是不安全的
本人现在来展示下为什么说是不安全的:
相信同学们这时候就疑惑了:为什么用户登录信息表中并没有保存该登录信息,却能够登陆呢?
答曰:
请看我们最后拼出来的sql字符串:
select * from users where username='1' or '1'='1' and password='1' or '1'='1';
相信看到这里,同学们就明白了登陆成功的原因了。
而这种现象,我们也有专门的名词来形容它 —— sql注入
那么,有没有什么办法能够防止sql注入呢?
答曰:
预编译操做对象 PreparedStatement
那么,现在本人来介绍下 预编译操做对象 PreparedStatement:
PreparedStatement:
使用步骤:
- 连接对象.prepareStatement(sql);
- sql语句中的字段的值用?问号占位
- 给sql语句中的问号赋值
本人现在来展示下PreparedStatement的使用:
package edu.youzg.about_jdbc.core;
import java.sql.*;
import java.util.Scanner;
public class LoginDemo1 {
public static void main(String[] args) throws Exception {
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine().trim();
System.out.println("请输入密码");
String password = sc.nextLine().trim();
//使用JDBC登录
Class.forName("com.mysql.jdbc.Driver");
//建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql:///dbstudy", "root", "123456");
//获取操作对象
String sql="SELECT * FROM users WHERE username=? AND PASSWORD=?";
//获取一个预编译操作对象 PreparedStatement
PreparedStatement preparedStatement = conn.prepareStatement(sql); //把SQL语句给给这个预编译操作对象
//下来给问号赋值 参1.问号的顺序,从1开始数 参数2 问号的值
preparedStatement.setString(1,username);
preparedStatement.setString(2,password);
ResultSet resultSet = preparedStatement.executeQuery(); //这里就不要再传入SQL语句
if(resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
//释放资源
conn.close();
preparedStatement.close();
resultSet.close();
}
}
那么,本人再来进行下sql注入,来展示下运行结果:
可以看到:预编译操作对象的使用,放置了sql注入!
那么,为了方便我们之后的操作,本人来给出一个方便我们JDBC操作的工具类:
package edu.youzg.about_jdbc.utils;
import java.io.FileInputStream;
import java.sql.*;
import java.util.Properties;
/**
* 此工具用于实现JDBC的基本 增、删、改、查 操作
*/
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private JDBCUtils() {
}
static {
try {
//读取配置文件中数据库的配置
Properties properties = new Properties();
properties.load(new FileInputStream("JDBCStudy/src/jdbcConfig.properties"));
//注册驱动
Class.forName(properties.getProperty("driver"));
url = properties.getProperty("url");
user = properties.getProperty("user");
password =properties.getProperty("password");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
Connection connection = DriverManager.getConnection(url, user, password);
return connection;
}
public static void close(Connection connection, Statement statement) throws SQLException {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
}
public static void close(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {
if (connection != null) {
connection.close();
}
if (statement != null) {
statement.close();
}
if (resultSet != null) {
resultSet.close();
}
}
}
那么,相应地,本人来给出一个配置文件:
driver=com.mysql.jdbc.Driver
#注意:这里的url是本人根据本人的数据库信息配置的,同学们请根据自己的数据库信息来给url赋值
url=jdbc:mysql://localhost:3306/dbstudy
user=root
password=123456
在本篇博文的最后,本人来讲解下如何在JDBC中获取自增长键的值:
获取自增长键的值:
步骤:
- 要获取自增长键的值,需要在获取操作对象时声明一个参数:
Statement.RETURN_GENERATED_KEYS
即:
PreparedStatement preparedStatement = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
- 当数据插入成功后,就可以取出这个自增长键的值:
//获取自增长键的结果集
ResultSet generatedKeys = preparedStatement.getGeneratedKeys();
while (generatedKeys.next()){
keyValue = generatedKeys.getInt(1);
}
- 之后就可以对循环中每次取出的自增长键值做处理了