Bootstrap

Java的JDBC编程

1、数据库的必备条件

*编程语言,如java、python、c++等

*数据库,如Oracle、MySQL、SQL server等

*数据库驱动包:不同的数据库,对应不同的编程语言提供了不同的数据库驱动包,如MySQL提供了java的驱动包mysql-connector-java,需要基于java的编程语言操作数据库,就需要有该驱动包。同样的需要基于java操作Oracle就需要有Oracle的数据库驱动包ojdbc。

2、Java的数据库编程:JDBC

JDBC,即java Database Connector-java,java数据库连接。是一种用于执行SQL语句的java API,它是java中的连接规范。这个API由java.sql.*,javax.sql.*包中的一些类和接口组成,它为java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问。

 3、JDBC的使用步骤

1、创建数据库连接

2、创建操作命令statement

3、使用操作命令来执行SQL

4、处理结果集statement

5、释放资源

4、示例

4.1、根据学生学号查询学生信息


import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class selectDemo {
    public static void main(String[] args) {
        //1、创建数据源
        DataSource dataSource = new MysqlDataSource();
        //2、用mysqlDataSource给我们提供的一些关于mysql的连接信息,设置相关属性
        //设置URL,也就是数据的连接字符串
        ((MysqlDataSource) dataSource).setURL("jdbc:mysql://localhost:3306/java_4?characterEncoding=utf8&useSSL=false");
        //设置用户名
        ((MysqlDataSource) dataSource).setUser("root");
        //设置密码
        ((MysqlDataSource) dataSource).setPassword("qwb251635..");
        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            //3、开始连接数据库
            connection = dataSource.getConnection();
            //让用户动态输入
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入学号:");
            String inputSn = sc.next();
            //开始构造sql语句
            String sql = "select * from student where sn='" + inputSn + "'";
            //5、获取一个sql的PrepareStatement对象
            statement = connection.prepareStatement(sql);
            //6、通过statement对象执行sql语句并返回结果
            resultSet = statement.executeQuery(sql);
            //7、遍历这个resultSet结果集,获取每一行记录的每一个字段
            if(resultSet.next()){
                //8、读取返回的数据,这里是按照返回的列去读
                //学生id
                int id=resultSet.getInt(1);//从1开始
                //学生学号
                String sn=resultSet.getString(2);
                //学生姓名
                String name=resultSet.getString(3);
                //学生邮箱
                String mail=resultSet.getString(4);
                //学生班级id
                String class_id=resultSet.getString(5);
                //打印结果
                System.out.println("id ="+id+", 学号 ="+sn+", 姓名="+name+", 邮箱="+mail+", 班级编号="+class_id);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        finally{
            //1、关闭结果集对象
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            //2、关闭sql预处理对象
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            //3、关闭连接对象
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

 

 注意:查询过程结束之后一定要关闭数据库连接,释放资源

确定与数据库交互的过程中使用到了那些资源

1、connection--连接对象

2、statement--执行并处理SQL的对象

3、resultSet--结果集对象

执行SQL之后,要关闭·这些对象(从后往前依次关闭),出现异常也要关闭,那整个数据库交互过程也就完成了。

4.2、数据库连接API

4.3.1、Connection接口实现类由数据库提供

DataSource提供连接池支持。连接池在初始化时将创建一定数量的数据库连接,这些连接可以重复使用的,没次使用完数据库连接,释放资源调用connection.close()方法都是将连接对象回收。

4.3.2、Statement对象

Statement主要是将SQL语句发送到数据库中,JDBC提供了三种Statement对象。

 主要常用的是PrepareStatement

*executeQuery()方法执行后返回单个结果集,通常用于select语句。

*executeUpdate()方法返回值是一个整数,指首影响变化的行数,通常用与update,insert,delete语句。

4.3.3、ResultSet对象

ResultSet对象它被称为结果集,它代表符合SQL语句条件的所有行,并且通过一套getXXX方法提供了对这些行中数据的访问。

ResultSet里的数据一行一行排列,每行由多个字段,并且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能操作当前的数据行。我们想要取得一条记录,就要使用ResultSet的next()方法,如果我们想要得到ResultSet里面的所有记录,就应该使用while循环。

4.3、代码优化解决sql注入问题


import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;

public class selectDemo1 {
    public static void main(String[] args) {
        //1.创建数据源
        DataSource dataSource = new MysqlDataSource();
        //2.用MysqlDataSource给我们提供的关于mysql一些连接信息,设置相关属性
        //设置URL,也就是数据库连接字符串
        ((MysqlDataSource) dataSource).setURL("jdbc:mysql://localhost:3306/java_2?characterEncoding=utf8&useSSL=false");
        //设置用户名
        ((MysqlDataSource) dataSource).setUser("root");
        //设置密码
        ((MysqlDataSource) dataSource).setPassword("qwb251635..");
        /*((MysqlDataSource)dataSource).setCharacterEncoding("utf8");
        ((MysqlDataSource)dataSource).setDatabaseName("java_2");
        ((MysqlDataSource)dataSource).setUseSSL(false);
         */

        Connection connection = null;
        PreparedStatement statement = null;
        ResultSet resultSet = null;
        try {
            //3、连接数据库
            connection = dataSource.getConnection();
            //4、让用户动态输入
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入要查询的学号:");
            String inputSn = sc.next();
            //5、开始构造sql语句
            String sql = "select * from student where sn=?";
            //6、获取一个处理SQL的prepareStatement对象
            statement=connection.prepareStatement(sql);
            //用真实值替换占位符
            statement.setString(1, inputSn);
            //7、通过statement对象执行sql语句并获取返回结果
            resultSet = statement.executeQuery();
            //遍历这个结果集,获取每一行记录的每一个字段
            if(resultSet.next()){
                //8、读取返回的数据
                //学生id
                int id=resultSet.getInt(1);
                //学生学号
                String sn=resultSet.getString(2);
                //学生姓名
                String name=resultSet.getString(3);
                //学生mail
                String mail=resultSet.getString(4);
                //学生班级号
                String class_id=resultSet.getString(5);
                //打印结果
                System.out.println("id ="+id+", 学号 ="+sn+", 姓名="+name+", 邮箱="+mail+", 班级编号="+class_id);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
        finally{
            //关闭结果集对象
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            //关闭SQL预处理对象
            if(statement!=null){
                try {
                    statement.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
            //关闭连接对象
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    throw new RuntimeException(e);
                }
            }
        }
    }
}

 4.4、解决代码冗余问题

 代码与需求不成正比,大部分都是在做一些数据连接和释放资源的操作,可以考虑将这些操作代码封装到一个工具类中,使用时调用即可。


import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class DBUtil {
    //定义要返回的对象
    private static DataSource dataSource;
    //关于数据源的配置项
    private static final String URL="jdbc:mysql://localhost:3306/java_4?characterEncoding=utf8&useSSL=false";
    private static final String USER="root";
    private static final String PassWord="qwb251635..";
    //在使用之前要初始化dataSource,写在static静态代码块中让类在加载JVM的时候就完成初始化操作
    static{
        //设置配置参数
        MysqlDataSource mysqlDataSource=new MysqlDataSource();
        mysqlDataSource.setURL(URL);
        mysqlDataSource.setUser(USER);
        mysqlDataSource.setPassword(PassWord);
        dataSource=mysqlDataSource;
    }
    //不允许外部创建这个类的实例,也就是不允许new这个对象
    private DBUtil(){
    };
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
    public static void close(ResultSet resultSet, Statement statement, Connection connection){
        if (resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

4.5、增加一条数据信息


import Utils.Text01.DBUtil;

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

public class insertDemo {
    public static void main(String[] args) {
        //定义数据库相关变量
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //获取用户输入
            Scanner sc=new Scanner(System.in);
            System.out.println("请输入学号:");
            int sn=sc.nextInt();
            System.out.println("请输入姓名:");
            String name=sc.next();
            System.out.println("请输入mail:");
            String qq_mail=sc.next();
            System.out.println("请输入班级id");
            int classes_id=sc.nextInt();
            //1、获取数据库连接
            connection= DBUtil.getConnection();
            //2、构造sql语句
            String sql="insert into student (sn,name,qq_mail,classes_id) values(?,?,?,?)";
            //3、获取预处理对象
            statement=connection.prepareStatement(sql);
            //4、把占位符替换成真实值
            statement.setInt(1,sn);
            statement.setString(2,name);
            statement.setString(3,qq_mail);
            statement.setInt(4,classes_id);
            //执行sql语句并获取结果
            int result = statement.executeUpdate();
            if(result>0){
                System.out.println("录入学生信息成功!!!");
            }else{
                System.out.println("录入学生信息失败!!!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            //释放资源
            DBUtil.close(null,statement,connection);
        }
    }
}

执行结果:

 4.6、根据id删除信息


import Utils.Text01.DBUtil;

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

public class DeleteDemo {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //获取用户输入
            Scanner sc=new Scanner(System.in);
            System.out.println("请输入学生编号:");
            int id=sc.nextInt();
            //连接数据库
            connection= DBUtil.getConnection();
            //构造sql语句
            String sql="delete from student where id=?";
            //获取预处理对象
            statement=connection.prepareStatement(sql);
            //替换占位符为真实数据
            statement.setInt(1,id);
            //执行sql语句并返回结果
            int result = statement.executeUpdate();
            if(result>0){
                System.out.println("删除学生信息成功!!!");
            }else{
                System.out.println("执行失败!!!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.close(null,statement,connection);
        }
    }
}

 4.7、更改学生信息表


import Utils.Text01.DBUtil;

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

public class UpdateDemo {
    public static void main(String[] args) {
        //定义数据库用到的资源变量
        Connection connection=null;
        PreparedStatement statement=null;
        try {
            //0.获取用户输入信息
            Scanner scanner=new Scanner(System.in);
            System.out.println("输入学生ID:");
            int id=scanner.nextInt();
            System.out.println("输入学号:");
            int sn=scanner.nextInt();
            System.out.println("输入姓名:");
            String name=scanner.next();
            System.out.println("输入邮箱:");
            String qq_mail=scanner.next();
            System.out.println("输入班级编号:");
            int classes_id=scanner.nextInt();
            //1.获取数据库连接
            connection= DBUtil.getConnection();
            System.out.println("++++++数据库连接成功++++++");
            //2.构建SQl语句
            String sql="update student set sn=?,name=?,qq_mail=?,classes_id=? where id=?";
            //3.获取预处理对象
            statement= connection.prepareStatement(sql);
            //4替换占位符为真实数据
            statement.setInt(1,sn);
            statement.setString(2,name);
            statement.setString(3,qq_mail);
            statement.setInt(4,classes_id);
            statement.setInt(5,id);
            //5.执行SQl,获取返回结果
            int result = statement.executeUpdate();
            if(result>0){
                System.out.println("修改信息成功!!");
            }else{
                System.out.println("执行失败!!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            DBUtil.close(null,statement,connection);
        }
    }
}

运行结果:

;