一,概述和下载

之前我是通过控制台和mysql可视化工具来操作数据库,而JDBC 是 Java 访问数据库的标准规范,通过它,我可以用java程序来访问数据库.

使用它之前,需要先去官网下载jar包:

https://dev.mysql.com/downloads/file/?id=494900 然后按照下图导入包:

java连接pgsql的角色用户 java连接sql数据库代码_java连接pgsql的角色用户

值得注意的是mysql版本是8.0.x的话,jar也得下载8.0.x版本的jar包.不然会报错.

二,DriverManager类得到连接对象connection

driverManager类主要用来创建数据库连接,如下代码就是取到了数据库的连接:

public class Demo1 {
    public static void main(String[] args) throws SQLException {
        String url = "jdbc:mysql://localhost:3306/db2";
        Connection connection = DriverManager.getConnection(url, "root", "Huan100861!");
        //com.mysql.jdbc.JDBC4Connection@68de145
        System.out.println(connection);
    }
}

ur的解析:

java连接pgsql的角色用户 java连接sql数据库代码_System_02

三,statement对象执行sql语句

获取到connnection对象后,可以进而获取到statement对象,它用来执行sql语句:

java连接pgsql的角色用户 java连接sql数据库代码_java连接pgsql的角色用户_03

创建表:
//1,创建连接
Connection conn=null;
Statement statement =null;
try{
    conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/db2","root","123");
    //2,通过连接对象得到语句对象
    statement =conn.createStatement();
    //3,通过语句对象发送sql语句给服务器
    //4,执行sql
    statement.executeUpdate("create table student(id int primary key auto_increment," +
            "name varchar(20) not null,gender boolean,birthday date)");
    System.out.println("创建表成功");
}catch(SQLException e)  {
    e.printStackTrace();
}
新增表内容:
//1,创建连接对象
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/db2","root","123");
//2,创建statement语句对象
Statement statement=connection.createStatement();
//3,执行sql语句:executeUpdate(sql)
int count=0;
count+=statement.executeUpdate("insert into student values(null,'孙悟空',1,'2024-03-24')");
count+=statement.executeUpdate("insert into student values(null,'白骨精',0,'2024-03-25')");
count+=statement.executeUpdate("insert into student values(null,'猪八戒',1,'2024-03-26')");
count+=statement.executeUpdate("insert into student values(null,'嫦娥',0,'2024-03-27')");
System.out.println("插入了"+count+"条记录");
查询表内容:
//1,得到连接对象
Connection connection= DriverManager.getConnection("jdbc:mysql://localhost:3306/db2","root","123");
//得到statement对象
Statement statement=connection.createStatement();
ResultSet res=statement.executeQuery("select * from student");
System.out.println(res);
while(res.next()){
    int id=res.getInt("id");
    String name=res.getString("name");
    boolean gender=res.getBoolean("gender");
    Date birthday=res.getDate("birthday");
    System.out.println(id+'+'+name+'+'+gender+'+'+birthday);
}
四,关闭资源连接

需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接

释放原则:先开的后关,后开的先关。ResultSet  Statement  Connection

放在哪个代码块中:finally 块

try {
     res.close();
     statement.close();
     connection.close();
 } catch (SQLException e) {
     throw new RuntimeException(e);
 }

五,数据库工具类 JdbcUtils

上文我们写了很多重复的代码,包括创建连接,取得statement对象,还有连接的关闭等,都可以抽离出来,封装成一个单独的类.

package com.itheima.utils;

import java.sql.*;

//访问数据库的工具类
public class JdbcUtils {
    //可以把几个字符串定义成常量:用户名,密码,URL,驱动类
    private static final String USER = "root";
    private static final String PWD = "123";
    private static final String URL = "jdbc:mysql://localhost:3306/db2";

