JDBC学习笔记

JDBC学习

1. JDBC

  • java DataBase Connectivity Java数据库连接
  • 使用java语言操作数据库

1.1 JDBC的本质

  • 一套操作所有关系型数据库的规则,即接口,各个数据库厂商写出不同的jar包去调用这套接口,真正执行的代码是驱动jar包中的实现类

  • 图解

在这里插入图片描述

1.2 java连接数据库

  • 步骤:
    1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
    1.复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下
    2.右键–>Add As Library
    2. 注册驱动
    3. 获取数据库连接对象 Connection
    4. 定义sql
    5. 获取执行sql语句的对象 Statement
    6. 执行sql,接受返回结果
    7. 处理结果
    8. 释放资源
代码示例
package codes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

import static java.lang.Class.forName;

public class Demo1 {
    public static void main(String[] args) throws Exception {

        /*
            mysql 5 之后的jar包可以省略不写  注册驱动这行代码
            E:\JavaWebCodes\javaweb_day05\day05_jdbc\libs\mysql-connector-java-5.1.37-bin.jar!\
            META-INF\services\
            java.sql.Driver

            这个配置文件里面写了
        */


        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");

    /*
        Driver 源码,类加载进来时自动执行,且执行一次

        实际执行对象未 DriverManager

        static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
     */


    //获取数据库连接对象
        Connection cont = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "root");

    //    定义1条sql语句

        String sql="update account set balance=500 where id=1";

    //    获取执行sql的语句的对象

        Statement stat = cont.createStatement();
    //    执行sql语句
        int result = stat.executeUpdate(sql);

        System.out.println(result);

    //    关闭资源

        stat.close();
        cont.close();

    }
}

1.3 各个对象的详细解释

  1. DriverManager:驱动管理对象
    * 功能:
    1. 注册驱动:告诉程序该使用哪一个数据库驱动jar
    static void registerDriver(Driver driver) :注册与给定的驱动程序 DriverManager 。
    写代码使用: Class.forName(“com.mysql.jdbc.Driver”);
    过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块**
    static {
    try {
    java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
    throw new RuntimeException(“Can’t register driver!”);
    }
    }**

    		注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。
    	2. 获取数据库连接:
    		* 方法:static Connection getConnection(String url, String user, String password) 
    		* 参数:
    			* url:指定连接的路径
    				* 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
    				* 例子:jdbc:mysql://localhost:3306/db3
    				* 细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称
    			* user:用户名
    			* password:密码 
    
    1. Connection:数据库连接对象
      1. 功能:
        1. 获取执行sql 的对象
          • Statement createStatement()
          • PreparedStatement prepareStatement(String sql)
        2. 管理事务:
          • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
          • 提交事务:commit()
          • 回滚事务:rollback()
    2. Statement:执行sql的对象
      1. 执行sql
        1. boolean execute(String sql) :可以执行任意的sql 了解
        2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
          • 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
        3. ResultSet executeQuery(String sql) :执行DQL(select)语句
      2. 练习:
        1. account表 添加一条记录
        2. account表 修改记录
        3. account表 删除一条记录

1.4 练习的规范示例

  • 插入操作
package codes;
/*
       执行sql的插入语句
        insert into account values(null,"王五","700");
 */

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBC_insert {
    public static void main(String[] args) {

        Connection cont=null;
        Statement stat=null;
        try {
            //    注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //    连接服务器对象
            cont = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
            //    获取statment对象

            stat = cont.createStatement();
            //   定义一条mysql语句

            String sql=" insert into account values(null,\"王五\",\"700\")";

            // 执行sql语句

            int count = stat.executeUpdate(sql);
            if(count>0){
                System.out.println("sql添加成功");
            }else{
                System.out.println("添加失败");
            }


        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            //  释放资源
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

        }

    }
}


  • 修改操作
package codes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
    执行一条update 的mysql语句

    update account set balance=800 where id=3;
 */
public class JDBC_update {
    public static void main(String[] args) {

        Connection cont=null;
        Statement stat=null;

        try {
            //  注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //  连接数据库对象
            cont = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
            // 获取执行sql的对象
            stat = cont.createStatement();
            //  定义一条修改语句
            String sql="update account set balance=800 where id=3";
            //  执行sql语句
            int count = stat.executeUpdate(sql);
            if(count>0){
                System.out.println("sql执行成功");
            }else{
                System.out.println("sql执行失败");
            }

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally{
            //  释放资源
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

        }

    }
}

