【JavaWeb】JDBC的基本操作和事务控制+登录和转账案例

1 JDBC操作数据库

1.1 连接数据库

首先导入jar包到lib
在这里插入图片描述

public class JdbcDemo1 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
    	//1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "123456");
        //3.定义sql语句
        String sql = "update account set balance = 500 where id = 1";
        //4.获取执行sql的对象 statement
        Statement statement = conn.createStatement();
        //5.执行sql
        int count = statement.executeUpdate(sql);
        //6.处理结果
        System.out.println(count);
        //7.释放资源
        statement.close();
        conn.close();
    }
}

1.2 数据库相关对象详解

1.2.1DriverManager:驱动管理对象

  1. 注册驱动
    -Class.forName("com.mysql.jdbc.Driver");
    com.mysql.jdbc.Driver类中存在静态代码块
    MySQL 5 之后的驱动jar包可以省略注册驱动的步骤

  2. 获取数据库连接
    -DriverManager.getConnection("jdbc:mysql://localhost:3306/db2", "root", "password");
    url语法:jdbc:mysql:// [ip地址] : [端口号] / [数据库名称]
    如果连接的是本机的mysql 默认是3306 url可以简写为"jdbc:mysql:///db2"

1.2.2 Connection:数据库连接对象

  1. 获取用于执行sql的对象
  • Statement createStatement();
  • PreparedStatement preparedStatement(String sql);
  1. 管理事务
  • 开启事务:void setAutoCommit(boolean autoCommit) 设置参数为false即开启事务
  • 提交事务:void commit()
  • 回滚事务:void rollback()

1.2.3 Statement:执行sql的对象

  1. 执行sql
  • boolean execute(String sql):可以执行任意sql
  • int executeUpdate(String sql):执行DML(C、U、D)语句、DDL(表、库)语句,返回值是受影响的行数。判断DML是否执行成功,返回值>0则成功。
  • ResultSet executeQurey(String sql):执行DQL(R)语句

1.2.4 ResultSet:结果集对象

  1. 获取封装好的查询结果
    -next():游标向前移动一行
    -getXxx(int column):获取第column列的Xxx类型的数据 索引从1开始
    -getXxx(String name):获取命名为name字段的Xxx类型的数据

1.2.5 PreparedStatement:

  1. sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题。
    sql:-select * from user where username = 'xxxx' and password = 'a' or 'a' = 'a'
  2. 使用PreparedStatement可以解决sql注入问题
  3. 预编译的sql:参数使用?作为占位符
  4. sql的参数使用?作为占位符。
  5. 获取执行sql对象使用preparedStatement
  6. 给占位符赋值setXxxxx(位置编号,值),注意编号从1开始。
  7. 效率高,且防止sql注入,后期都用这个,不再使用Statement对象

1.3 基本操作练习

增删改

    public static void main(String[] args){
    
    
        Connection conn = null;
        Statement statement = null;
        try{
    
    
            Class.forName("com.mysql.jdbc.Driver");
            String sql = "insert into account values(null,'王五',3000)";
            conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "password");
            statement = conn.createStatement();
            int count = statement.executeUpdate(sql);
            if(count > 0){
    
    
                System.out.println("添加成功");
            }else {
    
    
                System.out.println("添加失败");
            }
        }catch (ClassNotFoundException | SQLException e){
    
    
            e.printStackTrace();
        }finally {
    
    
            //避免空指针异常
            if(statement!=null){
    
    
                try {
    
    
                    statement.close();
                }catch (SQLException e){
    
    
                    e.printStackTrace();
                }
            }
            if(conn!=null){
    
    
                try {
    
    
                    conn.close();
                }catch (SQLException e){
    
    
                    e.printStackTrace();
                }
            }

        }
    }

查询

    public static void main(String[] args){
    
    
        Connection conn = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try{
    
    
            Class.forName("com.mysql.jdbc.Driver");
            String sql = "select * from account";
            conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "password");
            statement = conn.createStatement();
            resultSet = statement.executeQuery(sql);
            while(resultSet.next()){
    
    
                int id = resultSet.getInt(1);
                String name = resultSet.getString("name");
                double balance = resultSet.getDouble(3);
                System.out.println(id+ " "+ name+" "+balance);
            }
        }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();
                }
            }

        }
    }

新建一个Account类型的JavaBean
读取表到Account类型的列表中

package jdbc;

import domain.Account;

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

