文章目录
- 前言
- JDBC简介
- 总结
- 参考链接
前言
Java开发中需要和数据库打交道,但Java如何才能实现和数据库的连接呢?答案是JDBC。
JDBC简介
JDBC(Java DataBase Connectivity, java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口(大部分)和类组成。
JDBC需要连接驱动,驱动的作用是实现JDBC接口,在实现类中可以对应的操作数据库。JDBC与数据库驱动的关系如图所示,JDBC作为Java的接口提供了操作数据库的统一规范,各数据库只要实现这套接口,就可以完成Java与数据库的对接。
也就是说,驱动一般都由数据库生产厂商提供。
# MySQL在Java中的使用步骤
- 开发前的准备工作
导入MySQL的驱动jar包到工程中。过程参考下图:
博主下载的驱动位:mysql-connection-java-5.1.39-bin.jar。
MySQL连接驱动下载地址:MySqlConnectors 2. 注册驱动
注册驱动方式一:
com.mysql.jdbc.Driver driver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
通过这种方式可以知道,mysql的驱动在com.mysql.jdbc.Driver类下。也就是驱动是mysql厂家实现的。
在eclipse中查看MySQL的com.mysql.jdbc.Driver类,会发现如下问题,此时需要增加源码。
加载完源文件,得到com.mysql.jdbc.Driver类的源码如下:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
// 静态代码块
// Register ourselves with the DriverManager
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
public Driver() throws SQLException {
// Required for Class.forName().newInstance()
}
}
在这个驱动类中有静态代码块,根据代码块分类这篇文章可知: 静态代码块在类中方法外出现,并加上static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次。一般用于加载驱动。
可以知道在com.mysql.jdbc.Driver类中已经默认加载了驱动,如果使用方式一注册驱动,就会把驱动注册两遍。
注册驱动方式二:
java.sql.Driver driver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver);
通过这种方式可以知道,com.mysql.jdbc.Driver继承了java.sql.Driver接口,所以java.sql.Driver driver = new com.mysql.jdbc.Driver();
成立。
注册驱动方式三:
Class.forName("com.mysql.jdbc.Driver");
这种方式采用反射机制可以保证驱动只注册一次。Class也是Java的一个类,保存的是与之对应 Java 类的meta信息(元信息),用来描述这个类的结构,比如描述一个类有哪些成员,有哪些方法等。
当使用一个类的时候(比如 new一个类的实例),会检查此类是否被加载到内存,如果没有,则会执行加载操作。读取类对应的 class 文件数据,解析此数据,构造一个此类对应的 Class 类的实例。此时JVM就可以使用该类了,比如实例化此类,或者调用此类的静态方法。
类被加载之后,jvm 已经获得了一个描述类结构的 Class 实例。但是还需要进行类初始化操作之后才能正常使用此类,类初始化操作就是执行一遍类的静态语句,包括静态变量的声明还有静态代码块。
- 获取和数据库的连接对象: 是Connection接口的实现类对象
String url = "jdbc:mysql://localhost:3306/db02";
// jdbc:固定语法 数据库厂商名 IP地址 端口号 要连接的数据库
// 生成Connection对象
Connection conn = DriverManager.getConnection(url, "root", "root");
- 获取SQL语句的执行者对象: Statement接口和PreparedStatement接口
方式一:Statement接口类型执行者对象(这种方式会产生SQL注入)
Statement st = conn.createStatement();
SQL注入:用户输入的内容作为了SQL语句语法的一部分,改变了原有SQL真正的意义。假设有登录案例SQL语句如下:
SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;
此时,当用户输入正确的账号与密码后,查询到了信息则让用户登录。但是当用户输入的账号为XXX 密码为:XXX’ OR ‘a’=’a时,则真正执行的代码变为:
SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
此时,上述查询语句时永远可以查询出结果的。那么用户就直接登录成功了,显然我们不希望看到这样的结果,这便是SQL注入问题。为此,我们使用PreparedStatement来解决对应的问题。
方式二:PreparedStatement接口类型执行者对象
preparedStatement:预编译对象,是Statement对象的子类,会把sql语句先编译
,能过滤掉用户输入的关键字。PreparedStatement预处理对象,处理的每条sql语句中所有的实际参数,都必须使用占位符?替换。
String sql = "select * from users where username = ? AND password = ?";
PreparedStatement pst = conn.prepareStatement(sql);
pst.setObject(1, username);
pst.setObject(2, password);
void setXxx(int index, Xxx xx) 将指定参数设置指定类型的值
参数1:index 实际参数序列号,从1开始。
参数2:xxx 实际参数值,xxx表示具体的类型。
例如:
setString(2, "1234") 把SQL语句中第2个位置的占位符?替换成实际参数 "1234"
- 结果集对象:是ResultSet接口的实现类对象
ResultSet rs = pst.executeQuery(); // 查询
int rows = pst.executeUpdate(); // 增删改
总结
Java的内容太多,所以需要勤记笔记!