JAVA数据库操作——JDBC入门教程

本文章主要内容:

  • JDBC概述
  • JDBC入门
  • JDBC的API详解
  • JDBC的资源释放
  • JDBC的CURD操作
  • JDBC工具类的抽取
  • JDBC的PreparedStatement

正式进入正文

一、JDBC概述


JDBC:java database Connectcivity(java数据库连接)
JAVA数据库操作——JDBC入门教程_第1张图片

二、JDBC入门


使用java操作数据库的步骤:

  • 搭建开发环境
  • 编写程序,在程序中加载数据库驱动
  • 建立连接
  • 创建用于向数据库发送SQL的statement对象
  • 从代表结果集的ResultSet中取出数据
  • 断开与数据库的连接,并释放相关资源

下面是实例:
登录mysql
在这里插入图片描述
在mysql中建表

create database jdbctest;
use jdbctest;
create table user(
    uid int primary key auto_increment,
	username varchar(20),
	password varchar(20),
	name varchar(20)
);
insert into user values(null,'aaa','111','张三');
insert into user values(null,'bbb','222','李四');
insert into user values(null,'ccc','333','王五');

然后使用idea连接数据库:
IDEA使用JDBC连接MySQL数据库详细教程
https://blog.csdn.net/qq_36172505/article/details/84102468

编写代码

package com.jdbc.demo1;

import java.sql.*;

public class JDBCdemo1 {

    //JDBC的入门程序
    public void demo1(){

        try{
            //1.加载驱动
            //DriverManager.registerDriver(new Driver());//会导致驱动注册两次
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获得连接
            Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest?serverTimezone=GMT","root","123456");
            //3.创建sql语句,并且执行sql
            //3.1创建执行sql的对象
            String sql = "select * from user";
            Statement stmt = con.createStatement();
            //3.2执行sql
            ResultSet resultSet = stmt.executeQuery(sql);
            while(resultSet.next()){
                int uid = resultSet.getInt("uid");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                String name = resultSet.getString("name");

                System.out.println(uid+" "+username+" "+password+" "+name);
            }
            //4.释放资源
            resultSet.close();
            stmt.close();
            con.close();
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
        JDBCdemo1 demo1 = new JDBCdemo1();
        demo1.demo1();
    }
}

程序运行结果:
在这里插入图片描述

三、JDBC的API详解


DriverManager:驱动管理类

  • 主要作用:
    • 一、注册驱动
      • 实际开发中注册驱动使用如下的方式
        Class.forName(“Com.mysql.cj.jdbc.Driver”);
      • 因为之前的方式会导致驱动注册两次
    • 二、获得连接
      • connection getConnnection(String url,String username,String passsword);
        • url写法:jdbc:mysql://localhost:3306/jdbc
          • jdbc:协议
          • mysql:子协议
          • localhost:主机号
          • 3306:端口号
        • url简写:jdbc:mysql:///jdbc

Connetcion:连接驱动

  • 主要作用
    • 一、创建执行sql语句的对象
      Statement createStatement():执行sql语句,有sql注入的漏洞存在
      PreparedStatment prepareStatement(String sql): 预编译sql语句,解决sql注入的漏洞
      CallableStatement prepareCall(String sql): 执行sql中存储过程
    • 二、进行事务的管理
      setAutoCommit(boolean autoCommit) : 设置是否是否自动提交
      commit(): 事务提交
      rollback(): 事务回滚

Statement:执行sql语句

  • 主要作用
    • 一、执行sql语句
      boolean execute(String sql): 执行sql,执行select语句返回true,否则返回false
      ResultSet executeQuery(String sql): 执行sql中的select语句
      int executeUpdate(String sql): 执行sql中的insert/update/delete语句
    • 二、执行批处理操作
      addBatch(String sql): 添加到批处理
      executeBatch(): 执行批处理
      clearBatch():清空批处理

ResultSet:结果集

