JDBC基础

JDBC

JDBC概念

通过java代码操作数据库,实现在java代码中对数据库进行增删改查。

JDBC相关的类

DriverManager(驱动管理者)

getConnection()方法获取连接对象

  • 第一个参数:连接的数据库名称

  • 第二个参数:数据库的用户名

  • 第三个参数:数据库的密码

Connection(连接对象)

  1. createStatement()方法创建语句对象
  2. 管理事务(ACID):原子性,一致性,隔离性,持久性
    • 开启事务 setAutoCommit(),方法中是个布尔类型的参数,false表示手动提交(开启事务)
    • 提交事务Commit()
    • 回滚事务rollback()一般用在catch处理异常的代码中,即异常时回滚数据。

Statement(语句对象)

  • executeUpdate(这个方法是操作数据库中数据的增删改)
  • executeQuery(操作数据库中的查询)

两个方法的参数都是一条sql语句,即字符串类型,executeUpdate返回值是int类型的,返回的内容是影响数据库表中数据的行数。executeQuery的返回值是一个ResultSet(结果集对象)。

ResultSet(结果集对象)

作用:封装了数据库响应回来的数据

  • next()可以理解为这个方法为一个指针,一开始指向的是表中第一行数据的上方(不是字段名,即字段名和第一行数据的中间位置),返回值是boolean类型,如果为true,则表示有数据,如果为false,则表示没有数据。
  • getXXX(String s)和next()一起使用,如果next()返回的是true,调用getXXX(String s)可以获得这一行的数据,里面的参数就传这一行你想要的数据的字段名类型,XXX就是对应的数据类型。如,我想查这一行信息中年龄的信息,getInt(“age”),返回值仍然是Int。

JDBC使用注意事项及步骤

1.导入jar包(JDBC的具体实现),连接哪个数据库就用哪个数据库的驱动jir包

2.获取连接 用DriverManager中getConnection方法

3.利用Connection中的createStatement创建语句对象

4.通过语句对象实现对数据库的增删改查,增删改返回值为int(影响行数),查询的返回值为ResultSet(结果集对象)

5.利用ResultSet中的next和getXXX方法解析结果集

6.释放资源 colse();先开后关

JDBC获取连接代码

