JDBC基础

JDBC

一、JDBC的步骤:

  1. 创建工程,导入相应数据库对应的jar包
  2. 注册驱动:Class.forName("com.mysql.jdbc.Driver");;
  3. 链接数据库:Connection conn=DriverManager.getConnection(url,userName,passWord);
  4. 定义SQL要执行的语句:String sqlStr="~~~~~~";
  5. 获取执行SQL语句的对象: Statement stm = conn.createStatement();
  6. 执行SQL语句:stm.executeUpdate(sqlStr);

二、JDBC的API详解

  1. DriverManager: 驱动管理类
    (1) 注册驱动
    (2) 获取数据库链接

  2. Connection: 数据库链接对象
    获取执行SQL的对象
     (1) 普通执行SQL的对象:Statement createStatement();
     (2) 预编译SQL中执行SQL的对象, 防止 SQL注入: PreparedStatement prepareStatement(sql);
     (3) 执行存储过程的对象:CallableStatement prepareCall(sql); 不常用。

    管理事务
    事务的例子:假如你欠小明500块钱,你需要向小明账户汇款还钱,这时候你通过SQL语句使得你的账号存款会少五百,按理来说,这时候小明也会执行SQL语句,他的账户存款会多500,但是由于有些原因,小明的SQL语句出错了,那么你的账户上的钱已经少了500,而小明账户却没有收到你的汇款。这样显然是不合理的,因此我们便有了事务,事务让你和小明的SQL操作绑定在一起提交,只有你们俩的SQL语句都成功执行,才能修改数据库。如果不成功那么就回滚事务。

    • MySQL事务管理

      事务名称关键字
      开启事务BEGIN;或者 START TRANSACTION
      提交事务COMMIT
      回滚事务ROLLBACN

      MySQL默认自动提交事务

    • JDBC事务管理: Connection接口中定义了3个对应的方法

      事务名称语法
      开启事务setAutoCommit(boolean autoCommit):true为自动提交事务,false 为手动提交事务,即为开启事务
      提交事务commit()
      回滚事务rollback()
  3. Statement 执行对象类
    Statement的作用: 执行SQL语句
    执行SQL语句有两类:

    • 执行DML和DDL的语句int executeUpdate(sql); 返回值:DML所影响的行的个数; DDL执行成功也有可能返回0。
    • 执行DQL语句ResultSet executeQuery((sql); 返回值:ResultSet结果对象。
  4. ResultSet 是查询的结果

    • 获取结构中的数据
      (1) boolean next(); 将光标从当前位置向下移动一行,判断当前行是否有效。光标的起始位置在字段定义的那一行。
      (2) xxx getXxx(参数);获取数据,xxx为数据类型。这个函数有两种重载方式。
      注意:第一种重载方式:xxx getXxx(int),这个int 传的是表的第几列,起始列为1;
         第二种重载方式:xxx getXxx(String),这个String就是列的字段名。
public class JDBCDemo {
    public static void main(String[] args) throws Exception {
        //注册驱动;
        try {
            Class.forName("com.mysql.jdbc.Driver");
        }catch (Exception e){
            e.printStackTrace();
            System.out.print("注册失败");
        }
        //获取链接,后面这个characterEncoding =ut-8要设置,不然IDEA修改不了mysql数据库中的中文数据
        String str="jdbc:mysql://127.0.0.1:3306/db1?useSSL=false&characterEncoding=utf-8";
        String userName="root";
        String password="123456";
        Connection con= DriverManager.getConnection(str,userName,password);

        //要执行的SQL语句
        String sql1= "update bankCount set money=money-500 where name = \"你\"";//执行你在还钱
        String sql2="update bankCount set money=money+500 where name = \"小明\""; //执行小明收钱
        String sql3="select *from bankCount;";
        //获取执行sql语句的对象
        Statement stm=con.createStatement();

        try {
            //开启事务
            con.setAutoCommit(false);
            //执行你还钱的SQL
            int row11s = stm.executeUpdate(sql1);
            System.out.println(row11s);
            //执行小明收到你还的钱
            int rows22 = stm.executeUpdate(sql2);
            System.out.println(rows22);
            ResultSet res= stm.executeQuery(sql3);
            con.commit();
            while (res.next()){
                String st=res.getString("name")+"   "+res.getInt("money");
                System.out.println(st);
            }
        }catch (Exception throwA){
            //进入到catch这个语句块就表明事务出现了异常。这时候就需要回滚
            //捕获到异常就会滚
            con.rollback();
            throwA.printStackTrace();
            System.out.println("捕获到异常");
        } finally {
            //释放资源
            stm.close();
            con.close();
        }
    }
}
  1. PreparedStatement 重点(预编译,解决SQL注入的问题的)
    好处:预编译SQL性能更高;且防止SQL注入,将敏感字符进行转义,如单引号。
    解释SQL“注入”:入利用sql语句的语法规则,投机取巧的向服务器发起攻击。例如
    有一个用户登录表,如图所示:在这里插入图片描述
    如果是Statement类对象执行SQL语句
          	/*注册和链接数据库操作省略*/
          
            //执行的SQL语句
    		String name="张三";
           //String pwd="zhangsan";
            String pwd="'or 'suibian'='suibian";;
            String sqlStr="select *from student where name='"+name+"'and password='"+pwd+"';";
            Statement stm=con.createStatement();
            ResultSet res= stm.executeQuery(sqlStr);
            if(res.next()){
            System.out.println("登录成功");
        }else {
            System.out.println("登录失败");
        }
    
    这种情况下,当pwd="zhangsan",这个毫无疑问地,张三这个用户可以正常登录,但是如果当"'or 'suibian'='suibian",这时候我们仍然可以登录,且可以得到所有的用户登录信息。为什么会发生这样的事情呢?我们可以打印出stm要执行的sqlStr的语句观察:
    在这里插入图片描述这时候我们可以看出:where 后的条件是先得出name='张三'and password=''的结果为假,然后再和'suibian'='suibian'进行或运算。最终的where条件是true,因此,这个就可以理解为SQL注入。
      为了解决SQL注入,PreparedStatement 继承 Statement类。其代码如下:
 //要执行的SQL语句
        String name="张三";
        String pwd="zhangsan";
        String sqlStr="select *from student where name=? and password=?";

        PreparedStatement stm = con.prepareStatement(sqlStr);
        stm.setString(1,name);  //给将用户和密码传入stm对象中,表的起始列从1开始。
        stm.setString(2,pwd);  

        ResultSet res= stm.executeQuery();//不需要传参数。

6. 数据库连接池
数据库连接池,和线程池类似。连接池里建立了很多connection,当用户来连接数据库时候,池中的connection会用户和数据库连接起来;当用户离开,connection在回到池中,等待下一个用户,这就好比如物品循环利用。
如果不适用连接池,那么每一个用户访问数据库是都要重新建立一个connenction对象,断开数据库又要销毁connection,这个开销是非常大的。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值