    //得到数据库连接
    public static Connection getConnection() throws SQLException{
        return DriverManager.getConnection(URL,USER,PWD);
    }
    //关闭所有打开的资源-连接和语句
    public static void close(Connection conn, Statement stmt){
        //关闭之前要判断
        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(Connection conn, Statement stmt, ResultSet rs){
        if(rs!=null){
            try{
                rs.close();
            }catch(SQLException e){
                e.printStackTrace();
            }
        }
        close(conn,stmt);
    }
}

使用的示例,用户登录. 这里先准备数据:

create table user (
 id int primary key auto_increment,
 name varchar(20),
 password varchar(20)
)
insert into user values (null,'jack','123'),(null,'rose','456');

然后编写登录登录类:

package com.itheima;

import com.itheima.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Demo7Login {
    //从控制台上输入用户名和方法
    public  static void main (String[] args){
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String name=sc.nextLine();
        System.out.println("请输入密码:");
        String password=sc.nextLine();
        login(name,password);
    }
    //登录的方法
    public static void login(String name,String password){
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        try{
            connection= JdbcUtils.getConnection();
            statement=connection.createStatement();
            String sql="select * from user where name='"+name+"' and password='"+password+"';";
            System.out.println(sql);
            rs=statement.executeQuery(sql);
            if (rs.next()) {
                System.out.println("登录成功,欢迎您:" + name);
            } else {
                System.out.println("登录失败");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            //d) 释放资源
            JdbcUtils.close(connection, statement, rs);
        }
    }
}

但是这种写法,我们是简单地拼接sql语句,会带来sql注入的漏洞.

请输入用户名:
newboy
请输入密码:
a' or '1'='1
select * from user where name='newboy' and password='a' or '1'='1'

当我们输入这个密码时,居然也能登录成功.这是因为这条sql语句的where后变成了true,所以返回了全表. 为了避免这一个问题,就从statement接口处继承了PreparedSatement 接口,由它来操作数据库.

六,使用PreparedSatement 来执行sql

这样一来,就能避免直接拼接sql带来的sql注入的问题:

package com.itheima;

import com.itheima.utils.JdbcUtils;

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

public class Demo8Login {
    //从控制台上输入用户名和方法
    public  static void main (String[] args){
        Scanner sc=new Scanner(System.in);
        System.out.println("请输入用户名:");
        String name=sc.nextLine();
        System.out.println("请输入密码:");
        String password=sc.nextLine();
        login(name,password);
    }
    //登录的方法
    public static void login(String name,String password) {
        Connection connection = null;
        PreparedStatement ps = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection();
            String sql = "select * from user where name=? and password=?";
            ps = connection.prepareStatement(sql);
            ps.setString(1, name);
            ps.setString(2, password);//替换?
            resultSet = ps.executeQuery();
            if (resultSet.next()) {
                System.out.println("登录成功,欢迎您:" + name);
            } else {
                System.out.println("登录失败");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //d) 释放资源
            JdbcUtils.close(connection, ps, resultSet);
        }
    }
}

七,事务的jdbc处理

之前学过,事务的关键就是要开启事务,并且事务可以回滚.

package com.itheima;

import com.itheima.utils.JdbcUtils;

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

public class Demo12Transaction {
    //没有异常,提交事务,出现异常回滚事务
    public static void main(String[] args) {
        //1) 注册驱动
        Connection connection = null;
        PreparedStatement ps = null;
        try {
            //2) 获取连接
            connection = JdbcUtils.getConnection();
            //3) 开启事务
            connection.setAutoCommit(false);
            //4) 获取到 PreparedStatement
            //从 jack 扣钱
            ps = connection.prepareStatement("update account set balance = balance - ? where name=?");
            ps.setInt(1, 500);
            ps.setString(2,"Jack");
            ps.executeUpdate();
            //出现异常
            System.out.println(100 / 0);
            //给 rose 加钱
            ps = connection.prepareStatement("update account set balance = balance + ? where=name=?");
            ps.setInt(1, 500);
            ps.setString(2,"Rose");
            ps.executeUpdate();
            //提交事务
            connection.commit();
            System.out.println("转账成功");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                //事务的回滚
                connection.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
            System.out.println("转账失败");
        }
        finally {
            //7) 关闭资源
            JdbcUtils.close(connection,ps);
        }
    }
}

从这里来看的话,就是connection.setAutoCommit(false);false表示关闭事务自动提交,也就是开启手动事务的意思.后续要提交则connection.commit();,要回滚则connection.rollback();