JDBC基本操作与事务

JDBC(Java DataBase Connectivity)

jdbc概念:简而言之就是定义了一套操作所有关系型数据库的规则(接口)

JDBC基本使用

流程:

-->1. 注册驱动

-->2. 获取数据库连接对象

-->3. 定义SQL

-->4. 定义获取执行SQL的对象

-->5. 执行SQL,返回结果集resultSet

-->6. 遍历结果集,封装对象,装载集合

-->7. 释放资源

package com.meng.jdbc;

import com.meng.entity.User;

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

public class JDBCDemo1 {

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

    /***
     * 查询所有user
     * @return
     */
    public List<User> findAll() {
        Connection conn = null;
        Statement statement = null;
        ResultSet resultSet = null;
        List<User> list = null;

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

            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost/test2", "root", "123456");

            //3.定义SQL
            String sql = "select * from user";

            //4.获取执行SQL对象
            statement = conn.createStatement();

            //5.执行SQL
            resultSet = statement.executeQuery(sql);


            //遍历结果集,封装对象,装载集合
            User user =null;
            list =new ArrayList<User>();
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");

                //创建user对象,并赋值
                user = new User();
                user.setId(id);
                user.setName(name);
                user.setAge(age);

                //装载集合
                list.add(user);
            }
        } catch (ClassNotFoundException | 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(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

        }
        return list;
    }

}

上面这个方案在每次做crud的时候都要重新获取数据库连接对象,我们将封装成一个工具类来简化操作。

 

JDBCUtils工具类抽取

分析:

1、抽取注册驱动;

2、抽取一个获取数据库连接对象的方法;

*需求:不想在getConnection中传递参数,保证工具类的通用性。

*解决方案: 配置文件方式 jdbc.properties

3、抽取一个释放资源的方法

package com.meng.utils;

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

public class JDBCUtils {
    //静态变量只能被静态方法所访问
    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    /***
     * 文件读取只需要执行一次,所以使用静态代码块(随类的加载而加载,在执行构造器之前,并且只执行一次)
     */

    static {
        /**
         * 获取静态资源文件
         * 使用properties集合类比较方便
         */

            try {

                //创建Properties集合类(当使用该集合类时,路径下的任何文件夹名称都不能有中文字符,否则会报FileNotFoundException)
                Properties properties = new Properties();

                //获取src路径下的文件方式 -->ClassLoader(类加载器)
                ClassLoader classLoader = JDBCUtils.class.getClassLoader();
                URL resource = classLoader.getResource("jdbc.properties");
                String path = resource.getPath();
                System.out.println(path);


                //加载文件
                properties.load(new FileReader(path));

                //3. 获取数据,赋值
                url = properties.getProperty("url");
                user = properties.getProperty("user");
                password = properties.getProperty("password");
                driver = properties.getProperty("driver");

                //注册驱动
                Class.forName(driver);
            } catch (IOException | ClassNotFoundException e) {
                e.printStackTrace();
            }
        }



    /***
     * 获取连接
     * @return
     */
    public static Connection getConnection() throws SQLException {

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

    /***
     * 释放资源
     * @param statement
     * @param connection
     */
    public static void close(ResultSet resultSet, Statement statement, Connection connection){

        //释放resultSet
        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        //释放statement
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        //释放connection
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

登录小案例(PrepareStatement)

package com.meng.jdbc;

import com.meng.utils.JDBCUtils;

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


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

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String name = scanner.nextLine();
        System.out.println("请输入密码:");
        String password = scanner.nextLine();

        boolean login = new JDBCDemo4().login(name, password);

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

    /**
     * 登录方法
     */

    public boolean login(String name,String password){
        if(name ==null || password ==null){
            return false;
        }

        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;

        try {
            connection = JDBCUtils.getConnection();
            String sql = "select * from user where name = ? and password = ?";

            //通过preparedStatement获取数据库执行对象
            preparedStatement = connection.prepareStatement(sql);

            //给 ? 赋值
            preparedStatement.setString(1,name);
            preparedStatement.setString(2,password);

            //执行SQL
            resultSet = preparedStatement.executeQuery();

            return resultSet.next();

        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            JDBCUtils.close(resultSet,preparedStatement,connection);
        }
        return false;

    }
}

JDBC事务

1.操作

开启事务:setAutoCommit(boolean autoCommit); //调用该方法设置参数为false,即开启事务

提交事务:commit();

回滚事务:rollback();

2.使用connection来管理事务

package com.meng.jdbc;

import com.meng.utils.JDBCUtils;

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

public class JDBCDemo6 {
    public static void main(String[] args) throws SQLException {
        Connection connection =null;
        PreparedStatement preparedStatement1 = null;
        PreparedStatement preparedStatement2 = null;
        try {
            connection = JDBCUtils.getConnection();

            //开启事务
            connection.setAutoCommit(false);
            String sql1 = "update acount set bonus= bonus-? where id = 1";
            String sql2 = "update acount set bonus= bonus+? where id = 2";

            preparedStatement1 = connection.prepareStatement(sql1);
            preparedStatement2 = connection.prepareStatement(sql2);

            preparedStatement1.setString(1,"500");
            preparedStatement2.setString(1,"500");

            preparedStatement1.executeUpdate();
//            int a = 3/0;如果打开这个地方,出现异常,执行不了第二条SQL语句,执行事务回滚
            
            
            preparedStatement2.executeUpdate();

            //提交事务
            connection.commit();
        } catch (SQLException e) {
            try {
                //事务回滚
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JDBCUtils.close(preparedStatement1,connection);
        }
    }
}
上一篇:MyBatis学习笔记(1)-MyBatis介绍


下一篇:从Java ResultSet而不是从基础数据库中删除行