复习JDBC

JDBC简介:

JDBC全称:Java Data Base Connectivity(Java数据库连接),它主要由接口组成。
导入两个包 java.sql;javax.sql;
java.sql.*; 是核心包里的
java.sql.*是jdbc2.0之前的东西
javax.sql.*; 是扩展包中的
javax.sql.*包括了jdbc3.0的特性

//excute [ˈeksɪkju:t] 执行; 完成

这里写图片描述

数据库的访问过程

  • 客户端与MySQL服务器建立连接
  • 客户端向MySQL服务器建立数据库请求
  • MySQL服务器处理客户端请求,并将结果返回给客户端
  • 客户端接受MySQL服务器的响应,并且按照自己的业务逻辑做响应处理
    释放相关资源
具体操作过程
  • 注册驱动
    Sun公司定义了JDBC的一些接口,用户要想操作数据库,需要先把数据库的驱动,也就是JDBC的实现类拿到程序里来,这个操作称为注册驱动。Sun公司定义了DriverManager类用于完成驱动程序的注册:
    DriverManager.registerDrive(new com.jdbc.mysql.Driver());
  • 驱动注册后就可以创建与数据库的连接了
    Connection connection=DriverManager.getConnection();
  • 获得连接后,就可以在此连接上创建一条SQL语句,并发送给数据库
    Statement st=connection.createStatement();
    ResultSet set=st.excute(“slelct * from user”)
Connection详解:
  • JDBC中的Connection用于代表数据库的连接(桥梁),Connection是数据库编程中最重要的一个对象,客户端与数据库所有交互都是通过Connection对象完成的,这个对象的常用方法:
    createStatement():创建向数据库发送sql的statement对象
    prepareStatement():创建向数据库发送预编译sql的PrepareStatement对象
    setAutoCommit(boolean autoCommit):设置事务是否自动提交
    commit():在连接上提交事务
    rollback():在此连接上回滚事务
Statement详解:
  • JDBC程序中的Statement对象用于向数据库发送SQL语句
    Statement对象常用方法:
    executeQuery(String sql):用于向数据库发送查询语句
    executeUpdate(String sql):用于向数据库发送insert、update或者delete语句
    excute(String sql):用于向数据库发送任意sql语句
ResultSet详解:
  • JDBC程序汇总的ResultSet用于代表SQL语句的执行结果。Result封装执行结果时,采用的类似于表格的方式。Result对象维护了一个指向表格数据行的游标,游标在第一行之前,调用Result.next()方法,可以使游标指向具体的数据行,进行调用方法获取该行的数据。
  • ResultSet对象提供的都是用于获取数据的get方法
    getObject() getString() getDate()等
释放资源:

JDBC程序运行完后,切记要释放程序在运行过程中创建的那些与数据库交互的对象,这些对象通常是ResultSet、Statement、Connection对象
Connection对象的使用原则是尽量晚创建,尽量早的释放
为了确保资源释放代码能够运行,资源释放代码也一定要放在finally语句中

数据库的CRUD操作:

DriverManager.registerDrive(new com.jdbc.mysql.Driver());
Connection connection=DriverManager.getConnection();
Statement st=connection.createStatement();

