JDBC操作流程(Statement,PreparedStatement,Druid,Commons-dbutils)

本文详细介绍了如何使用Statement执行SQL语句,PreparedStatement的参数化查询优势,以及Druid数据库连接池的配置与操作。对比了PreparedStatement与Statement的安全性和性能提升。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Statement 操作流程

//1 导入并加载驱动
Class.forName("com.mysql.jdbc.Driver") ;
//8.0及以上数据库为  Class.forName("com.mysql.cj.jdbc.Driver");
//2 获取数据库的连接对象

Connnection connection = DriverManager.getConnection(
		"jdbc:mysql://localhost:3306/库名",
//如果mysql8.0以上则需要在库名后追加 ?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true 
    	"root",
    	"登录数据库的密码"
) ;
//3 准备sql语句
String sql = "select * from 表名" ;
//4 获取执行对象Statement
Statement statement = connection.createStatement() ;
//5 执行dql语句
ResultSet rs = statement.executeQuery(sql) ;
//6 返回执行语句后的所获取到的结果
while(rs.next()){
    //将返回到的结果的值赋给变量 并在控制台中输出。
       字段类型 变量名=   rs.getXXX("字段名称") ;
    //或是 字段类型 变量名 = rs.getXXX(列的索引值) ; //列的索引值1..开始
    //使用这个变量名
}

//7 释放资源
rs.close();
statement .close() ;
connection .close() ;

PreparedStatement 操作流程

其实操作流程具体与 Statement 流程大同小异

//1 导包并注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//2 获取数据库的连接对象
Connection connection = DriverManager.getConnection(
     "jdbc:mysql://localhost:3306/库名",
    "root",
    "登录mysql的密码"
) ;
//3 准备好参数化的sql语句 DML语句
String sql = "insert into 表名 values(?,?,?...)" ;
String sql2 = "update 表名 set 字段名称1 = ?,字段名称2 = ?,字段名称3 = ? where 字段名称 = ?" ;
String sql3 = "delete from 表名 where 字段名称 = ?" ;
//sql语句:参数化的DQL语句
String sql4 = "select * from 表名 " ;
String sql5 = "select * from 表名  where 字段名称 = ?" ;

//4 获取预编译对象,同时将sql发送给数据库
PreparedStatement ps  =   connection.prepareStatement(sql) ;
//5 通过预编译对象,参数赋值
ps.setXXX(占位符号的索引值,XXX类型的实际参数) ;
//6 执行DML语句
int count = ps.executeUpdate() ; 
//影响的行数 count
//要执行的DQL语句
ResultSet rs = ps.executeQuery() ;
while(rs.next()){
    //获取结果数据
    XXX 变量名  = rs.getXXX("列的名称,列的索引值") ;
}
//7 释放资源
rs.close();
ps.close();
connection.close() ;

Statement 与 PreparedStatement 的区别:

1. PreparedStatement可以写参数化查询,比Statement能获得更好的性能。
2. 对于PreparedStatement来说,数据库可以使用已经编译过及定义好的执行语句,这种预处理语句查询比普通的查询运行速度更快。
3. PreparedStatement可以阻止常见的SQL注入式攻击。
4. PreparedStatement可以写动态查询语句
5. Statement 执行的是静态sql语句,存在字符拼接,可能会出现sql注入,会导致数据库陷入不安全的处境。 PreparedStatement预编译对象:每次是在自己内存中直接赋值对应的值,sql语句永远是占位符号?     此种不会造成sql注入问题,会比较安全。

Druid 德鲁伊数据库连接池

druid 数据库连接池:
       可以分配,释放,管理数据库连接对象,当某个连接对象释放之后,会归还到连接池中,更有利于管理与操作数据库
       弊端:不易维护 (需要更新druid版本以及监控它的连接数量)
       好处:可以设置参数,将数据库连接池进行调优;

操作步骤:

