Java-JDBC的对象DriverManager,Connection,ResultSet,PreparedStatement,工具类:JDBCUTILS,JDBC控制事务

1. 概念

  • Java DataBase Connectivity Java 数据库连接 Java语言操作数据库
  • JDBC本质:其实是官方(sun)公司的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类 Person接口 Worker类 Person p=new Worker p.eat()

2.快速入门

2.1 步骤

* 导入驱动jar包
* 注册驱动
* 获取数据库连接对象 Connection
* 定义sql
* 注意:参数使用?作为占位符
* 获取执行sql语句的对象 Statement
* 执行sql 接受返回的结果
* 处理结果
* 释放资源

2.2 举例

package cn.itcast.jdbc;

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

//jdbc的快速入门
public class JdbcDemo1 {
    public static void main(String[] args) throws Exception {
        //1.导入驱动jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据的链接对象
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "123456");
        //4.定义sql语句
        String sql="UPDATE account set balance=500 WHERE id=1";
        //5.获取执行sql的对象 Statement
        Statement stmt= connection.createStatement();
        //6.执行sql
        int count=stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        connection.close();
    }
}

3 详解各个对象

3.1 DriverManager:驱动管理对象

注册驱动:告诉程序该使用哪一个数据库驱动jar

static void registerDriver(Driver driver):注册与给定的驱动程序 DriverManager
写代码使用:  Class.forName("com.mysql.jdbc.Driver");
通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块
    static{
        try{
            java.sql.DriverManger.registerDriver(new Driver());
        }catch(SQLException E){
            throw new RuntimeException("Can't register driver!");
        }
    }
    注意:mysql5之后的驱动jar包可以忽略注册驱动的步骤

获取数据库连接

  • 方法:static Connection getConnection(String url,String user,String password)
  • 参数:
    • url:指定连接的路径
      • 语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
      • 例子:jdbc:mysql://localhost:3306/db3
    • user:用户名
    • password:密码

3.2 Connection:数据库连接对象

获取执行sql的对象

  • Statement createStatement()
  • PreparedStatement preparedStatement(String sql)

管理事务

  • 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false。即开启事务
  • 提交事务:commit()

3.3 Statement:执行sql的对象

  1. 执行sql
    1. boolean excute(String sql):可以执行任意的sql语句
    2. int excuteUpdata(String sql):执行DDL语句(create,alter,drop),执行DML语句(insert,update,delete)
      • 返回值:影响的行数,可以通过这个影响的行数来判断语句是否执行成功,返回值大于0则执行成功,反之,失败
    3. ResultSet excuteQuery(String sql):执行DQL语句(select)

举例

package cn.itcast.jdbc;

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

public class JdbcDemo5 {
    public static void main(String[] args){
        Statement stmt=null;
        Connection connection=null;
        //1.导入驱动jar包
        //2.注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //4.定义sql语句
            String sql="CREATE TABLE studentone(id int,name varchar(20))";
            //3.获取数据的链接对象
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "123456");
            //5.获取执行sql的对象 Statement
            stmt= connection.createStatement();
            //6.执行sql
            int count=stmt.executeUpdate(sql);
            //7.处理结果
            System.out.println(count);
            if (count>0){
                System.out.println("添加成功");
            }else{
                System.out.println("添加失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //8.释放资源
            //避免空指针异常
            // stmt.close();
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

        }
    }
}

3.4 ResultSet:结果集对象

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

举例

//6.执行sql
resultSet =stmt.executeQuery(sql);
//7.处理结果
//游标下移一行
while(resultSet.next()){
    //获取数据
    int id=resultSet.getInt(1);
    String name=resultSet.getString("name");
    double balance =resultSet.getDouble(3);
    System.out.println(id+"-----"+name+"------"+balance);
}    

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

4.定义一种方法,查询emp表的数据将其封装成对象,然后装载集合,返回

4.1 定义emp类

package cn.itcast.domain;

