Java DataBase Connectivity

关于JDBC

什么是JDBC?

Java DataBase Connectivity (Java语言连接数据库)

JDBC的本质是什么?

JDBC是SUN公司制定的一套接口(interface)
java.sql.*;(这个软件包下有很多接口。)

JDBC开发前的准备工作
JDBC开发前的准备工作,先从官网下载对应的驱动jar包,然后将其配置到环境变量classpath当中。
classpath=.;D:\JDBC\MySQL\mysql-connector-java-5.1.37-bin.jar
以上的配置是针对于文本编辑器的方式开发,使用IDEA工具的时候,不需要配置以上的环境变量。
DEA有自己的配置方式。
JDBC编程六步(需要背会)
第一步: 注册驱动 (作用:告诉Java程序,即将要连接的是哪个品牌的数据库)
第二步: 获取连接 (表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭通道)
第三步: 获取数据库操作对象 (专门执行sq1语句的对象)
第四步: 执行SQL语句 (DQL DML.... )
第五步: 处理查询结果集 (只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。)
第六步: 释放资源 使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)
代码实战
举例一(注册驱动方法1 , JDBC完成insert)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

/*
  JDBC 编程六步
  1. 注册驱动
     java.sql.Driver driver = new com.mysql.jdbc.Driver(); // java.sql.Driver dirver抽象接口 com.mysql.jdbc.Driver实现类 ; 多态,父类的引用指向子类的对象
     java.sql.DriverManager.registerDriver(driver) Java的sql包下的用于管理一组JDBC驱动程序的基本服务的类的registerDriver()静态方法完成注册
  2. 建立连接
     Connection connection = DriverManager.getConnection(url,user,password);  DriverManager类中的getConnection建立与给定数据库URL的连接,返回一个Connection(连接对象)com.mysql.jdbc.JDBC4Connection@6d21714c。
  3. 获取数据库对象
     Statement statement = connection.createStatement(); 调用步骤二返回的数据库对象的createStatement方法返回一个Statement对象(Statement用于执行静态SQL语句并返回其生成的结果的对象)
  4. 执行SQL
     int count = statement.executeUpdate(sql);  调用statement对象的executeUpdate方法,执行给定的SQL语句(INSERT、UPDATE、DELETE )
  5. 如果第四步执行的是SELECT语句,这一步便是处理结果集
  6. 释放资源
     为了保证资源一定释放,将把close()操作放在finally中 statement.close(),connection.close(),并且要遵循从小到大依次关闭。 

*/
public class JDBCTest01 {
    public static void main(String[] args) {
        Statement statement=null;
        Connection connection=null;

        try{
            java.sql.Driver driver = new com.mysql.jdbc.Driver(); // java.sql.Driver dirver抽象接口 com.mysql.jdbc.Driver实现类 ; 多态,父类的引用指向子类的对象
            java.sql.DriverManager.registerDriver(driver);

            String url="jdbc:mysql://localhost:13306/atguigudb2";
            String user="root";
            String password="123456";
            connection = DriverManager.getConnection(url,user,password); // java.sql.Connection接口 Connection对象的数据库能够提供描述其表,其支持的SQL语法,其存储过程,此连接的功能等的信息。 该信息是用getMetaData方法获得的。
            System.out.println("数据库连接对象="+ connection); // 数据库连接对象=com.mysql.jdbc.JDBC4Connection@6d21714c

            statement = connection.createStatement(); // Statement 专门执行sql语句

            String sql="INSERT INTO emp32 VALUES(1)";
            int count = statement.executeUpdate(sql);// 执行给定的SQL语句的方法,专门执行DML语句的(insert delete update),返回值是"影响数据库中的记录条数"
            System.out.println(count==1 ? "保存成功" : "保存失败");

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            // 释放资源
            // 为了保证资源一定释放,在finally语句块中关闭资源,并且要遵循从小到大依次关闭,分别对其try..catch
            try {
                if(statement!=null){
                    statement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }

    }
}
举例二 (JDBC完成delete)
import java.sql.*;

/*
     JDBC完成delete
     
     1、注册驱动
     2、建立数据库连接
     3、获取数据库对象
     4、执行SQL
     5、如果第四步执行的是SELECT语句,则会有此步,应为处理结果集
     6、释放资源
*/
public class JDBCTest02 {
    public static void main(String[] args) {

        Statement statement=null;
        Connection connection=null;
        try {
            java.sql.Driver driver = new com.mysql.jdbc.Driver();
            DriverManager.registerDriver(driver);

            String url="jdbc:mysql://localhost:13306/atguigudb2";
            String user="root";
            String password="123456";
            connection = DriverManager.getConnection(url,user,password);
            System.out.println(connection);

            statement = connection.createStatement();

            String sql=" DELETE FROM emp1 WHERE id=0 ";
            int count = statement.executeUpdate(sql);
            System.out.println(count==1 ? "操作成功" : "操作失败"); 

        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            try {
                if(statement !=null){
                    statement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
}

举例三(注册驱动方法2)
①通过查看com.mysql.jdbc.Driver类的源码发现,可以利用反射的机制(Classs.forName此方法的执行会导致类的加载)从而使类中的静态代码块执行(这个代码块便是注册驱动的操作)
②将连接数据库的所有信息配置到配置文件中
import sun.security.util.Password;

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

/*
        注册驱动的另一种方式(常用)
        将连接数据库的所有信息配置到配置文件中
     1、注册驱动
     2、创建连接
     3、获取数据库对象
     4、执行SQL
     5、如果步骤4执行的是SELECT语句,则应有此步骤,为处理结果集
     6、释放资源

 */
public class JDBCTest03 {
    public static void main(String[] args) {
        //使用资源绑定器绑定属性配置文件
        ResourceBundle bundle = ResourceBundle.getBundle("jdbc03");
        String driver = bundle.getString("driver");
        String url = bundle.getString("url");
        String user = bundle.getString("user");
        String password = bundle.getString("password");

        Connection connection=null;
        Statement statement=null;

        try {
            //注册驱动第一种写法
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            //注册驱动方法二( 常用,因为参数是字符串,而字符串可以写到xxx.properties(配置文件)中)  (以下方法不需要接受返回值,我们只是想用它的类加载动作)
            //通过查看com.mysql.jdbc.Driver类的源码发现,可以利用反射的机制(Classs.forName此方法的执行会导致类的加载)从而使类中的静态代码块执行(这个代码块便是注册驱动的操作)
            Class.forName(driver);

            connection = DriverManager.getConnection(url, user, password);
            System.out.println(connection);

            statement = connection.createStatement();  // createStatement()

            String sql = " insert into atguigudb2.emp1 values (12,'鱼仔',now()) ";
            int count = statement.executeUpdate(sql);
            System.out.println(count==1 ?"操作成功" :"操作失败" );
            
        }catch (SQLException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally {
            try {
                if(statement!=null){
                    statement.close();
                }
            }catch (SQLException e ){
                e.printStackTrace();
            }
           try {
               if(connection!=null){
                   connection.close();
               }
           }catch (SQLException e){
               e.printStackTrace();
           }
        }
        
    }
}
/* jdbc03.properties */
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:13306/atguigudb2
user=root
password=123456
举例四(处理结果集)
import java.sql.*;
import java.util.ResourceBundle;

/*

        处理查询结果集
        1、注册驱动
        2、建立连接
        3、获取数据库对象
        4、执行SQL
        5、若第四步执行的是SELECT,则此步为处理结果集
        6、释放资源

 */
public class JDBCTest04 {
    public static void main(String[] args) {

        //将数据库信息绑定在配置文件
        ResourceBundle resourceBundle=ResourceBundle.getBundle("JDBC04");
        String driver = resourceBundle.getString("driver");
        String url = resourceBundle.getString("url");
        String user = resourceBundle.getString("user");
        String password = resourceBundle.getString("password");

        Connection connection=null;
        Statement statement =null;
        ResultSet resultSet=null;
        try {

            Class.forName(driver);

            connection = DriverManager.getConnection(url,user,password);
            System.out.println(connection);

            statement = connection.createStatement();

            // int executeUpdate (insert/delete/update)
            // ResultSet executeQuery (select)
            String sql=" select id i,name n,hire_date h from atguigudb2.emp1 ";
            resultSet = statement.executeQuery(sql); // executeQuery()方法,通常参数为静态SQL SELECT语句,返回一个ResultSet对象。

            //处理结构集
                // next()方法,移动光标到行前,依次往下,有数据返回ture,无数据返回false。
                // getString()方法,检索当前行中指定列的值ResultSet对象为String的值并返回,参数为列的下标数(从1开始)
                //                ,但使用下标,使程序并不健壮,建议使用字段名获取。
//            while (resultSet.next()){
//                String  id_name=resultSet.getString(1);
//                String  name_name=resultSet.getString(2);
//                String  date_name=resultSet.getString(3);
//                System.out.println(id_name+","+name_name+date_name);
//            }
            // 建议: 此写法不是以列的下标获取,而是以列的名字获取。
 /*           while (resultSet.next()){
                String  id_name=resultSet.getString("i");
                String  name_name=resultSet.getString("n");
                String  date_name=resultSet.getString("h");
                System.out.println(id_name+","+name_name+date_name);
            }
*/
            // 除了可以以String类型取出之外,还可以以特定的类型取出。
            while (resultSet.next()){
                int  id_name=resultSet.getInt("i");
                String  name_name=resultSet.getString("n");
                String  date_name=resultSet.getString("h");
                System.out.println(id_name+","+name_name+date_name);
            }
            
        }catch (SQLException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }finally {
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (statement!=null){
                    statement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }
    }
}
/* JDBC04.properties */
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:13306/atguigudb2
user=root
password=023156
IDEA配置驱动

新建工程:
File - New - Project - Empty Project(空的工程) - NEXT - Project name(工程名称) - project location(工程文件存放路径) - Finish - OK - New Window 。

新建模块:
File - New - Module - Java - NEXT - Module name - Finish 。

导入驱动:
右键模块 - Open Module Settings - Libraries - + - Java - 选择jar包(驱动) - Choose Modules(导入哪个模块中) - Apply - Ok。

PowerDesigner16.5安装

NEXT - NEXT - 选择People R…China(PRC),然后选择我同意协议-

在这里插入图片描述
更改路径
在这里插入图片描述
根据自己需要选择,也可以全选
在这里插入图片描述
根据自己需要选择,这里选择全选
在这里插入图片描述
直接下一步
在这里插入图片描述
继续下一步

在这里插入图片描述
等待安装
在这里插入图片描述

功能实现
模拟用户登录 (sql注入)
/*
实现功能:
       1、需求:
            模拟用户登录的功能的实现。
       2、业务描述:
            程序运行的时候吗,提供一个输入的入口,可以让用户输入用户名和密码
            用户输入用户名和密码之后,提交信息,java程序收集到用户信息
            Java程序连接数据库验证用户名和密码是否合法
            合法:显示登录成功
            不合法:显示登录失败
       3、数据准备:
            在实际开发中,表的设计会使用专业的建模工具,我们这里安装一个建模工具: PowerDesigner
            使用PD工具来进行数据库表的设计。(参见user-login.sql脚本)
       4、当前程序存在问题:
       用户名:fdsa
       密码:fdsa' or '1'='1
       登陆成功
       这种现象被成为SQL注入(安全隐患)。 多年前黑客常用
      5、导致SQL注入的根本原因是什么?
           用户输入的信息中含有sq1语句的关键字,并且这些关键字参与sq1语句的编译过程,
           导致sql语句的原意被扭曲,进而达到sql注入。
           
      注册驱动
      建立连接
      获取数据库对象
      执行SQL
      处理结果集
      释放资源
*/

import com.mysql.jdbc.Driver;

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

public class JDBCTest05 {
    public static void main(String[] args) {
        //初始化一个界面
        Map<String,String> userLoginInfo=initUI();
        //验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);
        //输出结果
        System.out.println(loginSuccess ? "登陆成功": "登录失败");

    }

    /**
     *用户登录
     * @param userLoginInfo 用户登录信息
     * @return false表示失败,true表示成功
     */

    private static boolean login(Map<String, String> userLoginInfo) {
        //打标记的意识
        boolean loginSuccess = false;
        //JDBC代码
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet=null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //建立连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2", "root", "123456");
            //获取数据库对象
            statement= connection.createStatement();
            //执行SQL
            String sql="select * from t_user where login_name='"+userLoginInfo.get("loginName")+"' and login_password='"+userLoginInfo.get("loginPwd")+"'";
            //以上正好完成了sq1语句的拼接,以下代码的含义是,发送sq1语句给DBMS, DBMs进行sq1编译。
            //正好将用户提供的“非法信息"编译进去。导致了原sq1语句的含义被扭曲了。
            resultSet = statement.executeQuery(sql);
            //处理结果集
            if(resultSet.next()){
                //登录成功
                loginSuccess=true;
            }
            //释放资源

        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            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();
                }
            }
        }


        return loginSuccess;
    }

    /**
     * 初始化用户界面
     * @return 用户输入的用户名和密码等登录信息
     */
    private static Map<String, String> initUI() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("用户名: ");
        String loginName = scanner.nextLine();  // nextLine() 读取整行数据

        System.out.println("密码: ");
        String loginPwd= scanner.nextLine();

        Map<String,String> userLoginInfo =new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);

        return userLoginInfo;
    }
}

PreparedStatement (解决sql注入)
/*
 1、解决SQL注入问题?
       决解方法:使用户提供的信息不参与SQL语句的编译过程,问题就解决了。
       要想用户信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement
       PreparedStatement接口继承了java.sql.Statement,是属于预编译的数据库对象,PreparedStatement原理是:预先对SQL语句的框架进行编译,然后再给sql语句传值。
 2、测试结果:
      用户名: fdsa
      密码: fdsa' or '1'='1
      登录失败
 */

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

public class JDBCTest06 {
    public static void main(String[] args) {
        //初始化一个界面
        Map<String,String> userLoginInfo=initUI();
        //验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);
        //输出结果
        System.out.println(loginSuccess ? "登陆成功": "登录失败");

    }

    /**
     *用户登录
     * @param userLoginInfo 用户登录信息
     * @return false表示失败,true表示成功
     */

    private static boolean login(Map<String, String> userLoginInfo) {
        //打标记的意识
        boolean loginSuccess = false;
        //单独定义变量
         String loginName=userLoginInfo.get("loginName");
         String loginPwd=userLoginInfo.get("loginPwd");
        //JDBC代码
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet=null;
        try {
            //1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、建立连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2", "root", "123456");
            //3、获取(预编译的)数据库对象
            //sql语句的框子。其中一个?,表示一个占位符,一个2将来接收一个“值”,注意:占位符不能使用单引号括起来。
            String sql="select * from t_user where login_name=? and login_password=?";
            //程序执行到此处,会发送sq1语句框子给DBMS,然后DBMS进行sq1语句的预先编译。
            preparedStatement = connection.prepareStatement(sql);
            //给占位符?传值(第1个问号下标是1,第2个问号下标是2, JDBC中所有下标从1开始。)
            preparedStatement.setString(1,loginName);
            preparedStatement.setString(2,loginPwd);

            //4、执行SQL
            resultSet=preparedStatement.executeQuery();
            //处理结果集
            if(resultSet.next()){
                //登录成功
                loginSuccess=true;
            }
            //释放资源

        }catch(ClassNotFoundException e){
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(preparedStatement!=null){
                try {
                    preparedStatement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


        return loginSuccess;
    }

    /**
     * 初始化用户界面
     * @return 用户输入的用户名和密码等登录信息
     */
    private static Map<String, String> initUI() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("用户名: ");
        String loginName = scanner.nextLine();  // nextLine() 读取整行数据

        System.out.println("密码: ");
        String loginPwd= scanner.nextLine();

        Map<String,String> userLoginInfo =new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);

        return userLoginInfo;
    }
}
Statement和PreparedStatement的对比
StatementPreparedStatement的对比
   Statement存在sql注入问题,PreparedStatement解决SQL注入问题。
   Statement是编译一次执行一次。PreparedStatement是编译一次,可执行N次。PreparedStatement效率较高一些。
   PreparedStatement会在编译阶段做类型的安全检查。
   综上,PreparedStatement使用较多。只在极少数情况需要使用Statement
Statement的应用场景

需求: 用户在控制台输入desc就是降序,输入asc就是升序
4、Statement使用的场景
业务方面要求必须支持SQL注入的时候。: Statement支持sql注入,凡是业务方面要求是需要进行sqI语句拼接的,必须使用Statement。
例如: 在页面实现降序、升序功能的时候,需要在SQL语句的尾端使用order BY ASC 或 DESC 而此时使用PreparedStatement进行值传递,向已
编译好的SQL语句中传入’ASC’或’DESC’时,将不符合SQL语句规范,导致执行失败。 此时便需要Statement进行sql注入。
总结: SQL拼接用Statement, 往SQL语句中传值用PreparedStatement 。

/*
4、Statement使用的场景
   业务方面要求必须支持SQL注入的时候。: Statement支持sql注入,凡是业务方面要求是需要进行sqI语句拼接的,必须使用Statement。
       例如: 在页面实现降序、升序功能的时候,需要在SQL语句的尾端使用order BY ASC 或 DESC 而此时使用PreparedStatement进行值传递,向已
             编译好的SQL语句中传入'ASC'或'DESC'时,将不符合SQL语句规范,导致执行失败。 此时便需要Statement进行sql注入。
    总结: SQL拼接用Statement, 往SQL语句中传值用PreparedStatement 。
*/
import java.sql.*;
import java.util.Scanner;

/*
   用户在控制台输入desc就是降序,输入asc就是升序
*/
public class JDBCTest07 {
    public static void main(String[] args) {
        /*
        //测试结果:  You have an error in your SQL syntax;
                  // check the manual that corresponds to your MySQL server version for the right syntax to use near ''asc'' at line 1
        Scanner scanner= new Scanner(System.in);
        System.out.println("请输入desc或asc,desc表示降序,asc表示升序");
        System.out.print("请输入: ");
        String keywords = scanner.nextLine(); //捕获输入的值

        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //建立连接
            connection =DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2","root","123456");
            //获取数据库预编译对象
            String sql=" select * from t_user order by login_name ?";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,keywords);
            //执行sql
            resultSet = preparedStatement.executeQuery();
            //处理结果集
            while (resultSet.next()){
                String a = resultSet.getString("id");
                String b = resultSet.getString("login_name");
                String c = resultSet.getString("realName");
                System.out.println(a+","+b+","+c);
            }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (preparedStatement!=null){
                    preparedStatement   .close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }

         */

        // 测试结果: 排序成功 
        Scanner scanner= new Scanner(System.in);
        System.out.println("请输入desc或asc,desc表示降序,asc表示升序");
        System.out.print("请输入: ");
        String keywords = scanner.nextLine(); //捕获输入的值

        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;
        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //建立连接
            connection =DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2","root","123456");
            //获取数据库对象
            statement = connection.createStatement();
            //执行sql
            String sql=" select * from t_user order by login_name "+keywords ;
            resultSet=statement.executeQuery(sql);
            //处理结果集
            while (resultSet.next()){
                String a = resultSet.getString("id");
                String b = resultSet.getString("login_name");
                String c = resultSet.getString("realName");
                System.out.println(a+","+b+","+c);
            }


        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (statement!=null){
                    statement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if (connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }

        }


    }
}
preparedStatement完成insert delete update
import java.sql.*;
/*
  preparedStatement完成insert delete update

*/
public class JDBCTest08 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;

        try {
            //1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2", "root", "123456");
            //3、获取预编译的数据库对象
          /*  一、(插入一条记录)
            String sql = " insert into t_user(id,login_name,login_password,realName) values (?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,10);
            preparedStatement.setString(2,"Tom");
            preparedStatement.setString(3,"123456");
            preparedStatement.setString(4,"汤姆");
           */
            /* 二、修改一条记录
            String sql = " update t_user set login_name=?,realName=? where id=? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(3,1);
            preparedStatement.setString(1,"GGbood");
            preparedStatement.setString(2,"鸡鸡bong");
            */
             /* 三、删除一条记录 */
            String sql = " delete from t_user where id=? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,1);
            //4、执行sql
            int count = preparedStatement.executeUpdate();
            System.out.println(count);

        }catch (SQLException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }finally {
            //6、释放资源
            try {
                if(preparedStatement!=null){
                    preparedStatement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }

    }
}
JDBC事务机制 (自动提交,有风险)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
   JDBC事务机制:
        1、JDBC中的事务是自动提交的,什么是自动提交?
            只要执行任意一条DM语句,则自动提交一次。这是JDBc默认的事务行为。
            但是在实际的业务当中,通常都是N条DM语句共同联合才能完成的,必须保证他们这些DM语句在同一个事务中同时成功或者同时失败。
        2、以下程序先来验证一下JDBc的事务是否是自动提交机制!
        测试结果: JDBc中只要执行任意一条 DMI语句,就提交一次。
            说明: 程序执行到断点处时,count已被赋值为1,说明第一次插入操作已经执行,
            但此时查看数据库,发现数据库的数据已经被更改,说明jdbc的事务已经进行了提交,尽管后面的sql操作还没有执行( 若这次操作失败,则会出现事故 )

*/
public class JDBCTest09 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;

        try {
            //1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2", "root", "123456");
            //3、获取预编译的数据库对象
            String sql = " insert into t_user(id,login_name,login_password,realName) values (?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql);

            // 第一次给占位符传值
            preparedStatement.setInt(1,14);
            preparedStatement.setString(2,"Tom2");
            preparedStatement.setString(3,"123456");
            preparedStatement.setString(4,"汤姆");
            int count = preparedStatement.executeUpdate();
            System.out.println(count);

            // 重新给占位符传值
            preparedStatement.setInt(1,15);
            preparedStatement.setString(2,"Tom3");
            preparedStatement.setString(3,"123456");
            preparedStatement.setString(4,"汤姆");
            count = preparedStatement.executeUpdate();
            System.out.println(count);


        }catch (SQLException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        }finally {
            //6、释放资源
            try {
                if(preparedStatement!=null){
                    preparedStatement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }

    }
}

在这里插入图片描述

账户转账演示事务 (决解方法)乄
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

/*
   账户转账演示事务
   sql脚本:
   create table t_act ( actno int, balance double(10,2) ) ;
   insert into t_act(actno,balance) values ( 111,20000 ),(222,0);

    当执行完第一次sql语句后,出现空指针异常导致后面的程序无法执行,可事务已经自动提交了,所以丢了10000元。

    解决方法: 要将数据库JDBC的自动提交机制改为手动。
              connection.setAutoCommit(false);   将此连接的自动提交模式设置为给定状态。
              connection.commit();    使自上次提交/回滚以来所做的所有更改都将永久性,并释放此 Connection对象当前持有的任何数据库锁。
              connection.rollback();   撤消在当前事务中所做的所有更改,并释放此 Connection对象当前持有的任何数据库锁。

*/
public class JDBCTest11 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;

        try {
            //1、注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2、获取连接
            connection = DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2", "root", "123456");
              //将自动提交机制改为手动提交
              connection.setAutoCommit(false);  // setAutoCommit(): 将此连接的自动提交模式设置为给定状态。
            //3、获取预编译的数据库对象
            String sql=" update t_act set balance=? where actno=? ";
            preparedStatement = connection.prepareStatement(sql);

            //给?传值
            preparedStatement.setDouble(1,10000);
            preparedStatement.setInt(2,111);
            int count = preparedStatement.executeUpdate();
            System.out.println(count);

            //中间发生空指针异常
            String s= null;
            s.toString();

            //再次给?传值
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setDouble(1,10000);
            preparedStatement.setInt(2,222);
            count += preparedStatement.executeUpdate();
            System.out.println(count==2 ? "转账成功" : "转账失败");

            // 程序能够走到这里说明以上程序没有异常,事务结束,手动提交数据
            connection.commit(); //使自上次提交/回滚以来所做的所有更改都将永久性,并释放此 Connection对象当前持有的任何数据库锁。

        }catch (Exception e){
            try {
                //回滚事务
                if(connection!=null){
                    connection.rollback();
                }
            }catch (SQLException exception){
                exception.printStackTrace();
            }

            e.printStackTrace();
        }finally {
            //6、释放资源
            try {
                if(preparedStatement!=null){
                    preparedStatement.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try {
                if(connection!=null){
                    connection.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
        }

    }
}
JDBC工具类的封装
package utils;

import java.sql.*;

/*
   JDBC工具类,简化JDBC编程
*/
public class DBUtil {
    /*
       工具类中的构造方法都是私有的。
       因为工具类中的方法都是静态的,不需要new对象,直接采用类名调用。
    */
    private DBUtil(){}

    //静态代码块在类加载时执行,并且只执行一次。
    /**
     * 注册驱动
     */
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接对象
     * @return 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:13306/atguigudb2","root","123456");
    }

    /**
     * 关闭资源
     * @param connection 连接对象
     * @param statement 数据库操作对象
     * @param resultSet 结果集
     */
    public static void close(Connection connection, Statement statement,ResultSet resultSet){
        try {
            if(resultSet!=null){
                resultSet.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        try {
            if(statement!=null){
                statement.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        try {
            if(connection!=null){
                connection.close();
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
    }

}
JDBC实现模糊查询
import utils.DBUtil;

import java.sql.*;

/*
   1、测试DBUtil
   2、模糊查询怎么写  (查询员工名字第二个字母是a的)

*/
public class JDBCTest12 {
    public static void main(String[] args) {

        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try {
            //1、注册驱动
            //2、获取连接
            connection = DBUtil.getConnection();
            //3、获取预编译数据库对象
            String sql = " select login_name from t_user where login_name like ? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,"_a%");
            //4、执行SQL
            resultSet = preparedStatement.executeQuery();

            //5、处理结果集
            while (resultSet.next()){
                String a = resultSet.getString("login_name");
                System.out.println(a);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6、释放资源
            DBUtil.close(connection,preparedStatement,resultSet);
        }

    }
}

在Java应用层面演示SQL的悲观锁(for update)
for update (悲观锁or行级锁)  
悲观锁: 事务必须排队执行。若A事务正在操作数据库中的一些数据,此时被操作的这些数据将被锁住,不允许被并发。只有等A事务结束了,等着的B事务才能继续(要是A一直不结果,B只能一直等着)。 

乐观锁: 支持并发,事务也不需要排队,只不过需要一个版本号。
    id  salary name 
    1   7000   jack   1.1
事务1(同时操作数据库) --> 读取版本号为1.1 ->> 先一步操作完毕,提交数据,校对版本号发现一致,操作成功,版本号被修改为1.2 。
事务2(同时操作数据库) --> 读取版本号为1.1 ->>A事务后操作完,再校对版本号发现不一致,回滚操作。  

import utils.DBUtil;

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

/*
   此程序开启一个事务,这个事务专门进行查询,并且使用行级锁/悲观锁,锁住相关的记录。
 */
public class JDBCTest13 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement =null;
        ResultSet resultSet=null;

        try {
            //1、注册驱动
            //2、获取连接
            connection = DBUtil.getConnection();
            //关闭事务自动提交
            connection.setAutoCommit(false);
            //3、获取预定义数据库对象
            String sql=" select id,login_name,realName from t_user where id=? for update ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,3);
            //4、执行SQL
            resultSet = preparedStatement.executeQuery();
            //5、处理结果集
            while (resultSet.next()){
                int a=resultSet.getInt("id");
                String b=resultSet.getString("login_name");
                String c=resultSet.getString("realName");
                System.out.println(a+","+b+","+c);
            }
            //提交事务
            connection.commit();
        }catch (SQLException e){
            try {
                //事务回滚
                if (connection!=null){
                    connection.rollback();
                }
            }catch (SQLException e1){
                e1.printStackTrace();
            }

            e.printStackTrace();
        }finally {
            //6、释放资源
            DBUtil.close(connection,preparedStatement,resultSet);
        }
    }
}
import utils.DBUtil;

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

/*
  此程序负责修改被锁定的记录。
*/
public class JDBCTest14 {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement =null;

        try {
            connection = DBUtil.getConnection();

            connection.setAutoCommit(false);

            String sql=" update t_user set login_name=? where id=? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,"喜羊羊");
            preparedStatement.setInt(2,3);
            int count = preparedStatement.executeUpdate();
            System.out.println(count);

            connection.commit();
        }catch (SQLException e){
            try {
                if (connection!=null){
                    connection.rollback();
                }
            }catch (SQLException e1){
                e1.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            DBUtil.close(connection,preparedStatement,null);
        }
    }
}

在这里插入图片描述
在这里插入图片描述

Druid(德鲁伊)数据库连接池

注意导包: druid-1.1.10.jar

/* DruidTest.java */ 

package LianJieCi;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;

import javax.annotation.Resource;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class DruidTest {

    private static  DataSource dataSource;
    static {
        try {
            Properties properties = new Properties();
            InputStream resourceAsStream = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
            properties.load(resourceAsStream);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public Connection getConnection() throws SQLException {
        Connection connection = dataSource.getConnection();
        return connection;

    }
}
/* druid.properties */  

url=jdbc:mysql://localhost:13306/test
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=10
/*JDBCUtiles.java*/ 

package LianJieCi;

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

/**
 * @author shkstart
 * @create 2022-03-23 11:20
 */
public class JDBCUtiles {
    public static void main(String[] args) throws SQLException {

        DruidTest druidTest = new DruidTest();
        Connection connection = druidTest.getConnection();
        System.out.println(connection);
    }
}

Apache-DBUtils实现CRUD操作

注意导包:commons-dbutils-1.3.jar

QueryRunnerTest.java
package dbutils;

import LianJieCi.DruidTest;
import bean.Customer;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.ResultSetHandler;
import org.apache.commons.dbutils.handlers.*;
import org.junit.Test;

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

//commons-dbutils 是Apache组织提供的一个开源JDBC具类库,封装了针对于数据库的增删改查操作。
public class QueryRunnerTest {
    @Test
    //测试插入
    public void testInsert() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();
            System.out.println(conn);

            String sql=" INSERT INTO temp1(id,NAME)  VALUES (?,?) ";

            QueryRunner queryRunner = new QueryRunner();
            int insertCount = queryRunner.update(conn,sql,6,"龙");
            System.out.println("添加了"+insertCount+"条记录");
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //致命操作: 此处应该写在finally中
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @Test
    //测试查询,返回单个对象
    public void testSelect1() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql="SELECT id,NAME FROM temp1 where id=?";

            //BeanHandler :是ResultSetHandler接口的实现类,用于封装表中的一条记录。
            BeanHandler<Customer> handler= new BeanHandler<Customer>(Customer.class);

            QueryRunner queryRunner = new QueryRunner();

            Customer customer = queryRunner.query(conn, sql, handler, 1);
            System.out.println(customer);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //测试查询,返回多个对象
    public void testSelect2() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql="SELECT id,NAME FROM temp1 where id>?";

            //BeanListHandler :是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合。
            BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class);

            QueryRunner queryRunner = new QueryRunner();

            List<Customer> list = queryRunner.query(conn, sql, handler, 1);
            list.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }


    }

    @Test
    //测试查询,MapHandler(单条)
    public void testSelect3() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql="SELECT id,NAME FROM temp1 where id=?";

            //MapHandler :是ResultSetHandler接口的实现类,对应表中的一条记录。将字段及相应字段的值作为map中的key和value。
            MapHandler handler=new MapHandler();

            QueryRunner queryRunner = new QueryRunner();

            Map<String, Object> map = queryRunner.query(conn, sql, handler, 1);
            System.out.println(map);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //测试查询,MapListHandler(多条)
    public void testSelect4() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql="SELECT id,NAME FROM temp1 where id>?";

            //MapListHandler :是ResultSetHandler接口的实现类,对应表中的多条记录。将字段及相应字段的值作为map中的key和value。将这些map添加到List中。
            MapListHandler handler=new MapListHandler();

            QueryRunner queryRunner = new QueryRunner();

            List<Map<String, Object>>  List = queryRunner.query(conn, sql, handler, 1);
            List.forEach(System.out::println);

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //测试查询,ScalarHandler,用于查询特殊字段
    public void testSelect5() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql=" select count(*) from temp1 ";

            ScalarHandler handler = new ScalarHandler();

            QueryRunner queryRunner = new QueryRunner();

            Long count= (Long) queryRunner.query(conn, sql, handler);
            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //测试查询,ScalarHandler,用于查询特殊字段
    public void testSelect6() {
        Connection conn=null;
        try {
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql=" select max(id) from temp1 ";

            ScalarHandler handler = new ScalarHandler();

            QueryRunner queryRunner = new QueryRunner();

            int count= (int) queryRunner.query(conn, sql, handler);
            System.out.println(count);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //如果以上实现类都不满足业务需求,自己自定义一个Interface ResultSetHandler<T>接口的实现类。
    public void testSelect7() {
        Connection conn=null;
        try {
            QueryRunner queryRunner = new QueryRunner();
            DruidTest druidTest = new DruidTest();
            conn = druidTest.getConnection();

            String sql="select * from temp1 where id=?";
            //自定义 (匿名接口实现类)
            ResultSetHandler<Customer> handler=new ResultSetHandler<Customer>() {
                @Override
                public Customer handle(ResultSet resultSet) throws SQLException {
//                    return null;
                    if(resultSet.next()){

                        int id = resultSet.getInt("id");
                        String name = resultSet.getString("NAME");
                        Customer customer = new Customer(id, name, null, null);
                        return customer;
                    }
                    return null;
                }
            };

            Customer customer = queryRunner.query(conn, sql, handler, 1);
            System.out.println(customer);


        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            try {
                if (conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    @Test
    //使用dbutils.jar中提供的DbUtils工具类,实现资源的关闭。
    public static void closeResource2(Connection connection, Statement statement, ResultSet resultSet, PreparedStatement preparedStatement){
        /* 一 较手写省了if
        try {
            DbUtils.close(preparedStatement);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            DbUtils.close(resultSet);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            DbUtils.close(statement);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            DbUtils.close(connection);
        } catch (SQLException e) {
            e.printStackTrace();
        } */
        /* 二 较手写省了if,try */
        DbUtils.closeQuietly(preparedStatement);
        DbUtils.closeQuietly(resultSet);
        DbUtils.closeQuietly(statement);
        DbUtils.closeQuietly(connection);

    }

    @Test
    //关闭资源(手动写)  
    public static void closeResource1(Connection connection, Statement statement, ResultSet resultSet, PreparedStatement preparedStatement){
        try {
            if ( preparedStatement!=null ){
                preparedStatement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if ( resultSet!=null ){
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if (statement!=null ){
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if ( connection!=null ){
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }

}
/* Customer.java */ 
package bean;

import java.sql.Date;

/*
 * ORM编程思想  (object relational mapping)
 * 一个数据表对应一个java类
 * 表中的一条记录对应java类的一个对象
 * 表中的一个字段对应java类的一个属性
 * 
 */
public class Customer {
	
	private int id;
	private String name;
	private String email;
	private Date birth;
	public Customer() {
		super();
	}
	public Customer(int id, String name, String email, Date birth) {
		super();
		this.id = id;
		this.name = name;
		this.email = email;
		this.birth = birth;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getEmail() {
		return email;
	}
	public void setEmail(String email) {
		this.email = email;
	}
	public Date getBirth() {
		return birth;
	}
	public void setBirth(Date birth) {
		this.birth = birth;
	}
	@Override
	public String toString() {
		return "Customer [id=" + id + ", name=" + name + ", email=" + email + ", birth=" + birth + "]";
	}
	
	
	
}

<!-- druid.properties --> 
url=jdbc:mysql://localhost:13306/dbtest12
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=10

总结

传统创建一次性连接
/*  jdbc_1.java */
package utils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * @author shkstart
 * @create 2022-03-24 14:48
 */
public class jdbc_1 {
    public static void main(String[] args) {

        Connection connection= null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        try {
            connection = new getConnection1().getConnection();

            String sql="select * from temp1 ";
            ps = connection.prepareStatement(sql);
            resultSet = ps.executeQuery();

            if (resultSet.next()){
                String id = resultSet.getString("id");
                String NAME = resultSet.getString("NAME");
                System.out.println(id+","+NAME);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            close close = new close();
            close.close(connection,null,ps,resultSet);
        }
    }
}
/*  getConnection1.java */
package utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.ResourceBundle;

/**
 * @author shkstart
 * @create 2022-03-24 14:56
 */
public class getConnection1 {

    public  Connection getConnection() throws Exception{

        ResourceBundle resource = ResourceBundle.getBundle("getConnection_p");
        String driver = resource.getString("driver");
        String url = resource.getString("url");
        String user = resource.getString("user");
        String password = resource.getString("password");

        Class.forName(driver);
        Connection connection = DriverManager.getConnection(url,user,password);

        return connection;
    }
}
/* close.java  */
package utils;

import java.sql.*;
public class close {

    public void close(Connection connection, Statement statement, PreparedStatement preparedStatement, ResultSet resultSet){
        try {
            if(resultSet!=null){
                resultSet.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(preparedStatement!=null){
                preparedStatement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(statement!=null){
                statement.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        try {
            if(connection!=null){
                connection.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
<!-- getConnection_p.properties -->
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:13306/dbtest12
user=root
password=123456
使用数据库连接池
/* jdbc_2.java */
package utils;

// DataSource数据源
// Properties类 读取配置文件
// commons-dbutils工具类jar包
// QueryRunner类 一共有6种方法,query对应sql查询,update(SQL中INSERT,UPDATE,或DELETE语句)....
//ResultSetHandler处理结果集 8种,BeanListHandler、ArrayListHandler、ScalarHandler....
//BeanListHandler类 将结果集中每一条记录封装到指定的javaBean中,将这些javaBean在封装到List集合中。

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import java.util.Properties;

public class jdbc_2 {
    public static void main(String[] args) {
        Connection connection=null;

        try {
            druid_conn druid = new druid_conn();
            connection = druid.getConnection();

            String sql="select * from temp1";
            //BeanListHandler :是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合。
            BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class);

            QueryRunner queryRunner = new QueryRunner();
            List<Customer> list = queryRunner.query(connection,sql, handler);
            list.forEach(System.out::println);
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //使用dbutils.jar中提供的DbUtils工具类,实现资源的关闭。
            DbUtils.closeQuietly(connection);
        }
    }
}
/*  druid_conn.java */
package utils;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

/**
 * @author shkstart
 * @create 2022-03-24 20:56
 */
public class druid_conn {

    private static DataSource dataSource ;
    static {
        try {
            InputStream resourceAsStream = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");

            Properties pro=new Properties();
            pro.load(resourceAsStream);

            dataSource= DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public Connection getConnection() throws SQLException{
        return dataSource.getConnection();
    }
}
/* Customer.java */
package utils;

/**
 * @author shkstart
 * @create 2022-03-24 21:18
 */
public class Customer {
    private int id;
    private String name;

    public Customer() { super(); }

    public Customer(int id, String name) {
        super();
        this.id = id;
        this.name = name;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Customer [id=" + id + ", name=" + name + "]";
    }
}
<!-- druid.properties --> 
url=jdbc:mysql://localhost:13306/dbtest12
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
initialSize=10
maxActive=10
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值