JDBC-API详解和数据库连接池使用

JDBC-API详解和数据库连接池使用

文章目录

  • JDBC-API详解和数据库连接池使用
    • 一、DriverManager(驱动管理类)
    • 二、Connection(数据库连接对象)
    • 三、Statement
    • 四、ResultSet(结果集对象)
    • 四、PreparedStatement
    • 五、数据库连接池

一、DriverManager(驱动管理类)

DriverManager(驱动管理类)作用:

  • 注册驱动
  • 获得数据库连接

注册驱动的相关函数:Class.forName(com.mysql.cj.jdbc.Driver) – 可以不写

  • 提示:MySql5之后又的驱动包,可以省略注册驱动的步骤
  • 自动加载jar包中META-INF/services/java.sql.Driver文件中的驱动类

JDBC-API详解和数据库连接池使用_第1张图片

获得数据库连接的函数:static Connection getConnection(String url, String user, String password)
url语法格式:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1&参数键值对2…
示例:“jdbc:mysql://localhost:3306/数据库名”

提示细节:

  • 如果连接的是本机的mysql服务器,并且mysql服务器的默认端口是3306,则url可以简化:jdbc:mysql:///数据库名称?参数值键值对
  • 配置useSSL=false参数,禁止安全连接方式,解决警告提示

JDBC-API详解和数据库连接池使用_第2张图片

二、Connection(数据库连接对象)

Connection(数据库连接对象)作用:

  • 获取执行SQL的对象–获得Statement
  • 管理事务

1、获得执行的SQL

  • 普通执行SQL的对象-- Statement createStatement()
  • 预编译SQL的执行对象,防止SQL注入-- PreparedStatement preparedStatement(sql)
  • 执行存储过程的对象 – CallableStatement prepareCall(sql)

2、管理事务

  1. mysql中的事务管理–默认提交事务
    开启事务:begin;/start transaction
    提交事务:commit
    回滚事务:rollback
  2. JDBC中的事务管理–Connection接口中定义了3个对应的方法
    开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务
    提交事务:commit()
    回滚事务:rollback()
package com.lz;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBC_Connection {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获得数据库连接
        String url="jdbc:mysql://localhost:3306/java";
        String username="root";
        String password="123456";
        Connection conn= DriverManager.getConnection(url,username,password);
        String sql1="update user set username='yjr' where id=1";    //定义两个sql语句
        String sql2="update user set username='zzz' where id=3";
        //获得执行sql的Statement的对象
        Statement statement= conn.createStatement();
        try {
            //开启事务
            conn.setAutoCommit(false);
            System.out.println(statement.executeUpdate(sql1));//执行两个sql语句
            //设置一个异常
            int i=1/0;
            System.out.println(statement.executeUpdate(sql2));

            //提交事务
            conn.commit();
        } catch (Exception e) {
            //回滚事务
            conn.rollback();
            throw new RuntimeException(e);
        }
        //释放资源
        statement.close();conn.close();
    }
}

三、Statement

Statement作用:执行SQL语句
执行SQL语句

int executeUpdate(sql)  //执行DML、DDL语句
//返回值:(1)DML语句影响的行数(依据返回值的结果判断是否操作成功) (2)DDL语句操作后,执行成功可能也返回0(当只要不出异常就表示操作成功)
ResultSet executeQuery(sql) //执行DQL语句
//返回值:ResultSet结果集对象

四、ResultSet(结果集对象)

ResultSet(结果集对象)作用:封装了DQL查询语句的结果

ResultSet executeQuery(sql) //执行DQL语句,返回ResultSet对象

获取查询的结果

boolean next()(1)将光标从当前位置向前移动一行 (2)判断当前行是否为有效行
/*
	返回值: true--有效行,当前行有数据
			false--无效行,当前行没有数据
*/
xxx getXxx(参数):获取数据
/*
	Xxx:数据类型; 如:int getInt(参数);String getString(参数)
	参数:int--列的编号,从1开始
		  String-- 列的名称
*/
//示例:
   @Test
    public void test() throws SQLException, ClassNotFoundException {
        Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
        // 定义url、数据库用户名、数据库的密码
        String url="jdbc:mysql:///java?useSSL=false";
        String username="root";
        String password="123456";
        Connection conn= DriverManager.getConnection(url,username,password); //获取数据库连接
       String sql="select * from user";
       //创建执行sql的Statement对象
        Statement stm= conn.createStatement();;
        //执行sql语句,返回一个ResultSet结果集对象
        ResultSet rs=stm.executeQuery(sql);
        while (rs.next()){
//            //通过下标的方式:获得resultset集合中的数据
//            int id=rs.getInt(1);
//            String name=rs.getString(2);
//            String pass=rs.getString(3);
            //通过表中的字段属性来获取resultset中的数据
            int id=rs.getInt("id");
            String name= rs.getString("username");
            String pass=rs.getString("password");
            System.out.println(id + " " + name + " " + pass);
        }
        //释放资源
        stm.close();
        conn.close();
    }