import java.util.Date;

//封装Emp表的JavaBean
public class Emp {
    private int id;
    private String ename;
    private int job_id;
    private int mgr;
    private Date joindate;
    private double salary;
    private double bounds;
    private  int dept_id;

    public Emp(int id, String ename, int job_id, int mgr, Date joindate, double salary, double bounds, int dept_id) {
        this.id = id;
        this.ename = ename;
        this.job_id = job_id;
        this.mgr = mgr;
        this.joindate = joindate;
        this.salary = salary;
        this.bounds = bounds;
        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 getBounds() {
        return bounds;
    }

    public void setBounds(double bounds) {
        this.bounds = bounds;
    }

    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 +
                ", joindata=" + joindate +
                ", salary=" + salary +
                ", bounds=" + bounds +
                ", dept_id=" + dept_id +
                '}';
    }
}

4.2 定义方法 public List findAll(){}

package cn.itcast.jdbc;

import cn.itcast.domain.Emp;
import cn.itcast.utils.JDBCutils;

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

//定义一个方法,查询emp表的数据将其封装成对象,然后装载集合,返回
public class JdbcDemo9 {
public List findAll(){
Statement stmt=null;
Connection connection=null;
ResultSet resultSet=null;
List list=new ArrayList();
Emp emp=null;
//1.导入驱动jar包
//2.注册驱动
try {
// Class.forName("com.mysql.jdbc.Driver");
// //3.获取数据的链接对象
// connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "123456");
connection=JDBCutils.getConnection();
//4.定义sql语句
String sql="select * from emp";
//5.获取执行sql的对象 Statement
stmt= connection.createStatement();
//6.执行sql
resultSet =stmt.executeQuery(sql);
//7.处理结果
//游标下移一行
while(resultSet.next()){
//获取数据
System.out.println("----------1-----------");
int id=resultSet.getInt("id");
String ename=resultSet.getString("ename");
int job_id=resultSet.getInt("job_id");
int mgr=resultSet.getInt("mgr");
Date joindate=resultSet.getDate("joindate");
double salary=resultSet.getDouble("sarlary");
double bounds=resultSet.getDouble("bonus");
int dept_id=resultSet.getInt("dept_id");

            //创建emp对象
            emp=new Emp(id,ename,job_id,mgr,joindate,salary,bounds,dept_id);
            //装载集合
            list.add(emp);
            // System.out.println(list);
        }

    }catch (SQLException e) {
        e.printStackTrace();
    }finally {
        //8.释放资源
        //避免空指针异常
        //未使用jdbcutil工具类简化
        // stmt.close();
        // if (resultSet!=null){
        //     try {
        //         resultSet.close();
        //     } catch (SQLException e) {
        //         e.printStackTrace();
        //     }
        // }
        // if (connection!=null){
        //     try {
        //         connection.close();
        //     } catch (SQLException e) {
        //         e.printStackTrace();
        //     }
        // }
        JDBCutils.close(resultSet,stmt,connection);
    }
    return list;
}
public static void main(String[] args) {
    List<Emp> list=new JdbcDemo9().findAll();
    System.out.println(list);
}

}

4.3 实现方法 select * from emp

    public static void main(String[] args) {
        List<Emp> list=new JdbcDemo8().findAll();
        System.out.println(list);
    }
}

5.抽取JDBC工具类:JDBCUTILS

package cn.itcast.utils;

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