public class JdbcDemo2 {
    
    
    public List<Account> findAll(){
    
    
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Account> accounts = null;
        try {
    
    
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///db2", "root", "123456");
            String sql = "select * from account";
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            accounts = new ArrayList<>();
            Account account = null;
            while(rs.next()){
    
    
                account = new Account();
                int id = rs.getInt("id");
                String name = rs.getString("name");
                double balance = rs.getDouble("balance");
                account.setBalance(balance);
                account.setId(id);
                account.setName(name);
                accounts.add(account);
            }
        } catch (ClassNotFoundException e) {
    
    
            e.printStackTrace();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            if(rs != null){
    
    
                try {
    
    
                    rs.close();
                } catch (SQLException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(stmt != null){
    
    
                try {
    
    
                    stmt.close();
                } catch (SQLException e) {
    
    
                    e.printStackTrace();
                }
            }
            if(conn != null){
    
    
                try {
    
    
                    conn.close();
                } catch (SQLException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
        return accounts;
    }

    public static void main(String[] args) {
    
    
        List<Account> all = new JdbcDemo2().findAll();
        for(Account a : all){
    
    
            System.out.println(a);
        }
    }
}

1.4 抽取JDBC的工具类

简化代码的书写
编写jdbc配置文件,设置url、user、password、driver
jdbc.properties

url=jdbc:mysql:///db2
user=root
password=password
driver=com.mysql.jdbc.Driver
package jdbc;

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

public class JdbcUtil {
    
    
    private static String url;
    private static String user;
    private static String password;
    private static String driver;
    //读取配置文件 用静态代码块 只需要读取一次
    static {
    
    
        try{
    
    
            Properties pro = new Properties();

            //获取src路径下的文件的方式ClassLoader加载器
            ClassLoader classLoader = JdbcUtil.class.getClassLoader();
            URL res = classLoader.getResource("jdbc.properties");
            String path = res.getPath();
            pro.load(new FileReader(path));

            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            Class.forName(driver);
        }catch (IOException 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 stmt, Connection conn){
    
    
        if(stmt!=null){
    
    
            try {
    
    
                stmt.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
        if(conn!=null){
    
    
            try {
    
    
                conn.close();
            }catch (SQLException e){
    
    
                e.printStackTrace();
            }
        }
    }
    public static void close(Statement stmt, Connection conn, ResultSet rs){
    
    
        if(rs!=null){
    
    
            try{
    
    
                stmt.close();
            }catch (SQLException e){
    
    
                e.printStackTrace();
            }
        }
        if(stmt!=null){
    
    
            try {
    
    
                stmt.close();
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        }
        if(conn!=null){
    
    
            try {
    
    
                conn.close();
            }catch (SQLException e){
    
    
                e.printStackTrace();
            }
        }
    }
}

使用工具类

package jdbc;

import domain.Account;

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

public class JdbcDemo2 {
    
    
    public List<Account> findAll(){
    
    
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<Account> accounts = null;
        try {
    
    
            conn = JdbcUtil.getConnection();
            String sql = "select * from account";
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            accounts = new ArrayList<>();
            Account account = null;
            while(rs.next()){
    
    
                account = new Account();
                int id = rs.getInt("id");
                String name = rs.getString("name");
                double balance = rs.getDouble("balance");
                account.setBalance(balance);
                account.setId(id);
                account.setName(name);
                accounts.add(account);
            }
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            JdbcUtil.close(stmt,conn,rs);
        }
        return accounts;
    }

    public static void main(String[] args) {
    
    
        List<Account> all = new JdbcDemo2().findAll();
        for(Account a : all){
    
    
            System.out.println(a);
        }
    }
}

2 登录案例

public class JdbcDemo3 {
    
    
    public static void main(String[] args) {
    
    
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String username = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        boolean check = login(username, password);
        if(check){
    
    
            System.out.println("登录成功");
        }else{
    
    
            System.out.println("登录失败");
        }
    }
    public static boolean login(String username, String password){
    
    
        if(username == null || password == null){
    
    
            return false;
        }
        Connection connection = null;
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
    
    
            connection = JdbcUtil.getConnection();
            //注意参数两端都有单引号 因为他们是字符串
            String sql = "select * from user where username= ? and password= ? ";
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setString(1,username);
            preparedStatement.setString(2,password);
            resultSet = preparedStatement.executeQuery();
            return resultSet.next();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            JdbcUtil.close(preparedStatement,connection,resultSet);
        }
        return false;
    }
}

3 JDBC控制事务-转账案例

使用Connection对象来管理事务
执行操作之前开事务 置为false
事务结束之后提交事务
在catch里面回滚 catch捕获的异常范围要扩大 不能仅仅时sql异常

package jdbc;

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

public class JdbcDemo4 {
    
    
    public static void main(String[] args) {
    
    
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;
        try{
    
    
            conn = JdbcUtil.getConnection();
            conn.setAutoCommit(false);
            String sql1 = "update account set balance = balance - ? where id = ?";
            String sql2 = "update account set balance = balance + ? where id = ?";

            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            pstmt1.setDouble(1,500);
            pstmt2.setDouble(1,500);
            pstmt1.setInt(2,2);
            pstmt2.setInt(2,1);

            pstmt1.executeUpdate();
            pstmt2.executeUpdate();

            conn.commit();
        }catch(Exception e){
    
    //任何异常都要回滚 所有这里不只是sql异常
            try {
    
    
                if(conn != null) conn.rollback();
            } catch (SQLException ex) {
    
    
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
    
    
            if(pstmt2!=null){
    
    
                try {
    
    
                    pstmt2.close();
                } catch (SQLException e) {
    
    
                    e.printStackTrace();
                }
            }
            JdbcUtil.close(pstmt1,conn);
        }
    }
}

猜你喜欢

转载自blog.csdn.net/xd963625627/article/details/105509283