  • 删除操作
package codes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
    执行一条删除的mysql语句
    delete from account where id=3;
 */
public class JDBC_delete {
    public static void main(String[] args) {
        Connection cont=null;
        Statement stat=null;
        try {
            //  注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //  连接数据库对象
            cont = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
            // 创建一个statment对象
            stat = cont.createStatement();
            //  定义一条删除的sql语句
            String sql="delete from account where id=3";
            //  执行sql语句
            int cnt = stat.executeUpdate(sql);
            if(cnt>0){
                System.out.println("sql执行成功");
            }else{
                System.out.println("sql执行失败");
            }

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

        if(cont!=null){
            try {
                cont.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

    }
}

  • DDL语句
package codes;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
 *  执行一条DDL语句,创建一个新的学生表stu5
 *  create table stu5(id int,name varchar(20));
 */
public class JDBC_DDL {
    public static void main(String[] args) {
        Connection cont=null;
        Statement stat=null;
        try {
            // 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 连接数据库对象
            cont = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
            // 执行mysql的对象
            stat = cont.createStatement();
            // 定义一条DDL语句
            String ddl="create table stu5(id int,name varchar(20))";
            // 执行sql语句
            int cnt = stat.executeUpdate(ddl);
            System.out.println(cnt);
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

1.5 结构集对象(封装DQL的查询结果)

  • ResultSet:结果集对象,封装查询结果

    • next():游标向下移动一行

      • 在这里插入图片描述
    • getXxx(参数)::获取数据,某一行的某一列(一个单元格)

      • Xxx:代表数据类型,如int getInt() ,String getString()
      • 参数
        • int:代表列的编号,从1开始,如getString(1)
        • String:代表列的名称,如getDouble(“balance”)
      • 注意:
        * 使用步骤:
        1. 游标向下移动一行
        2. 判断是否有数据
        3. 获取数据

        	   //循环判断游标是否是最后一行末尾。
                while(rs.next()){
                    //获取数据
                    //6.2 获取数据
                    int id = rs.getInt(1);
                    String name = rs.getString("name");
                    double balance = rs.getDouble(3);
        
                    System.out.println(id + "---" + name + "---" + balance);
                }
        
示例
package codes;

import java.sql.*;

public class JDBC_ResultSet {

    public static void main(String[] args) {

        Connection cont=null;
        Statement stat=null;
        ResultSet rs=null;
        try {
            // 加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 链接数据库
            cont = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");

            //创建执行sql语句的对象
            stat = cont.createStatement();

            // 定义一条sql语句(DQL)
            String sql="select *from account";

            rs = stat.executeQuery(sql);
            rs.next();
            // 获取id
            int id = rs.getInt(1);
            // 获取姓名
            String name=rs.getString("name");
            // 获取余额balance
            double balance = rs.getDouble("balance");

            System.out.println(id+"---"+name+"---"+balance);

        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            // 释放资源

            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

  • 效果图

在这里插入图片描述

在这里插入图片描述

示例:打印表中所有数据
package codes;

import java.sql.*;

public class JDBC_ResultSet_for {

    public static void main(String[] args) {

        Connection cont=null;
        Statement stat=null;
        ResultSet rs=null;
        try {
            // 加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 链接数据库
            cont = DriverManager.getConnection("jdbc:mysql:///db3", "root", "root");

            //创建执行sql语句的对象
            stat = cont.createStatement();

            // 定义一条sql语句(DQL)
            String sql="select *from account";

            rs = stat.executeQuery(sql);

            //循环判读释放存在下一行,如果存在,循环打印,不存在,终止
            while(rs.next()){

                // 获取id
                int id = rs.getInt(1);
                // 获取姓名
                String name=rs.getString("name");
                // 获取余额balance
                double balance = rs.getDouble("balance");

                System.out.println(id+"---"+name+"---"+balance);
            }


        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            // 释放资源

            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

  • 效果图

在这里插入图片描述

1.6 练习:将表中的记录转换成对象存储

  • 练习:
    * 定义一个方法,查询emp表的数据将其封装为对象,然后装载集合,返回。
    1. 定义Emp类
    2. 定义方法 public List getData(){}
    3. 实现方法 select * from emp;
  • 员工表

在这里插入图片描述

  • 创建员工类
package someclass;

/*
 *   员工类
 *   存放数据库中的员工记录
 */
import java.util.Date;

public class Emp {
    private int id;
    private String ename;
    private int job_id;
    private int mgr;
    private Date joindate;
    private double salary;
    private double bonus;
    private int dept_id;

    public Emp() {
    }

    public Emp(int id, String ename, int job_id, int mgr, Date joindate, double salary, double bonus, int dept_id) {
        this.id = id;
        this.ename = ename;
        this.job_id = job_id;
        this.mgr = mgr;
        this.joindate = joindate;
        this.salary = salary;
        this.bonus = bonus;
        this.dept_id = dept_id;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public int getJob_id() {
        return job_id;
    }

    public void setJob_id(int job_id) {
        this.job_id = job_id;
    }

    public int getMgr() {
        return mgr;
    }

    public void setMgr(int mgr) {
        this.mgr = mgr;
    }

    public Date getJoindate() {
        return joindate;
    }

    public void setJoindate(Date joindate) {
        this.joindate = joindate;
    }

    public double getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public double getBonus() {
        return bonus;
    }

    public void setBonus(double bonus) {
        this.bonus = bonus;
    }

    public int getDept_id() {
        return dept_id;
    }

    public void setDept_id(int dept_id) {
        this.dept_id = dept_id;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", ename='" + ename + '\'' +
                ", job_id=" + job_id +
                ", mgr=" + mgr +
                ", joindate=" + joindate +
                ", salary=" + salary +
                ", bonus=" + bonus +
                ", dept_id=" + dept_id +
                '}';
    }
}

  • 创建转换方法
package codes;

import someclass.Emp;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/*
*   将员工表中的记录转换成对象,存储起来
 */
public class JDBC_DQL_emp {

    public static void main(String[] args) {
        List<Emp> data = new JDBC_DQL_emp().getData();
        for (Emp emp : data) {
            System.out.println(emp);
        }


    }

    public static List<Emp> getData(){
        Connection cont=null;
        Statement stat=null;
        ResultSet rs=null;
        ArrayList<Emp> empLists = new ArrayList<>();
        try {
            // 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 连接数据库
            cont = DriverManager.getConnection("jdbc:mysql:///db3","root","root");
            // 创建sql执行对象
            stat = cont.createStatement();
            // 定义一个sql语句
            String sql="select *from emp";
            rs = stat.executeQuery(sql);

            Emp emp = new Emp();
            while(rs.next()){
                int id = rs.getInt("id");
                String ename = rs.getString("ename");
                int job_id = rs.getInt("job_id");
                int mgr = rs.getInt("mgr");
                Date joindate = rs.getDate("joindate");
                double salary = rs.getDouble("salary");
                double bonus = rs.getDouble("bonus");
                int dept_id = rs.getInt("dept_id");

                emp = new Emp();
                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                emp.setJoindate(joindate);
                emp.setSalary(salary);
                emp.setBonus(bonus);
                emp.setDept_id(dept_id);
                emp.setMgr(mgr);

                empLists.add(emp);

            }

            return empLists;
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(stat!=null){
                try {
                    stat.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if(cont!=null){
                try {
                    cont.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

        return empLists;
    }

}

  • 效果图

在这里插入图片描述

1.7 优化sql语句的操作

  • 写一个JDBC的工具类,来简化一些重复的操作
    • 注册驱动
    • 连接数据库
    • 释放资源
  • 配置文件:用于连接数据库,存储user,password,数据库名称
url=jdbc:mysql:///db3
user=root
password=root
driver=com.mysql.jdbc.Driver
  • 工具类
package JDBC_Utils;

import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

/*
**`连接数据库的一些工具类
*   1.注册取得
*   2.获取连接对象
*   3.释放资源
 */
public class JDBC_tools {



    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    /*
        创建一个静态代码块,在类加载的时候只执行一次
        加载配置文件
     */

    static{
        // 配置文件流
        Properties pro=new Properties();
        // 定义一个类加载器,
        ClassLoader cls = JDBC_tools.class.getClassLoader();
        // 获取文件的URL
        URL resource = cls.getResource("jdbc.properties");
        // URL的路径部分
        String path = resource.getPath();
        try {
            pro.load(new FileReader(path));
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");

            // 加载驱动

            Class.forName(driver);

        } catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static Connection getConnection() throws SQLException {

        return DriverManager.getConnection(url,user,password);
    }


    /**
     * 释放连接对象cont和执行sql对象stat
     * 适用于DML,DDL的情况
     * @param cont
     * @param stat
     */
    public static void closeSource(Connection cont, Statement stat){
        if(stat!=null){
            try {
                stat.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(cont!=null){
            try {
                cont.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
    /**
     * 释放连接对象cont和执行sql对象stat和结果集对象rs
     * 适用于DQL的情况
     * @param cont
     * @param stat
     * @param rs
     */
    public static void closeSource(Connection cont, Statement stat,ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stat!=null){
            try {
                stat.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if(cont!=null){
            try {
                cont.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

}

  • 测试类
package codes;

import JDBC_Utils.JDBC_tools;
import someclass.Emp;

import java.sql.*;
import java.util.ArrayList;
import java.util.List;

/*
 *   将员工表中的记录转换成对象,存储起来
 */
public class JDBC_DQL_emp_tools {

    public static void main(String[] args) {
        List<Emp> data = new JDBC_DQL_emp().getData();
        for (Emp emp : data) {
            System.out.println(emp);
        }


    }

    public static List<Emp> getData(){
        Connection cont=null;
        Statement stat=null;
        ResultSet rs=null;
        ArrayList<Emp> empLists = new ArrayList<>();
        try {

            //使用工具类的方法
            // 连接数据库
            cont = JDBC_tools.getConnection();
            // 创建sql执行对象
            stat = cont.createStatement();
            // 定义一个sql语句
            String sql="select *from emp";
            rs = stat.executeQuery(sql);

            Emp emp = new Emp();
            while(rs.next()){
                int id = rs.getInt("id");
                String ename = rs.getString("ename");
                int job_id = rs.getInt("job_id");
                int mgr = rs.getInt("mgr");
                Date joindate = rs.getDate("joindate");
                double salary = rs.getDouble("salary");
                double bonus = rs.getDouble("bonus");
                int dept_id = rs.getInt("dept_id");

                emp = new Emp();
                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                emp.setJoindate(joindate);
                emp.setSalary(salary);
                emp.setBonus(bonus);
                emp.setDept_id(dept_id);
                emp.setMgr(mgr);

                empLists.add(emp);

            }

            return empLists;
        } catch ( SQLException e) {
            e.printStackTrace();
        }finally {
            //使用工具类的方法
            JDBC_tools.closeSource(cont,stat,rs);
        }

        return empLists;
    }

}

  • 效果图

在这里插入图片描述

1.8 练习:数据库登录案例

  • 练习:
    • 需求:

      1. 通过键盘录入用户名和密码
      2. 判断用户是否登录成功
        • select * from user where username = “” and password = “”;
        • 如果这个sql有查询结果,则成功,反之,则失败
    • 步骤:

      1. 创建数据库表 user(在数据库db4创建)
      CREATE TABLE USER(
       	id INT PRIMARY KEY AUTO_INCREMENT,
      
        	username VARCHAR(32),
        	PASSWORD VARCHAR(32)
      	INSERT INTO USER VALUES(NULL,'zhangsan','123');
          INSERT INTO USER VALUES(NULL,'lisi','234');
        );
      
      1. 使用工具类,注意修改配置文件
      url=jdbc:mysql:///db4
      user=root
      password=root
      driver=com.mysql.jdbc.Driver
      
      1. java测试代码
      package codes;
      
      import JDBC_Utils.JDBC_tools;
      
      import java.sql.Connection;
      import java.sql.ResultSet;
      import java.sql.SQLException;
      import java.sql.Statement;
      import java.util.Scanner;
      
      public class JDBC_Login {
      
          public static void main(String[] args) {
              Scanner sc=new Scanner(System.in);
              System.out.println("请输入用户名:");
              String username=sc.nextLine();
              System.out.println("请输入密码:");
              String password=sc.nextLine();
      
              boolean result = new JDBC_Login().login(username, password);
      
              if(result){
                  System.out.println("登录成功");
              }else{
                  System.out.println("用户名或密码错误");
              }
          }
      
          public static boolean login(String username,String password){
      
              Connection cont=null;
              Statement stat=null;
              ResultSet rs=null;
              try {
                  // 使用工具类,实现驱动注册,连接数据库
                  cont = JDBC_tools.getConnection();
                  // 获取指向sql的对象
      
                  stat = cont.createStatement();
      
                  // 定义sql语句,用于查找用户输入的用户名和密码
                  String sql="select *from user where username='"+username +"' and password='"+ password+"'";
                  rs = stat.executeQuery(sql);
                  // 查询到了,为true,查询不到,为false
                  return rs.next();
              } catch (SQLException throwables) {
                  throwables.printStackTrace();
              }finally {
                  JDBC_tools.closeSource(cont,stat,rs);
              }
              return false;
          }
      }
      
      
      • 效果图

在这里插入图片描述

在这里插入图片描述

1.9 sql注入问题

    1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
  1. 输入用户随便,输入密码:a’ or ‘a’ = 'a
    2. sql:select * from user where username = ‘fhdsjkf’ and password = ‘a’ or ‘a’ = ‘a’

     2. 解决sql注入问题:使用PreparedStatement对象来解决
     3. 预编译的SQL:参数使用?作为占位符
     4. 步骤:
     	1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
     	2. 注册驱动
     	3. 获取数据库连接对象 Connection
     	4. 定义sql
     		* 注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
     	5. 获取执行sql语句的对象 PreparedStatement  Connection.prepareStatement(String sql) 
     	6. 给?赋值:
     		* 方法: setXxx(参数1,参数2)
     			* 参数1:?的位置编号 从1 开始
     			* 参数2:?的值
     	7. 执行sql,接受返回结果,不需要传递sql语句
     	8. 处理结果
     	9. 释放资源
     
     5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
     	1. 可以防止SQL注入
     	2. 效率更高
    
  • sql注入问题效果图

在这里插入图片描述

1.10 解决sql注入问题,提高安全性

package codes;

import JDBC_Utils.JDBC_tools;

import java.sql.*;
import java.util.Scanner;

public class JDBC_Login {

    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username=sc.nextLine();
        System.out.println("请输入密码:");
        String password=sc.nextLine();

        boolean result = new JDBC_Login().login2(username, password);

        if(result){
            System.out.println("登录成功");
        }else{
            System.out.println("用户名或密码错误");
        }
    }

    /**
     * 解决sql问题,使用prepare
     * @param username
     * @param password
     * @return
     */
    public static boolean login2(String username,String password){

        Connection cont=null;
        PreparedStatement pstat=null;
        ResultSet rs=null;
        try {
            // 使用工具类,实现驱动注册,连接数据库
            cont = JDBC_tools.getConnection();
            // 获取指向sql的对象

            // 使用 PreparedStatement对象来解决sql注入的问题
            // 设置一条预编译的sql语句,?为占位符,
            String sql="select *from user where username=? and password=?";
            pstat=cont.prepareStatement(sql);
            // 第一个问号占位符设置字符串数据
            pstat.setString(1,username);
            // 第二个问号占位符设置字符串数据
            pstat.setString(2,password);


            //不需要sql参数
            rs = pstat.executeQuery();
            // 查询到了,为true,查询不到,为false
            return rs.next();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            JDBC_tools.closeSource(cont,pstat,rs);
        }
        return false;
    }
}

  • 效果图

在这里插入图片描述

1.11 事务操作

  1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
  2. 操作:
    1. 开启事务
    2. 提交事务
    3. 回滚事务
  3. 使用Connection对象来管理事务
    • 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
      • 在执行sql之前开启事务
    • 提交事务:commit()
      • 当所有sql都执行完提交事务
    • 回滚事务:rollback()
      • 在catch中回滚事务
  4. 代码实现
package codes;

import JDBC_Utils.JDBC_tools;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
 * JDBC事务操作
 * 张三+500
 * 李四-500
 */
public class JDBC_things {
    public static void main(String[] args) {
        // 修改配置文件db3
        Connection cont=null;
        PreparedStatement pstat1=null;
        PreparedStatement pstat2=null;
        try {
            // 使用工具类
            cont = JDBC_tools.getConnection();
            // 开启事务
            cont.setAutoCommit(false);
            // 定义两条sql语句,实现转账
            String sq1="update account set balance=balance-? where id=?";
            String sq2="update account set balance=balance+? where id=?";

            // 使用PreparedStatement执行sql,防止注入
            pstat1 = cont.prepareStatement(sq1);
            pstat1.setDouble(1,500);
            pstat1.setInt(2,1);

            pstat2 = cont.prepareStatement(sq2);
            pstat2.setDouble(1,500);
            pstat2.setInt(2,2);
            // 执行sql
            pstat1.executeUpdate();

            // 人为制造异常
            //int num=3/0;
            pstat2.executeUpdate();

            // 提交事务
            cont.commit();
            // 抓一个大异常,什么异常发生了,都需要回滚
        } catch (Exception throwables) {
            // 发生异常,回滚事务
            if(cont!=null){
                try {
                    cont.rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            throwables.printStackTrace();
        }finally {
            // 需要释放pstat1 和 pstat2
            JDBC_tools.closeSource(cont,pstat1);
            JDBC_tools.closeSource(null,pstat2);
        }

    }
}

  • 发生异常的效果图

在这里插入图片描述

在这里插入图片描述

  • 无异常发生

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值