public static void main(String[] args) throws Exception{
    //1.导入jar包
    //2.获取连接
    Connection con=DriverManager.getConnection
    ("jdbc:用的数据库,如mysql://连接数据库地址/数据库名称","数据库账号","数据库密码");

    //3.创建语句对象
    Statement stat = con.createStatement();
    
    //4.在控制台看到连接对象的结果
    System.out.println(con);

JDBC进行增删改操作(以增为例子,三种操作是一样的只有sql语句不一样)

public static void main(String[] args) throws Exception{
   //1.导入jar包
    //2.获取连接
    Connection con = DriverManager.getConnection("jdbc:如mysql://连接数据库地址/具体的哪个库","数据库账号","数据库密码");

    //3.利用连接对象获取语句对象
    Statement stat = con.createStatement();

    //4.定义一个sql语句为字符串类型
    String sql = "insert into 表名 values(值)";
    
    //5.语句对象进行增删改操作(增删改的方法名为executeUpdate),返回值为影响的行数
    int rs = stat.executeUpdate(sql);//传入的参数是上面定义的sql语句

    //6.在控制台打印影响的行数
    System.out.println("影响的行数为:"+rs);

    //7.释放资源
    stat.close();
    con.close();
}

JDBC进行查询操作

public static void main(String[] args) throws Exception{
   //1.导入jar包
    //2.获取连接
    Connection con = DriverManager.getConnection("jdbc:如mysql://连接数据库地址/具体的哪个库","数据库账号","数据库密码");

    //3.利用连接对象获取语句对象
    Statement stat = con.createStatement();

    //4.定义一个sql语句为字符串类型
    String sql = "select * from 表名";

    //5.语句对象进行查询操作(查询的方法名为executeQuery),返回值为一个结果集
    ResultSet rs = stat.executeQuery(sql);//传入的参数是上面定义的sql语句

    //6.解析结果集,while循环,如果指针下有数据就获取出来循环打印
    while (rs.next()){
        int id = rs.getInt("id");//比如这个表中第一列字段名为id的int类型的编号
        String username = rs.getString("username");//第二列字段名为username的字符串类型的用户名
        String password = rs.getString("password");//第三列字段名为password的字符串类型的密码
        //7.打印第一行的数据
        System.out.println(id+"/t"+username+"/t"+password);//如果表中有多行数据下一次进入循环,以此类推
    }
    
    //7.释放资源
    rs.close();
    stat.close();
    con.close();
}

注意事项

  • 要导入数据库驱动的jar包
  • sql语句不能有错误
  • 连接地址,账户,密码不能写错
  • 最后要关闭资源,先开后关

sql注入

在用户用网页登录时,利用特殊的sql格式来实现错误密码的登录,最终在java代码中正确的查询到了数据,导致登录成功。

如用户在用户名处写 ‘ ’ or 1 = 1 – ,就算输入密码,也能登录成功。

‘ ’ or 1 = 1 – 这条语句通过java代码,带到数据库中的显示就是select * from 表名 where loginname=‘ ’ or 1 = 1 --,–在mysql中代表注释的意思,后面的内容可以忽略不记,所以这条语句在mysql中是可以查询成功的,所以导致sql注入问题。

解决方案

PreparedStatement接口

1.为什么要使用PreparedStatement

通过继承接口可以知道,他的父接口是Statement(语句对象),既然父类解决不了sql注入问题,就要使用它的子类来解决sql注入。

2.PreparedStatement执行原理

sql语句会预先编译,在创建语句对象的时候提供了sql语句,而不是等到执行的时候才提供sql语句,执行效率会更高,sql语句代码所有要替换的参数使用占位符,占位符是问号(?)

3.PreparedStatement的优点

  • sql语句会预先编译,执行效率会更高。
  • 解决了sql注入的问题,更安全
  • sql语句代码的可读性更好,替换的参数变成了占位符

PreparedStatement中相关的方法

1.如何得到这个对象

通过连接对象创建预编译语句对象,创建的时候要提供sql语句,语句可以有占位符,可以没有,如果有占位符,后面要替换占位符为真实的值。

2.executeUpdate和executeQuery

预编译语句对象中也有这两个方法,但是在使用的时候不用提供sql语句,因为创建的时候提供了sql语句,最主要的是怎样替换占位符

3.怎样替换占位符

insert into student values(?,?,?),比如这条sql语句,预编译语句对象为ps,那么替换第一个值就是ps.setXXX(1,替换的内容),以此类推,替换的内容要以数据库中的表的数据结构一致

public static void main(String[] args) throws Exception{
   //1.导入jar包
    //2.获取连接
    Connection con = DriverManager.getConnection("jdbc:如mysql://连接数据库地址/具体的哪个库","数据库账号","数据库密码");

    //3.利用连接对象获取预编译语句对象
    PreparedStatement ps = con.prepareStatement("insert into student values(?,?,?)");//这里的问号就是占位符
    
    //4.替换占位符,如果第一个为ind,第二个为String,第三个为String
    ps.setInt(1,1);//表示为第一个占位符赋值1
    ps.setString(2,"zhangsan");
    ps.setString(3,"zhangsan123");
    
    //5.替换占位符后,告诉预编译对象你要进行的操作
    int rs = ps.executeUpdate();//这里是增加数据,所以是update
    
    //6.可以直接关闭资源,不看影响的行数
    ps.close();
    con.close();
}

事务

  • 开启事务

Connection对象中setAutoCommit(false)

  • 提交事务

Connection中commit()

  • 回滚事务

Connection中rollback();

public static void main(String[] args) throws Exception{
    //因为后面要释放资源,所以定义在外面
    Connection con = null;
    PreparedStatement ps = null;
    try{
        con = DriverManager.getConnection("jdbc:如mysql://连接数据库地址/具体的哪个库","数据库账号","数据库密码");
          //开启事务          
        con.setAutoCommit(false);
        //模拟转账操作
        ps = con.prepareStatement("update user set money = money-500 where name='zhangsan'");
        ps = con.prepareStatement("update user set money = money+500 where name='lisi'");
        ps.executeUpdate();
        //如果没有报错,提交事务
        con.commit();

    }catch (Exception e){
        //如果报错,回滚事务
        con.rollback();
        e.printStackTrace();
    }finally {
        //释放资源,进行非空的判断,如果不为空就关
        if(ps != null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (con != null){
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值