//1 导包
//2 加入连接池的配置文件
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名
username=root
password=123456
initialSize=5    //初始化连接池数量
maxActive=10        //最大连接数量
maxWait=3000        //连接等待时间,超时自动断开
//3读取配置文件 
   InputStream inputStream =  当前类.class.getClassLoader().getResourceAsStream("xxx.properties") ;//xxx.properties 中为连接池配置文件,也可以在此设置连接池的配置
//4 创建属性集合列表
Properties prop = new Properties() ;
prop.load(inputStream) ;
//5获取数据源----DruidDataSourceFactory
DataSource ds = DruidDataSourceFactory.createDataSource( prop) ;
//DataSource替代了DriverManager: Connection getConnection() ;
//6获取连接对象
Connection conn = ds.getConnection() ;
//使用连接对象

Commons-dbutils 工具类库

DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的(关闭资源、加载驱动)。将jdbc的操作进行简单封装,操作数据库的代码更加简便高效。

使用步骤:

1 导入核心的jar包 commons-dbtils.jar

mysql驱动jar包

连接池--druid的jar包

junit单元测试:核心包junit.jar以及依赖包

2 有关commons-dbtils.jar 核心接口以及核心类有哪些

执行对象:操作数据库

org.apache.commons.dbutils.QueryRunner 里面封装就是PreparedStatement 两个通用的方法

query(xxx,ResultSetHandler rsh):针对dql语句来完成查询操作

update(xxx,xx):针对dml域操作:        insert into,update,delete from .... 核心接口:ResultSetHandler:针对结果集的处理

有很多实现类:

BeanListHandler:将查询的多条记录封装到list集合中

BeanHandler:将查询的结果其中某条记录封装到一个java实体类中

ScalarHandler:查询单行数据/查询总记录数        可以使用聚合函数:

        select count(id字段) from 表名 ; 

查询总记录数的返回值使用int 和long都可以

使用QueryRunner 查询数据库中表所有数据 :

@Override
    public List<Employee> findAll() throws SQLException {
        //使用Commons-dbutils 包 导入
        //创建数据库连接对象
        QueryRunner queryRunner = new QueryRunner((DataSource) DruidUtils.getDs());

        //准备sql语句
        String sql = "select * from employee";
        //执行通用方法
        //query(String sql,ResultSetHandler rsh)
        //参数1:sql语句
        //参数2:结果集的处理对象:接口
        //将所有记录封装到List<Employee>中
        //public BeanListHandler<T>(Class<T> type) :参数是存储当前类型的字节码文件对象

            List<Employee> list = queryRunner.query(sql,new BeanListHandler<Employee>(Employee.class));

        return list;
    }

使用PreparedStatement与Commons-dbutils查询与更新数据

@Override
    public Employee select(int id) throws SQLException {
        QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs());
        String sql = "select from employee where id = ?";
        //执行sql:将查询的这条记录封装到Employee类中
        // public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params)
        //参数1:sql语句
        //参数2:结果集的处理:BeanHandler对象    //有参构造 public BeanHandler<T>(Class<T> class)
        //参数3:给占位符号 赋值
        Employee emp = queryRunner.query(sql,new BeanHandler<Employee>(Employee.class),id);
        return emp;
    }

    @Override
    public void add(Employee employee) {
        QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs());
        String sql = "insert into employee(name,age,gender,address,salary) values(?,?,?,?,?)";
        //执行更新
        //通用的方法
        //update(String sql,Object...params)
        //参数1:sql
        //参数2:给占位符号赋值
        try {
            int count = queryRunner.update(sql,
                    employee.getName(),
                    employee.getAge(),
                    employee.getGender(),
                    employee.getAddress(),
                    employee.getSalary());
            System.out.println("影响了" +count+"行");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }

    @Override
    public void updateEmp(Employee employee) {
        QueryRunner queryRunner =new QueryRunner(DruidUtils.getDs());
        String sql = "update employee set name=?,age=?,gender=?,address=?,salary=?  where id=?";
        try {
            int count = queryRunner.update(sql,employee.getName()
            ,employee.getAge(),employee.getGender()
            ,employee.getAddress(),employee.getSalary()
            ,employee.getId());
            System.out.println("影响了" +count+"行");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }

    }

        

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值