MySQL(六) JDBC和数据库连接池

JDBC

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。

基础测试代码

  • 步骤:

    • 加载驱动
    • 链接数据库DriverManager
    • 获得执行sql的对象 statement
    • 获得返回的结果集
    • 释放链接
public class demo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动

        Class<?> aClass = Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动


        //2.用户信息url   useUnicode=true支持中文编码    characterEncoding=utf8设定中文字符库为utf-8   useSSL=ture使用安全链接
        String url= "jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&useUnicode=true&characterEncoding=utf8";
        String username="root";
        String password="123456";
        //3.连接成功,返回数据库对象   Connection代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);

        //4.执行SQL对象
        Statement statement = connection.createStatement();

        //5.执行SQL的对象 去 执行SQL 可能存在结果,查看和返回
        String sql="SELECT * FROM users";
        ResultSet resultSet = statement.executeQuery(sql);//返回的结果集,结果集中封装了全部查询出的结果
        while (resultSet.next()){
            System.out.println("id="+ resultSet.getObject("id"));
            System.out.println("id="+ resultSet.getObject("NAME"));
            System.out.println("id="+ resultSet.getObject("PASSWORD"));
            System.out.println("id="+ resultSet.getObject("email"));
            System.out.println("id="+ resultSet.getObject("birthday"));
        }

        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

  • DriverManager
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forName("com.mysql.jdbc.Driver");
  • url
String url = "jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&useUnicode=true&characterEncoding=utf8";
//mysql--3306
// 协议://主机地址:端口号/数据库名?参数1&参数2...
//oracle--1521
//jdbc:oracle:thin:@localhost:1521:sid
  • Connection
//链接成功 数据库对象 connection代表数据库
Connection connection = DriverManager.getConnection(url,username,password);
connection.rollback();  //事务滚回
connection.commit(); //事务提交
connection.setAutoCommit(); //数据库自动提交
  • Statement
        statement.executeQuery();//查询操作 返回结果集ResultSet
        statement.execute();//可以执行任何sql
        statement.executeUpdate();//更新 插入 删除都是用这个,返回受影响的行数
  • ResultSet
//不知道类型就用Object
resultSet.getObject();
//知道类型可以直接使用对应类型获取
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDouble();
resultSet.next();//移动到下一行数据
resultSet.beforeFirst();//移动到最前
resultSet.afterLast();//移动到最后
resultSet.previous();//移动到前一行
resultSet.absolute(i);//移动到第i行

statement对象

工具类
//db.properties存储信息降低耦合
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&useUnicode=true&characterEncoding=utf8
username=root
password=123456

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static  String driver=null;
    private static  String url=null;
    private static  String username=null;
    private static  String password=null;
    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");

            Properties properties=new Properties();
            assert in != null;
            properties.load(in);
            driver=properties.getProperty("driver");
            url=properties.getProperty("url");
            username=properties.getProperty("username");
            password=properties.getProperty("password");
            //驱动只用加载一次
            Class.forName(driver);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }
    //施放资源
    public  static void release(Connection connection, Statement statement, ResultSet resultSet) throws Exception {
        if (resultSet!=null){
            resultSet.close();
        }
        if (statement!=null){
            statement.close();
        }
        if (connection!=null){
            connection.close();
        }
    }
}

操作
import utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class Test2 {
    public static void main(String[] args) throws Exception {
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            connection= JdbcUtils.getConnection();
            statement=connection.createStatement();
            String sql="insert into users(id,name,password,email,birthday)" +
                    "values(100,'tzt','123456','123456@qq.com','1998-08-08');";
            int i=statement.executeUpdate(sql);
            if (i>0){
                System.out.println("插入成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}

SQL注入问题

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

sql存在漏洞,会被攻击导致数据泄露
比如登录业务中,需要查询账号密码所对应的用户(比对),可能用到如下sql语句:

select * from users where name='name' and password ='password'

其中name和password两个变量都是用户所传入的数据
如果用户构造合适的输入,比如:

String name=" ' or  1=1 -- ";
String password ="12412r1";//password在此例中的值不重要

那么如上sql语句拼接成了:

select * from users where name='  ' or  1=1 -- password ='12412r1'

就可以匹配到表中所有用户的信息

PreparedStatement对象

PreparedStatement:可以防止SQL注入且效率更高

import utils.JdbcUtils;

import java.sql.*;

public class Test2 {
    public static void main(String[] args) throws Exception {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection= JdbcUtils.getConnection();
            //?占位符
            String sql="insert into users(id,name,password,email,birthday)" +
                    "values(?,?,?,?,?);";
            //和Statement的区别!!!!!!!!!
            statement=connection.prepareStatement(sql);
            //手动给参数赋值
            statement.setInt(1,99);
            statement.setString(2,"hhh");
            statement.setString(3,"12312313");
            statement.setString(4,"15612318@qq.com");
            statement.setDate(5,new java.sql.Date(new Date(1231).getTime()));  //把util下的时间date转换成sql下的date
            //执行
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("插入成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection,statement,resultSet);
        }
    }
}

IDEA连接数据库(略)

JDBC操作事务

数据库连接池

数据库链接–执行完毕–施放十分消耗资源
池化技术:准备一些预先的资源,过来就链接预先准备好的

若常用连接数10个
最小连接数:10个即可
最大连接数:15 业务最高承载上限,超过此值则排队等待
等待超时:等待时间超过一定值直接失败

编写连接池:实现DataSource接口

开源数据源实现

DBCP
C3P0
Druid:阿里巴巴

使用了数据库连接池之后,我们在项目开发中就不需要编写链接数据库的代码了!

DBCP

需要导入的包:
commons-dbcp-1.4
commons-pool-1.6

配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&useUnicode=true&characterEncoding=utf8
username=root
password=123456
工具类
package utils;

import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils_DBCP {
    private static DataSource dataSource=null;

    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties=new Properties();
            assert in != null;
            properties.load(in);

            //创建数据源 工厂模式→创建
            dataSource=BasicDataSourceFactory.createDataSource(properties);



        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws Exception {
        return dataSource.getConnection();
    }

    //施放资源
    public  static void release(Connection connection, Statement statement, ResultSet resultSet) throws Exception {
        if (resultSet != null) {
            resultSet.close();
        }
        if (statement != null) {
            statement.close();
        }
        if (connection != null) {
            connection.close();
        }

    }

}

测试
import utils.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

public class Test4 {
    public static void main(String[] args) throws Exception {
        Connection connection=null;
        PreparedStatement statement=null;
        ResultSet resultSet=null;
        try {
            connection= JdbcUtils_DBCP.getConnection();
            //?占位符
            String sql="insert into users(id,name,password,email,birthday)" +
                    "values(?,?,?,?,?);";
            //和Statement的区别!!!!!!!!!
            statement=connection.prepareStatement(sql);
            //手动给参数赋值
            statement.setInt(1,49);
            statement.setString(2,"few");
            statement.setString(3,"12312313");
            statement.setString(4,"15612318@qq.com");
            statement.setDate(5,new java.sql.Date(new Date(1231).getTime()));
            int i=statement.executeUpdate();
            if (i>0){
                System.out.println("插入成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JdbcUtils_DBCP.release(connection,statement,resultSet);
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值