栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Druid数据库连接池的介绍及使用、Statement对象和PreparedStatement对象的区别

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Druid数据库连接池的介绍及使用、Statement对象和PreparedStatement对象的区别

Druid数据库连接池的介绍及使用、Statement对象和PreparedStatement对象的区别 面试题: Statement对象和PreparedStatement对象的区别:

1)执行sql效率区别
Statement对象:执行sql,每一次将sql都需要发送一次,相对于PreparedStatement对象效率低,不用它的原因
数据库的性能优化—>减少服务器的交互次数(和数据库的交互次数减少)
PreparedStatement对象:预编译对象: 执行的参数化的sql,直接先发送给数据库,数据库会进行校验(参数类型,以及参数的字段是哪一列),并且保存在预编译对象中,可以不断的重新赋值;执行sql效率高!
2)是否存在sql注入的区别
Statement对象:执行的sql语句,都是静态化sql,sql存在字符串拼接,就会导致可能出现sql注入,非常不安全!
举例:
select * from user where username = ‘“+变量名+”’ and password ‘“+值…+”’ ;

​ PreparedStatement预编译对象:每次是在自己内存中直接赋值对应的值,sql语句永远是占位符号?
​ select * from user where username = ? and password = ? ;
​ 不会造成sql注入问题,非常安全的!

Druid数据库连接池的介绍及使用
可以分配,释放,管理数据库连接对象,当前某个连接对象释放之后,会归还到连接池中,大大提高了JDBC操作数据库性能!
	弊端:维护成本高; (维护它druid的版本以及监控它的连接数量)
	好处:可以设置参数,将数据库连接池进行调优;
	
    每一个线程都会使用自己的连接对象!
    前某个连接对象释放之后,会归还到连接池中,等待下一次利用(大大提高了连接对象的使用率)

在连接池中:会初始化一些连接数量(提供了很多参数)
    initialSize:初始化数量
    maxActive:最大激活数量
    maxWait:最大等多等待时间(毫秒值)
    maxidle:最大空闲数量
    minidel:最小空闲数量
    ...
    ...
druid.properties文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/homework11
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
DruidJdbcUtils封装类
import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;


public class DruidJdbcUtils {
    //成员变量位置:提供ThreadLocal:模拟线程,每一个线程使用自己的Connection
    private static ThreadLocal threadLocal = new ThreadLocal<>();
    //声明一个DataSource类型的变量
    private static DataSource dataSource;

    //无参构造私有化:目的外界不能new对象了
    private DruidJdbcUtils(){}

