JDBC总结应用

jdbc:java database Connectivity(java连接数据库)
maven导入依赖:

<dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
 </dependency>

一、使用步骤(固定六步)

1.注册驱动(作用:告诉java程序,即将要连接的是哪个品牌的数据库)

Class.forName("com.mysql.jdbc.Driver");

2.获取连接(表示JVM的进程和数据库之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭)

Connection connection = DriverManager.getConnection(url, username, password);

3.获取数据库操作对象(专门执行SQL语句的对象)

Statement st = connection.createStatement();

4.编写sql语句,并执行

String sql = "select * from smbms_bill where billCode='BILL2016_001'";
ResultSet resultSet = st.executeQuery(sql);
  • int executeUpdate(String sql)专门执行DML语句的(insert,delete,update):返回值表示影响的行数
  • ResultSet executeQuery(String sql)专门执行DQL(select)的语句,返回一个ResultSet类型的结果集

5.处理查询结果集(只有当第四步执行的是select语句时,才需要处理查询结果集)


while(resultSet.next()){
      System.out.println("id="+resultSet.getObject("id"));
      System.out.println("billCode="+resultSet.getString("billCode"));
      System.out.println("productName="+resultSet.getObject("productName"));
      System.out.println("---------------------------");
}

结果集图解:
在这里插入图片描述

6.关闭资源,一定要关,先开的最后关(使用完资源后,一定要关闭资源。java和数据库属于进程间的通信,开启之后一定要关闭)

  • 为了保证资源一定关闭,通常放在finally语句块中关闭
  • 并且要遵循从小到大依次关闭
  • 并且分别对其try…catch
resultSet.close();
st.close();
connection.close();

二、自己封装DbUtil工具类

package com.yl.Utils;
import java.sql.*;
public class DbUtil {
    public static final String URL = "jdbc:mysql://localhost:3306/yulu";//yulu为要连接的数据库名
    public static final String USER = "root";
    public static final String PASSWORD = "123456";
    private static Connection conn = null;
    static{
        try {
            //1.加载驱动程序
            Class.forName("com.mysql.jdbc.Driver");
            //2. 获得数据库连接
            conn = DriverManager.getConnection(URL, USER, PASSWORD);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection(){
        return conn;
    }
}

在其他程序中调用如下:

public class JdbcTest02 {
    public static void main(String[] args) throws SQLException {
        //1.注册驱动,获取连接(通过直接调用封装类方法来实现)
        Connection connection = DbUtil.getConnection();
        //2.获取预编译的对象,并传入sql
        String sql = "delete from user where id = ? ";//删除一行
        PreparedStatement ps = connection.prepareStatement(sql);
        //3.传参
        ps.setString(1,"001");
        //4.执行
        ps.executeUpdate();
        //5.关闭资源
        ps.close();
        connection.close();
    }
}

三、其他问题

1.SQL注入问题
  • 什么是sql注入:发送sql语句给DBMS,DBMS进行SQL编译。正好将用户提供的非法信息编译进去,导致原SQL语句的含义被扭曲了

  • 如何解决sql注入问题
    只要用户提供的信息不参与sql语句的编译过程,问题就解决了。
    (解决问题的关键)即使用户提供的信息中含有sql语句的关键字,但是没有参与编译,就不起作用。
    要想用户信息不参与sql语句的编译,那么就必须使用java.sql.PreparedStatement(这才是以后常用的)
    -PreparedStatement接口继承了java.sql.Statement
    -PreparedStatement是属于预编译的数据库操作对象
    -PreparedStatement原理是:预先对sql语句的框架进行编译,然后再给sql语句传“值”

  • 对比Statement和PreparedStatement
    Statement存在SQL注入问题,而PreparedStatement解决了SQL注入问题。
    Statement是编译一次,执行一次;而PreparedStatement是编译一次,可以执行N多次。PreparedStatement效率高一些。
    在mysql中,只要执行的语句完全一模一样,就不会重新编译,而只会直接执行。
    PreparedStatement会在编译阶段做类型的安全检查。

绝大部分情况下需要使用PreparedStatement,而只有极少数的情况下才使用Statement。

  • 什么情况下必须使用Statement?
    业务方便必须支持SQL注入的时候(即业务要求需要进行sql拼接) 比如:按升序或是降序排序,desc/asc就得使用sql注入
2.PreparedStatement解释

获取预编译的数据库操作对象:
PreparedStatement prepareStatement(String sql)


String sql = "select * from t_userlogin where userName= ? and passWord= ?";//sql语句的框子
PreparedStatement ps = conn.prepareStatement(sql);//程序执行到此处,会发送sql语句框子给DBMS,然后DBMS进行sql语句的编译
ps.setString(1,"zhangsan");//表示给第一个占位符传值为“zhangsan”
ps.setString(2,"123456");//表示给第一个占位符传值为“123456”
ps.executeQuery();//执行

注意:

1.sql语句的框子。其中一个?表示一个占位符,一个?将来接收一个“值”。注意:占位符?不能使用单引号括起来。
2. 给占位符?传值(第1个问号下标是1,第2个问号下标是2,JDBC中所有的下标从1开始)

四、JDBC事务

public class TransactionTest {
    @Test
    public void test() {
        Connection connection = null;
        try {
            //1.获取数据库连接
            connection = DbUtil.getConnection();
            //2.通知数据库开启事务,false为开启
            connection.setAutoCommit(false);
            //3.写SQL预编译
            String sql = "update account set money = money-100 where id='1'";
            connection.prepareStatement(sql).executeUpdate();

            //4.制造错误1/0
            int i = 1/0;//此处会发生异常

            String sql2 = "update account set money = money+100 where id='2'";
            connection.prepareStatement(sql2).executeUpdate();

            connection.commit();//如果执行到此处便表明以上两条SQL都成功了,就提交事务
        }catch (Exception e){
            //如果出现异常就回滚事务
            try {
                e.printStackTrace();
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally {
            try {
                connection.close();//关闭资源
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

数据库事务语句:

start transaction ;#开启事务

update account set money = money-100 where id='1';

update account set money = money+100 where id='2';

rollback ;#回滚事务

commit ;#提交事务
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值