JDBC基础-各类作用+工具类抽取+事务管理

Posted Henrik-Yao

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JDBC基础-各类作用+工具类抽取+事务管理相关的知识,希望对你有一定的参考价值。

Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。

一.最简单的jdbc-demo及基本步骤

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

public class JdbcDemo {
    public static void main(String[] args) throws Exception {
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取数据连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/root?serverTimezone=UTC","root","123456");
        //定义sql语句
        String sql = "update user set password = '123' where id =1";
        //获取sql对象Statement
        Statement stmt = conn.createStatement();
        //执行sql
        stmt.executeUpdate(sql);
        //释放资源
        stmt.close();
        conn.close();
    }
}

二.JDBC各类作用及应用

1.DriverManager:驱动管理对象

DriverManage的主要作用是注册驱动,即告诉程序使用哪一个数据库驱动jar
从Driver的源码文件中可以看出其在静态代码块执行驱动注册

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//

package com.mysql.cj.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

    static {
        try {
            DriverManager.registerDriver(new Driver());
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }
}

DriverManage的第二个作用是获取数据库连接
通过getConnection(String url,String user, String password)方法获取数据库连接
参数包括:
url:指定连接的路径
user:用户名
password:密码

  • url语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
  • 例如jdbc:mysql://localhost:3306/root(root是我的一个数据库名称)
  • 由于我的时区有多个,所以传了一个参数(?serverTimezone=UTC)指定时区
  • 如果连接的是本地mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为jdbc:mysql:///root
    @CallerSensitive
    public static Connection getConnection(String url,
        String user, String password) throws SQLException {
        java.util.Properties info = new java.util.Properties();

        if (user != null) {
            info.put("user", user);
        }
        if (password != null) {
            info.put("password", password);
        }

        return (getConnection(url, info, Reflection.getCallerClass()));
    }

2.Connection:数据库连接对象

Connection的主要作用获取执行sql的对象并管理事务

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

3.Statement:执行sql的对象

可以形象的理解Connection的作用是建桥,建立Java和数据库的连接,Statement的作用是执行事务,形象理解为派个人过桥,提着篮子,去拿数据
实现代码:Statement stmt = conn.createStatement();

  • boolean execute(String sql):可以执行任意的sql
  • int executeUpdate:可以通过判断影响的行数判断sql语句是否执行成功

下面是一个简单的jdbc-demo,相比于上一个demo改进的地方在于定义了一个count来判断sql语句是否执行成功

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

public class JdbcDemo {
    public static void main(String[] args){
        Statement stmt = null;
        Connection conn = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String sql = "insert into user (username, password) values ('admin','789')";
            conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
            stmt = conn.createStatement();
            int count = stmt.executeUpdate(sql);
            if(count>0){
                System.out.println("添加成功");
            }else {
                System.out.println("添加失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException exception) {
            exception.printStackTrace();
        }finally {
            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException exception) {
                    exception.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException exception) {
                    exception.printStackTrace();
                }
            }
        }
    }
}

4.ResultSet:封装结果集对象,封装查询结果

  • next():游标向下移动一行
  • getXxx(参数):获取数据
  • Xxx代表数据类型
  • 参数:
  • 1.int代表列的编号,从1开始,如:getString(1);
  • 2.String代表列名称,如getDouble("")

下面是一个简单的jdbc-demo,相比于上一个demo,这个demo增加了一个ResultSet作为结果集接收sql执行结果

import javax.xml.transform.Result;
import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args){
        Statement stmt = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String sql = "select * from user ";
            conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            rs.next();
            int id = rs.getInt(1);
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id+"---"+username+"---"+password);

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

下面是一个简单的jdbc-demo,相比于上一个demo,这个demo增加了 while (rs.next())使得每条查询记录都能打印出来(上一个demo只能打印一条查询记录)

import javax.xml.transform.Result;
import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args){
        Statement stmt = null;
        Connection conn = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String sql = "select * from user ";
            conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            while (rs.next()){
                int id = rs.getInt(1);
                String username = rs.getString("username");
                String password = rs.getString("password");
                System.out.println(id+"---"+username+"---"+password);
            }

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

下面是一个简单的jdbc-demo,相比于上一个demo,这个demo增加了 user类,对于user表,将查询的数据封装为对象装载进入集合

public class User {
    private int id;
    private String username;
    private String password;

    public int getId() {
        return id;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\\'' +
                ", password='" + password + '\\'' +
                '}';
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

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

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

    public List<User> findAll(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        List<User> list = new ArrayList<User>();
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///root?serverTimezone=UTC","root","123456");
            String sql = "select * from user";
            stmt = conn.createStatement();
            rs = stmt.executeQuery(sql);
            while (rs.next()){
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                User user = new User();
                user.setId(id);
                user.setUsername(username);
                user.setPassword(password);
                list.add(user);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException exception) {
            exception.printStackTrace();
        }finally {
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException exception) {
                    exception.printStackTrace();
                }
            }
            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException exception) {
                    exception.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException exception) {
                    exception.printStackTrace();
                }
            }
        }
        return list;

    }

}

5.PreparedStatement:预防sql注入

详细的内容可以查看我的另一篇博文sql注入问题

三.抽取JDBC工具类:JDBCUtils

以上的代码重复度过高,所以我们需要抽取方法,简化书写,首先将一些惯用的常量放在配置文件druid.properties中

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/root?serverTimezone=UTC
username=root
password=123456

下面是工具类的书写,值得关注的是类加载器ClassLoader的使用

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
以上是关于JDBC基础-各类作用+工具类抽取+事务管理的主要内容,如果未能解决你的问题,请参考以下文章

JDBC基础

JDBC-02-笔记

JDBC工具类的抽取

JDBC——抽取工具类

抽取JDBC工具类并增删改查

抽取JDBC工具类