//jdbc工具类
public class JDBCutils {
    private static String url;
    private  static  String user;
    private  static String password;
    private static String driver;
    //文件的读取,只需读取一次就可的导这些值,使用静态代码块
    static {
        //读取资源文件,获取值
        //1.创建Properties集合类
        Properties properties=new Properties();
        //获取src路径下的文件的方式--->ClassLoader 类加载器
        ClassLoader classLoader=JDBCutils.class.getClassLoader();
        URL res=classLoader.getResource("jdbc.properties");
        String path=res.getPath();
        System.out.println(path);
        //加载文件
        try {
            properties.load(new FileReader("E:\\Idea Project\\yonghucase\\out\\production\\jdbc test\\jdbc.properties"));
            // properties.load(new FileReader(path));
            //获取属性赋值
            url=properties.getProperty("url");
            user=properties.getProperty("user");
            password=properties.getProperty("password");
            driver=properties.getProperty("driver");
            //注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException{
        return DriverManager.getConnection(url,user,password);
    }
    //释放资源
    public  static void close(Statement statement,Connection connection){
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public  static void close(ResultSet resultSet,Statement statement, Connection connection){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

5.1 目的:简化书写

  • 分析:
    1. 注册驱动也抽取
    2. 抽取一个方法获取连接对象
      • 需求:不想传递参数,还得保证工具类的通用性
      • 解决:配置文件
        jdbc.properties
        url=
        user=
        password=
    3. 抽取一个方法释放资源

5.2 练习:通过键盘录入用户名和密码,判断用户是否登录成功

package cn.itcast.jdbc;

import cn.itcast.domain.Emp;
import cn.itcast.utils.JDBCutils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;


public class JdbcDemo10 {
    public  static  void main(String[] args){
        //键盘录入,接受用户名和密码
        Scanner scanner=new Scanner(System.in);
        System.out.println("请输入用户名");
        String username=scanner.nextLine();
        System.out.println("请输入密码");
        String password=scanner.nextLine();
        //调用方法
        boolean flag=new JdbcDemo10().login(username,password);
        //判断结果,输出不同数据
        if(flag){
            System.out.println("登录成功");
        }else{
            System.out.println("登录失败");
        }
    }
    //登录方法
    public boolean login(String username,String password){
        if(username==null||password==null){
            return false;
        }
        Connection connection=null;
        Statement stmt=null;
        ResultSet resultSet=null;
        // //3.获取数据的链接对象
        try {
        connection = JDBCutils.getConnection();
            //定义sql
            String sql="select * from user where username='"+username+"' and password='"+password+"'";
            //获取执行sql的对象
            stmt=connection.createStatement();
            //执行查询
            resultSet=stmt.executeQuery(sql);
            return resultSet.next();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCutils.close(resultSet,stmt,connection);
        }
        //连接数据库判断是否成功
        return false;
    }
}

6.JDBC控制事务

6.1 事务

  • 一个包含多个步骤的业务操作。如果业务操作被事务管理,则多个步骤要么同时成功。要么同时失败

6.2 操作

  1. 开启事务
  2. 提交事务
  3. 回滚事务

6.3 使用Connection对象来管理事务

  • 开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false。即开启事务
  • 提交事务:commit()
  • 回滚事务:rollback()

6.4 实例

package cn.itcast.jdbc;

import cn.itcast.utils.JDBCutils;

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

public class JdbcDemo12 {
    public static void main(String[] args){
        Connection connection=null;
        PreparedStatement preparedStatement1=null;
        PreparedStatement preparedStatement2=null;
        ResultSet resultSet=null;
        //获取连接
        try {
            connection= JDBCutils.getConnection();
            String sql1="update account set balance=balance-? where id=?";
            String sql2="update account set balance=balance+? where id=?";
        preparedStatement1=connection.prepareStatement(sql1);
        preparedStatement2=connection.prepareStatement(sql2);

        //设置参数
            preparedStatement1.setDouble(1,500);
            preparedStatement1.setInt(2,1);

            preparedStatement2.setDouble(1,500);
            preparedStatement2.setInt(2,1);

            preparedStatement1.executeUpdate();
            preparedStatement2.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCutils.close(preparedStatement1,connection);
            JDBCutils.close(preparedStatement2,connection);
        }
    }
}
posted @ 2020-06-02 22:25  东血  阅读(244)  评论(0编辑  收藏  举报

载入天数...载入时分秒...