    //静态代码块
    static {
        try {
            //创建属性集合列表
            Properties properties = new Properties();
            //直接读取连接池的配置文件
            InputStream inputStream = DruidJdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            //将字节输入流的内容加载属性列表中
            properties.load(inputStream);
            //DruidDataSourceFactroy工厂类获取数据源对象
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //封装一个功能:获取数据源
    public static DataSource getDataSource(){
        return  dataSource;
    }

    //封装一个功能:获取数据库的连接对象
    public static Connection getConnection(){
        //1)首先要从当前线程中获取连接对象
        try {
            Connection connection = threadLocal.get();
            //2)判断conn是空的
            if(connection==null){
                //当前线程中没有开始绑定连接对象
                //3)从数据源连接池获取连接对象
                connection = dataSource.getConnection() ;
                //4)将当前连接对象绑定给自己的线程中
                threadLocal.set(connection);
            }
            return connection ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    //封装释放资源
    public static void close(PreparedStatement preparedStatement, Connection connection){
        close(null,preparedStatement,connection);
    }
    public static void close(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(preparedStatement!=null){
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(connection!=null){
            try {
                connection.close();
                //需要将自己线程中的连接对象解绑
                threadLocal.remove();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    //测试连接是否成功
    public static void main(String[] args) {
        // DataSource dataSource = DruidJdbcUtils.getDataSource();
        //  System.out.println(dataSource);
        //获取连接对象
        Connection connection = DruidJdbcUtils.getConnection();
        System.out.println(connection);
    }
}
单元测试的介绍

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gPmKUiP4-1653231696745)(…/…/…/AppData/Roaming/Typora/typora-user-images/image-20220521170145941.png)]

使用PrepareStatement预编译对象执行sql语句(DML/DQL)
//添加员工数据
Connection connnection = JdbcUtils.getConnnection();
//sql---参数化的sql语句
//sql语句中的值不是写死的,是在执行sql执行之前,可以多次赋值
String sql = "insert into emploee(name,age,gender,address,salary) values(?,?,?,?,?)" ;
//通过连接对象获取预编译对象PreparedStatement
//Connection---->PreparedStatement prepareStatement(String sql) throws SQLException
//将参数化的sql发送给数据库,并且存储到PreparedStatement对象中
PreparedStatement ps = connnection.prepareStatement(sql);
//PreparedStatement预编译对象中,需要给 ?  (占位符号)进行赋值
//通用方法:void setXxx(int parameterIndex, Xxx x)  :给占位符号赋值,
//参数1:第几个占位符号(从1开始)
//参数2:实际参数
ps.setString(1,"亓桑") ;
ps.setInt(2,20);
ps.setString(3,"男");
ps.setString(4,"西安市") ;
ps.setDouble(5,10000.00) ;

//PreparedStatement预编译对象 :执行sql
//通用方法:int executeUpdate()  :DML语句
//ResultSet executeQuery()  :DQL语句
int count = ps.executeUpdate();
System.out.println("影响了"+count+"行");

//释放资源
JdbcUtils.close(ps,connnection);


//查询员工数据
Connection connnection = JdbcUtils.getConnnection();
//sql---参数化的sql语句
//sql语句中的值不是写死的,是在执行sql执行之前,可以多次赋值
String sql = "select * from emploee where id = ?" ;
//通过连接对象获取预编译对象PreparedStatement
//Connection---->PreparedStatement prepareStatement(String sql) throws SQLException
//将参数化的sql发送给数据库,并且存储到PreparedStatement对象中
PreparedStatement ps = connnection.prepareStatement(sql);

//给参数赋值
ps.setInt(1,7) ;

//执行查询
//ResultSet executeQuery()  :DQL语句
ResultSet rs = ps.executeQuery();
while (rs.next()){
    int id = rs.getInt("id");
    String name = rs.getString("name");
    int age = rs.getInt("age");
    String gender = rs.getString("gender");
    String address = rs.getString("address");
    double salary = rs.getDouble("salary");
    System.out.println(id+"t"+name+"t"+age+"t"+gender+"t"+address+"t"+salary);
}

//释放资源
JdbcUtils.close(ps,connnection);
使用Statement/PreparedStatement分别完成模拟登录功能 Statement模拟登录
import com.qf.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;


public class Statement_LoginTest {
    public static void main(String[] args) {
        //调用登录 操作
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;
        //提示并录入数据
        System.out.println("请您输入用户名:") ;
        String username = sc.nextLine() ;  //录入字符串的方法

        System.out.println("请您输入密码:") ;
        String password = sc.nextLine() ;

        boolean flag = isLogin(username,password) ;
        if(flag){
            System.out.println("恭喜您,登录成功!! ");
        }else{
            System.out.println("登录失败!");
        }
    }

    
    public static boolean isLogin(String username,String password){
        Connection conn = null ;
        Statement stmt = null ;
        ResultSet rs = null ;
        try {
            //获取数据库的链接对象
            conn = JdbcUtils.getConnnection() ;
            //准备好sql
            String sql = "select * from user where username = '"+username+"' and password = '"+password+"'" ;
            System.out.println(sql) ;
            //获取Statement对象
            stmt = conn.createStatement();

            //执行查询sS
            rs = stmt.executeQuery(sql);

            return  rs.next() ;
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            JdbcUtils.close(rs,stmt,conn);
        }
        return  false ;
    }
}
PreparedStatement模拟登录
package com.qf.statement_and_preparedstatement_04;

import com.qf.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;


public class PerparedStatement_LoginTest {

    public static void main(String[] args) {
        //创建键盘录入对象
        Scanner sc = new Scanner(System.in) ;

        //提示并录入数据
        System.out.println("请您输入用户名:") ;
        String username = sc.nextLine() ;
        System.out.println("请您输入密码:" );
        String password = sc.nextLine() ;
        boolean flag  = login(username,password) ;
        if(flag){
            System.out.println("恭喜您,登录成功!!");
        }else{
            System.out.println("对不起,登录失败!");
        }
    }

    
    public static boolean login(String username, String password) {

        try {
            //获取数据库的连接对象
            Connection conn = JdbcUtils.getConnnection();
            //准备sql----参数化的sql
            String sql = "select * from user where username = ? and password = ?" ;
            //获取预编译对象,并且发送sql到数据库
            PreparedStatement ps = conn.prepareStatement(sql) ;
            System.out.println(sql) ;
            //给参数赋值
            ps.setString(1,username) ;
            ps.setString(2,password);

            //执行查询
            ResultSet rs = ps.executeQuery();
            return rs.next() ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  false ;
    }
}

conn.prepareStatement(sql) ;
System.out.println(sql) ;
//给参数赋值
ps.setString(1,username) ;
ps.setString(2,password);

        //执行查询
        ResultSet rs = ps.executeQuery();
        return rs.next() ;
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return  false ;
}

}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/926452.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号