//create
String sql="delete from user where id=1";
int num=st.excuteUpdate(sql);
if(num>0){
    System.out.println("插入成功");

//update
String st=connection.createStatement();
String sql="update user set name="" where name=" " ";
int num=st.excuteUpdate(sql);
if(num>0){
    System.out.println("修改成功");
}

//delete
String st=connection.createStatement();
String sql="delete from user where id=1";
int num=st.excuteUpdate(sql);
if(num>0){
    System.out.println("删除成功");
}

//read
String st=connection.createStatement();
String sql="delete from user where id=1";
int num=st.excuteQuery(sql);
while(rs.next()){
    //根据获取列的数据类型,分别调用rs的相应方法
    //映射到java对象中
}

数据库注入问题:

我们的代码中,最终拼接而成的发给数据库执行的SQL语句是:

String sql = “select * from t_user where name =’”+ name +”’ and password = ‘”+ password +”’”;
如果用户在name中输入了haha or 1=1– 这样就发生了数据注入问题

  • 仔细分析一下,数据库注入成功的根本原因是,我们把sql语句中的参数(用户的输入)和sql命令拼接成了一个sql语句,因为一个sql语句中既可以有sql的命令又可以有参数,因此,用户的输入也可以被当做sql的语句来解析执行。
  • 那么,既然知道了sql注入成功的原因,我们就反其道而行之,不让用户输入的参数被当做sql命令解析,而是只把它当做普通字符串来解析。
  • 由此,java中引入了prepareStatement,利用preparestatement来防止sql注入的核心思想就是,不把用户的输入当做sql命令来解析和执行。
PreparedStatement
  • PreparedStatement继承自Statement,可以通过Connection的prepareStatement方法得到
  • prepareStatement很明显的将sql命令语句与参数分开处理,其执行过程是,首先在sql语句真正执行之前,先把sql命令送到数据库中进行预编译,生成相应 的数据库命令,然后在获取sql中的参数,然后真正执行该sql语句。
  • 这样一来,用户输入的参数,只被当做参数而非命令来解析,就可以避免数据库注入这样的问题发生。
  • 显然,这样一来,单次执行PreparedStatement需要与数据库通信两次,效率,比之于单词执行Statement要低。

使用JDBC进行批处理

  • 业务场景:当需要向数据库发送一批SQL语句执行时,应避免向数据库一条条的发送执行,而应采用JDBC的批处理机制,以提升执行效率。
  • 如何实现批处理:
方法一Statement.addBatch(sql)

executeBatch():执行批处理命令
clearBatch():清楚批处理命令

Connection connection=null;
Statement statement=null;
ResultSet resultset=null;
try{
    connection=JdbcUtil.getConnection();
    String sql1="insert into user(name,password,email,birthday)"
           values('kkk','123','abc@sina.com','1978-08-08');
    String sql2="update user set password='123456' where id=3";
    statement=connection.createStatement();
    //把SQL语句加入到批命令中
    statement.addBatch(sql1);
    statement.addBathc(sql2);
    //把SQL语句提交给MySQL
    statement.excuteBatch();
}finally{
    //释放资源
    JdbcUtil.free(connection,statement,resultset)   
}
  • 采用Statement.addBatch(sql)方式实现批处理
    优点:可以向数据库发送多条不同的SQl语句;
    缺点:SQL语句没有预编译(PreparedStatement),容易出现注入现象。
    同时向数据库发送多条语句相同但仅参数不同的SQL语句时,需要重复写上很多条SQL语句
方法二PreparedStatement.addBatch()

注意内存溢出问题

Connection connection = JdbcUtil.getConnection();
String sql = "insert into user(name,password,email,birthday) values(?,?,?,?)";
Statement statement = connection.prepareStatement(sql);
for(int i=0;i<50000;i++){
    statement .setString(1, "haha" + i);
    statement .setString(2, "haha" + i);
    statement .setString(3, "haha" + i + "@gamil.com");
    statement .setDate(4,new Date(1999, 9, 9));
statement .addBatch();
if(i%1000==0){
    statement .executeBatch();
    statement .clearBatch();
    }
}
statement .executeBatch();
  • 采用PreparedStatement.addBatch()实现批处理
    优点:对于sql语句,PreparedStatement在服务端的编译,优化次数要远小于Statement。
    缺点:只能应用在SQL语句相同,但参数不同的批处理中。因此此种形式的批处理经常用于在同一个表中批量插入数据,或批量更新表的数据。

  • 对于Statement对象,我们已经知道是封装SQL语句并发送给数据库执行的功能,但是实际开发中,这个功能我们更经常用的是Statement类的子类PreparedStatement类的对象来实现,而不是采用Statement对象。

  • Statement和PreparedStatement的关系与区别在于:
      ① PreparedStatement类是Statement类的子类,拥有更多强大的功能。
      ② PreparedStatement类可以防止SQL注入攻击的问题,后面会说到。
      ③ PreparedStatement会对SQL语句进行预编译,以减轻数据库服务器的压力,而Statement则无法做到。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值