四、PreparedStatement

PreparedStatement原理:

  • 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译
  • 执行的时候就不用在进行这些步骤,速度很快
  • 如果mysql模板一样,则只需进行一次检查,编译
SQL注入:是通过操作输入来修改事先定义好的SQL语句,用以达到执行代码对服务器进行攻击的方法
        String username="yjr";
        String password="' or '1 = 1";
        String sql="select * from user where username='"+username+"' and password='"+password+"'"; //定义sql语句
        //最终执行的sql语句(有sql注入)
        //select * from user where username='yjr' and password='' or '1 = 1'

PreparedStatement作用:预编译SQL语句并执行;预防SQL注入的问题(将敏感字符进行转义)

  1. 获取PreparedStatement对象
//SQL语句中的参数值,使用?占位符代替
String sql="select * from user where username=? and password=?";
//通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt=conn.PrepareStatement(sql);

 2.设置参数值

PreparedStatement对象:setXxx(参数1,参数2):给?赋值
Xxx:数据类型;  如setInt(参数1,参数2)
参数:
参数1:?的位置编号,从1开始
参数2:?的值
3.执行SQL

executeUpdate();//此时这两种方法不需要再传递sql
executeQuery();  

4.示例

package com.lz;

import org.junit.Test;
import java.sql.*;
public class JDBC_PreparedStatement {
    /**
     *解决SQL注入的问题--PreparedStatement
     */
    @Test
    public void testLogin() throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
        // 定义url、数据库用户名、数据库的密码
        String url="jdbc:mysql:///java?useSSL=false";
        String username1="root";
        String password1="123456";
        Connection conn= DriverManager.getConnection(url,username1,password1); //获取数据库连接
        String username="yjr";
        String password="123";//'or' 1' = '1
        String sql="select * from user where username=? and password=?";
        PreparedStatement pstmt= conn.prepareStatement(sql);
        pstmt.setString(1,username);//设置参数=》?---这里解决了sql注入的问题,pstmt.setXxx()在设置参数时,进行了转义,就没有将正常中的单引号保留
        pstmt.setString(2,password);
        System.out.println(sql);
        ResultSet rs=pstmt.executeQuery();//直接调用方法,不传递参数并返回结果集
        if (rs.next()){
            System.out.println("用户登录成功!");
        }
        else {
            System.out.println("登录失败!");
        }
        //释放资源
        conn.close();
        rs.close();
        pstmt.close();
    }

    /**
     *SQL注入问题
     */
   @Test
    public void testLogin_inject() throws SQLException, ClassNotFoundException {
       Class.forName("com.mysql.cj.jdbc.Driver"); //注册驱动
       // 定义url、数据库用户名、数据库的密码
       String url="jdbc:mysql:///java?useSSL=false";
       String username1="root";
       String password1="123456";
       Connection conn= DriverManager.getConnection(url,username1,password1); //获取数据库连接
       String username="yjr";
       String password="'or '1'='1";//sql注入
       String sql="select * from user where username='"+username+"' and password='"+password+"'";
       System.out.println(sql);//select * from user where username='yjr' and password=''or '1'='1'
       Statement stmt= conn.createStatement();
       ResultSet rs=stmt.executeQuery(sql);
       if (rs.next()){
           System.out.println("用户登录成功!");
       }
       else {
           System.out.println("登录失败!");
       }
       //释放资源
       conn.close();
       rs.close();
       stmt.close();
 }
}

五、数据库连接池

  1. 数据库连接池
    数据库连接池是个容器,负责分配、管理数据库连接
    它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个新的是数据库连接
    释放空间的时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
    好处:资源重用、提升系统的响应速度、避免数据库连接遗漏

JDBC-API详解和数据库连接池使用_第3张图片
2. 数据库连接池的实现
标准接口:DataSource(获取连接)

Connection getConnection()//获取连接--不在使用DriverManager。getConnection()方法获取

常见的数据库连接池:DBCP、C3P0、Druid
Druid(德鲁伊):是阿里巴巴开源的数据库连接池的项目;功能强大,性能优秀,是java语言最好的数据库连接池之一。
3. 数据库连接池的使用步骤
导入响应的Maven依赖、定义配置文件、加载配置文件、获取数据库连接对象、获取连接
4. 使用

   <dependency>
      <groupId>com.alibabagroupId>
      <artifactId>druidartifactId>
      <version>1.2.3version>
    dependency>
package com.lz.druid;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;

public class Demo_Druid {
    public static void main(String[] args) throws Exception {
        //1.导入Maven依赖
        //2.定义配置文件
        //3.加载配置文件
        Properties prop=new Properties();
        prop.load(new FileInputStream("src/main/java/com/lz/druid.properties"));

        //4.获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //5.获取数据库连接对象
        Connection connection= dataSource.getConnection();
        System.out.println(connection);
        System.out.println(System.getProperty("user.dir"));//当前工程的路径
    }
}

你可能感兴趣的:(数据库,mysql,java)