JDBC
概念:Java DataBase Connectivity ,Java数据库连接,Java语言操作数据库
JDBC本质:其实是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
步骤:
- 导入驱动jar包
- 注册驱动
- 获取数据库连接对象 Connection
- 定义sql
- 获取执行sql语句的对象 Statement
- 执行sql,接收返回结果
- 处理结果
- 释放资源
详解各个对象:
-
DriverManager:驱动管理对象
功能:
1.注册驱动:static void registerDriver(Driver driver):注册与给定的驱动程序DriverManager,告诉程序该使用哪一个数据库驱动jar
写代码时使用:Class.forName(“com.mysql.jdbc.Driver”);底层实现了上面的registerDriver()方法
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
2.获取数据库连接:static Connection getConnection(String url,String user,String password)
url:指定连接的路径 jdbc:myysql://ip地址(域名):端口号/数据库名称
如果连接的是本机mysql服务器,并且mysql服务器默认端口为3306,则url可以简写为:jdbc:mysql:///数据库名称
-
Connection:数据库连接对象
功能:
1.获取执行sql的对象:
Statement createStatement()
PreparedStatement prepareStatement()
2.管理事务:
开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
提交事务:commit()
回滚事务:rollback()
-
Statement:执行sql的对象
执行sql:
boolean execute(String sql); 可以执行任意的sql
int executeUpdate(String sql):执行DML(insert、update、delete)语句,DDL(create、alter、drop)语句 返回值是受影响的行数,可以通过这个影响的行数来判断DML语句是否执行成功 返回值>0则执行成功,否则失败
ResultSet executeQuery(String sql):执行DQL(select)语句返回结果集对象
-
ResultSet:结果集对象,封装查询结果
1.next():右表向下移动一行(游标起始位置在结果集第一个数据前一个位置)
2.getXxx():获取数据 Xxx代表数据类型
-
PreparedStatement:执行sql的对象
1.SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题。
2.解决SQL注入问题:使用PreparedStatement对象 它是预编译sql
3.预编译sql:即动态sql,参数使用?作为占位符
4.静态sql容易产生SQL注入问题
将JDBC冗余操作封装到一个工具类中
package util;
import java.io.FileReader;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
//JDBC工具类
public class JDBCUtils {
private static String url;
private static String user;
private static String password;
private static String driver;
/**
文件的读取,只需要读取一次即可拿到。使用静态代码块
*/
static {
try{
//读取资源文件
//1.创建properties集合类
Properties pro = new Properties();
//获取xx路径下的文件的方式--->ClassLoader类加载器
ClassLoader classLoader = JDBCUtils.class.getClassLoader();
URL res = classLoader.getResource("jdbc.properties");
String path = res.getPath();
//2.加载文件
pro.load(new FileReader("path"));
//3.获取数据
url = pro.getProperty("url");
user = pro.getProperty("user");
password = pro.getProperty("password");
driver = pro.getProperty("driver");
//注册驱动
Class.forName(driver);
}catch(Exception e) {
System.out.println(e.getMessage());
}
}
//获取连接返回连接对象
public static Connection getConnection(){
Connection conn = null;
try{
conn = DriverManager.getConnection(url,user,password);
}catch(Exception e){
System.out.println(e.getMessage());
};
return conn;
}
/**
* 释放资源
* @param stmt
* @param conn
*/
public static void close(Statement stmt,Connection conn){
if (stmt!=null){
try{
stmt.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
if (conn!=null){
try{
conn.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
public static void close(ResultSet rs, Statement stmt, Connection conn){
if (rs!=null){
try{
stmt.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
if (stmt!=null){
try{
stmt.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
if (conn!=null){
try{
conn.close();
}catch(Exception e){
System.out.println(e.getMessage());
}
}
}
}
//jdbc.properties
url = jdbc:mysql://db1
user=root
password=root
driver=com.mysql.jdbc.Driver
JDBC控制事务:
1.事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
2.使用Connection对象来管理事务
开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务 在执行sql之前开启事务
提交事务:commit() 在所有sql都执行完成后提交事务
回滚事务:rollback() 在catch中写回滚事务
数据库连接池:是一个容器(集合),存放数据库连接的容器。当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完后会将连接对象归还给容器。节约了资源,并且用户访问高效。
1.实现:
1.标准接口:DataSource javax.sql包下的
方法:
获取连接:getConnection()
归还连接:如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会再关闭连接了,而是归还连接
2.一般我们不去实现它,有数据库厂商来实现
1.C3P0:数据库连接池技术
2.Druid:数据库连接池实现技术,由阿里巴巴提供的
2.C3P0:数据库连接池技术
步骤:
3.Druid:数据库连接池实现技术,由阿里巴巴提供
3.1 定义工具类
定义一个类 JDBCUtils
提供静态代码块加载配置文件,初始化连接池对象
提供方法:
获取连接方法:通过数据库连接池获取连接
释放资源
获取连接池的方法
DruidDemo.java
public class DruidDemo {
public static void main(String[] args) throws Exception {
//1.加载配置文件
Properties pro = new Properties();
InputStream is = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
pro.load(is);
//2.获取连接池对象
DataSource ds = DruidDataSourceFactory.createDataSource(pro);
//3.获取连接
Connection conn = ds.getConnection();
System.out.println(conn);
}
}
druid.properties
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db1?serverTimezone=Asia/Shanghai
username=root
password=root
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
DruidTest.java
//测试工具类
public class DruidTest {
public static void main(String[] args) throws SQLException {
//给dept表添加一条记录
//1.获取连接
Connection conn = JDBCUtils.getConnection();
//2.定义sql
String sql = "insert into dept values(?,?,?)";
//3.获取邮差对象
PreparedStatement ps = conn.prepareStatement(sql);
//4.给?赋值
ps.setInt(1,50);
ps.setString(2,"HAHAHAH");
ps.setString(3,"CHINA");
//5.执行sql
ps.executeUpdate();
}
}
JDBCUtils.java
/*
Druid连接池的工具类
*/
public class JDBCUtils {
//1.定义成员变量 DataSource
private static DataSource ds;
static {
//1.加载配置文件
Properties pro = new Properties();
try {
pro.load(JDBCUtils.class.getResourceAsStream("druid.properties"));
//获取DataSource
ds = DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Statement stmt,Connection conn){
if (stmt!=null) {
try {
stmt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if (conn!=null){
try {
conn.close();//归还连接
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
public static void close(ResultSet rs, Statement stmt, Connection conn){
if (rs!=null) {
try {
rs.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if (stmt!=null) {
try {
stmt.close();
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
if (conn!=null){
try {
conn.close();//归还连接
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
}
//获取连接池
public static DataSource getDataSource(){
return ds;
}
}