  • 结果集:其实就是查询(Select)语句查询的结果的封装
  • 主要作用:
    结果集获取查询到的结果
    next():针对不同的类型的数据可以使用getxxx()获取数据,通用的获取数据的方法:getObject();

四、JDBC的资源释放


  • jdbc程序运行完后,要释放程序在运行过程中,创建的那些与数据库进行交互的对象,这些对象通常是ResultSet,Statement和Connection对象
  • 特别是Connection对象,是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭,极易导致系统宕机,Connection的使用原则是尽量晚创建,尽量早释放

根据这样的原则我们重写连接数据库的代码:

package com.jdbc.demo1;
import java.sql.*;

public class JDBCdemo2 {

    //JDBC的入门程序
    public void demo1(){

        Connection con = null;
        Statement stmt = null;
        ResultSet resultSet = null;

        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest?serverTimezone=GMT","root","123456");
            String sql = "select * from user";
            stmt = con.createStatement();
            resultSet = stmt.executeQuery(sql);
            while(resultSet.next()){
                int uid = resultSet.getInt("uid");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                String name = resultSet.getString("name");

                System.out.println(uid+" "+username+" "+password+" "+name);
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            if (resultSet!=null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    resultSet = null;
                }
                resultSet = null;
            }

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

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

五、JDBC的CURD操作


  • 插入数据库中的记录
  • 修改
  • 删除
  • 查询

数据库中数据:
JAVA数据库操作——JDBC入门教程_第2张图片
增删改查的示例代码

package com.jdbc.demo1;

import java.sql.*;

public class JDBCdemo2 {

    //查询方法
    //查询一条记录
    public void demo5(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs =null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///jdbctest?serverTimezone=GMT","root","123456");
            stmt = conn.createStatement();
            String sql = "select * from user where uid = 2" ;
            rs = stmt.executeQuery(sql);//返回的int值代表影响的行数
            if (rs.next()){
                System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }

    //查询方法
    //查询所有记录
    public void demo4(){
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs =null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///jdbctest?serverTimezone=GMT","root","123456");
            stmt = conn.createStatement();
            String sql = "select * from user" ;
            rs = stmt.executeQuery(sql);//返回的int值代表影响的行数
            //遍历结果集
            while (rs.next()){
                System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (rs!=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                rs = null;
            }
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }

    //删除方法
    public void demo3(){
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///jdbctest?serverTimezone=GMT","root","123456");
            stmt = conn.createStatement();
            String sql = "delete from user where uid = 4" ;
            int i = stmt.executeUpdate(sql);//返回的int值代表影响的行数
            if (i>0) {
                System.out.println("删除成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }

    //修改方法
    public void demo2(){
        Connection conn = null;
        Statement stmt = null;
        try {
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获得连接
            conn = DriverManager.getConnection("jdbc:mysql:///jdbctest?serverTimezone=GMT","root","123456");
            //获得执行sql语句的对象
            stmt = conn.createStatement();
            //编写sql
            String sql = "update user set username = 'qqq',password='456',name = '赵六' where uid = 4" ;
            //执行sql
            int i = stmt.executeUpdate(sql);//返回的int值代表影响的行数
            if (i>0) {
                System.out.println("修改成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }

    //保存操作
    public void demo1(){
        Connection conn = null;
        Statement stmt= null;
        try{
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获得连接
            conn = DriverManager.getConnection("jdbc:mysql:///jdbctest?serverTimezone=GMT","root","123456");
            //获得执行sql语句的对象
            stmt = conn.createStatement();
            //编写sql
            String sql = "insert into user values (null,'eee','123','刘大')";
            //执行sql
            int i = stmt.executeUpdate(sql);
            if (i>0){
                System.out.println("保存成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //释放资源
            if (stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                stmt = null;
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                conn = null;
            }
        }
    }

    public static void main(String[] args) {
        JDBCdemo2 demo2 = new JDBCdemo2();
        demo2.demo5();
    }
}

六、JDBC工具类的抽取


上一节的不同方法中很多代码酒店重复的

  • 为了简化开发,可以将一些重复的代码进行提取,这里示范为一个新包里的新类JDBCUtils
  • JAVA数据库操作——JDBC入门教程_第3张图片
package com.jdbc.utils;

import java.sql.*;

/*
JDBC的工具类
 */
public class JDBCUtils {

    private static final String driverClass;
    private static final String url;
    private static final String username;
    private static final String password;

    static {
        driverClass = "com.mysql.cj.jdbc.Driver";
        url = "jdbc:mysql:///jdbctest?serverTimezone=GMT";
        username = "root";
        password = "123456";
    }


    /*
    注册驱动的方法
     */
    public static void loadDriver() throws ClassNotFoundException
    {
        Class.forName(driverClass);
    }

    /*
    获得连接的方法
     */
    public static Connection getConnection() throws Exception
    {
        loadDriver();
        Connection conn = DriverManager.getConnection(url,username,password);
        return conn;
    }

    /*
    资源释放
     */
    public static void release(Statement stmt,Connection conn)
    {
        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }

    public static void release(ResultSet rs,Statement stmt,Connection conn)
    {
        if (rs!=null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            stmt = null;
        }
        if (conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            conn = null;
        }
    }
}

现在我们写一个测试函数来测试我们的工具类

package com.jdbc.demo1;

import com.jdbc.utils.JDBCUtils;

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

public class JDBCdemo3 {

    //保存记录
    public void demo1(){
        Connection conn = null;
        Statement stmt = null;
        try{
            conn = JDBCUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "insert into user values (null,'fff','123','哈哈')";
            int num = stmt.executeUpdate(sql);
            if (num>0){
                System.out.println("保存成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(stmt,conn);
        }
    }

    public static void main(String[] args) {
        JDBCdemo3 demo3 = new JDBCdemo3();
        demo3.demo1();
    }
}

在这里插入图片描述
JAVA数据库操作——JDBC入门教程_第4张图片

七、JDBC的PreparedStatement


便于移植和编译,通常将数据库url,name,password等提取到一个配置文件里,需要的时候从配置文件里解析。一般使用属性文件表示。
在这里插入图片描述
JAVA数据库操作——JDBC入门教程_第5张图片

package com.jdbc.utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/*
JDBC的工具类
 */
public class JDBCUtils {

    private static final String driverClass;
    private static final String url;
    private static final String username;
    private static final String password;

    static {
        //加载属性文件并解析:
        Properties props = new Properties();
        //如何获得属性文件的输入流
        //通常使用类的加载器的方式进行获取:
        InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
        try {
            props.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }

        driverClass = props.getProperty("driverClass");
        url = props.getProperty("url");
        username = props.getProperty("username");
        password = props.getProperty("password");
    }
    //后面不变
}

JDBC的SQL注入漏洞


package com.jdbc.demo2;

import com.jdbc.utils.JDBCUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

//演示JDBC的注入的漏洞
public class JDBCdemo4 {

    //测试sql注入漏洞的方法
    public void demo1(){
        boolean flag = JDBCdemo4.login("aaa","111");
        if (flag == true)
            System.out.println("登录成功!");
        else
            System.out.println("登陆失败!");
    }

    public static boolean login(String username, String password) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        boolean flag = false;
        try {
            conn = JDBCUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "select * from user where username = '" + username + " 'and password = '" + password + "'";
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                flag = true;
            } else {
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(stmt, conn);
        }
        return flag;
    }

    public static void main(String[] args) {
        JDBCdemo4 demo4 = new JDBCdemo4();
        demo4.demo1();
    }
}

在这里插入图片描述
如果我们修改用户名,再瞎写一个密码,可以看到,都登录成功了。
JAVA数据库操作——JDBC入门教程_第6张图片
JAVA数据库操作——JDBC入门教程_第7张图片
为什么有这种情况?这就是sql注入的漏洞的产生,产生的原因就是我们在输入用户名的时候输入了sql的一个关键字

sql注入漏洞的解决


JAVA数据库操作——JDBC入门教程_第8张图片
不使用statment。使用preparedStatment

package com.jdbc.demo2;

import com.jdbc.utils.JDBCUtils;

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

//演示JDBC的注入的漏洞
public class JDBCdemo4 {

    //测试sql注入漏洞的方法
    public void demo1(){
        boolean flag = JDBCdemo4.login2("aaa","111");
        if (flag == true)
            System.out.println("登录成功!");
        else
            System.out.println("登陆失败!");
    }

    //避免sql注入漏洞的方法
    public static boolean login2(String username, String password) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        boolean flag = false;
        try {
            //获得连接
            conn = JDBCUtils.getConnection();
            //编写sql
            String sql = "select * from user where username = ? and password = ?";
            //预处理sql
            pstmt = conn.prepareStatement(sql);
            //设置参数
            pstmt.setString(1,username);
            pstmt.setString(2,password);
            //执行sql语句
            rs = pstmt.executeQuery();
            if (rs.next()) {
                flag = true;
            } else {
                flag = false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JDBCUtils.release(pstmt, conn);
        }
        return flag;
    }
    public static void main(String[] args) {
        JDBCdemo4 demo4 = new JDBCdemo4();
        demo4.demo1();
    }
}

使用PreparedStatement

PreparedStatement的使用

使用PreparedStatement完成的增删改查代码

package com.jdbc.demo2;

//preparedStatment的使用

import com.jdbc.demo1.JDBCdemo2;
import com.jdbc.utils.JDBCUtils;

import java.sql.*;

public class JDBCdemo5 {

    //查询方法
    //查询一条记录
    public void demo5(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtils.getConnection();
            String sql = "select * from user where uid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setObject(1,2);
            rs = pstmt.executeQuery();
            while (rs.next()){
                System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(rs,pstmt,conn);
        }
    }

    //查询方法
    //查询所有记录
    public void demo4(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            conn = JDBCUtils.getConnection();
            String sql = "select * from user";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while (rs.next()){
                System.out.println(rs.getInt("uid")+" "+rs.getString("username")+" "+rs.getString("password")+" "+rs.getString("name"));
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(rs,pstmt,conn);
        }
    }

    //删除方法
    public void demo3(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        try{
            conn = JDBCUtils.getConnection();
            String sql = "delete from user where uid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,6);
            int num = pstmt.executeUpdate();
            if (num>0){
                System.out.println("删除成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(pstmt,conn);
        }
    }

    //修改方法
    public void demo2(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        try{
            conn = JDBCUtils.getConnection();
            String sql = "update user set username = ?,password = ? ,name = ? where uid = ?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"www");
            pstmt.setString(2,"123456");
            pstmt.setString(3,"张六");
            pstmt.setInt(4,6);
            int num = pstmt.executeUpdate();
            if (num>0){
                System.out.println("修改成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(pstmt,conn);
        }
    }

    //保存操作
    public void demo1(){
        Connection conn = null;
        PreparedStatement pstmt = null;
        try{
            conn = JDBCUtils.getConnection();
            String sql = "insert into user values (null,?,?,?)";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"qqq");
            pstmt.setString(2,"123");
            pstmt.setString(3,"张五");
            int num = pstmt.executeUpdate();
            if (num>0){
                System.out.println("保存成功!");
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            JDBCUtils.release(pstmt,conn);
        }
    }

    public static void main(String[] args) {
        JDBCdemo5 demo5 = new JDBCdemo5();
        demo5.demo5();
    }
}

数据库连接池


  • 连接池是创建和管理一个连接的缓冲池的技术,这些连接准备好被任何需要它们的线程使用
    JAVA数据库操作——JDBC入门教程_第9张图片
    JAVA数据库操作——JDBC入门教程_第10张图片

你可能感兴趣的:(java,JDBC,数据库)