JavaSE-数据库(JDBC)

1- JDBC概念

Java DataBase Connectivity 是Java的数据库连接技术,它是一组接口。使用Java编程来访问各种数据库。

2-JDBC特点

由一组接口组成,代码针对接口进行编程的。不需要自己去实现接口,这些接口的实现类由第三方数据库厂商来实现。

3- JDBC访问数据库

3.1 创建JDBC工程

  1. 创建普通的Java工程.
  2. 将普通的Java项目转换成Maven项目
  3. 倒入相关依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>cn.guardwhy</groupId>
    <artifactId>JDBC</artifactId>
    <version>1.0-SNAPSHOT</version>
    <packaging>jar</packaging>
    <dependencies>
        <!--mysql的驱动-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.30</version>
        </dependency>
        <!--单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--lombok插件-->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.16</version>
        </dependency>
    </dependencies>

    <!--在build中配置resources,来防止我们资源导出失败的问题-->
    <build>
        <resources>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.properties</include>
                    <include>**/*.xml</include>
                </includes>
                <filtering>true</filtering>
            </resource>
        </resources>
    </build>
</project>

3.2 访问数据库步骤

  1. 通过DriverManager创建连接对象。

  2. 创建好连接对象以后, 由客户端通过Statement发送SQL语句给MySQL服务器。

  3. 在数据库服务器端执行SQL语句

  4. 将执行的结果以ResultSet返回给客户端

4-访问数据库类

4.1 注册驱动

  • JDBC规范定义驱动接口: java.sql.Driver
  • MySql驱动包提供了实现类: com.mysql.jdbc.Driver
加载注册驱动的方式 描述
Class.forName(数据库驱动实现类) 加载和注册数据库驱动,数据库驱动由数据库厂商MySql提供
"com.mysql.jdbc.Driver"

1)代码示例

public class JDBCDemo01 {
	public static void main(String[] args) throws ClassNotFoundException {
    // 注册驱动
    // forName 方法执行将类进行初始化
    Class.forName("com.mysql.jdbc.Driver");
    }
}

4.2 获得连接

  • Connection 接口,代表一个连接对象 ,具体的实现类由数据库的厂商实现。
  • 使用 DriverManager类的静态方法,getConnection可以获取数据库的连接
获取连接的静态方法 作用
Connection getConnection(String url, String user, String password) 通过连接字符串和用户名,密码来获取数据库连接对象。

4.2.1 连接参数

1)DriverManager类

注册驱动,从JDK1.5版本以后就会自动注册了。创建数据库连接

JDBC连接数据库的四个参数 具体作用
username 登录用户名
password 登录密码
连接字符串URL URL的格式: jdbc:mysql://localhost:3306/db_jdbc

JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。

  • 第一部分是协议 jdbc,这是固定的。
  • 第二部分是子协议,就是数据库名称,连接mysql数据库,第二部分当然是mysql了。
  • 第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分。分别由数据库服务器的IP地址(localhost)、端口号(3306),以及要使用的 数据库名称 组成。

    2) URL参数的作用

如:乱码的处理,如果数据库出现乱码,可以指定参数 ?characterEncoding=utf8,表示让数据库以UTF-8编码来处理数据。

jdbc:mysql://localhost:3306/数据库名?characterEncoding=utf8

如果服务器是本地,端口号是默认的3306,可以简写:

jdbc:mysql:///数据库名

4.2.2 得到连接对象

package cn.guardwhy_01;
/**
 * 得到数据库连接对象
 */
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class JDBCDemo01 {

    public static void main(String[] args) throws Exception {
        String url = "jdbc:mysql://localhost:3306/db_jdbc";
        /**
         * 方式一:使用用户名、密码、url得到连接对象
         */
        Connection connection1 = DriverManager.getConnection(url, "root", "root");
        // 实现Connection接口的子类对象
        System.out.println("数据库连接对象:" + connection1);

        /**
         * 方式二:使用属性文件和url得到连接对象
         */
        Properties properties = new Properties();
        properties.setProperty("user", "root");
        properties.setProperty("password", "root");
        // 2.实现connection接口
        Connection connection2 = DriverManager.getConnection(url, properties);
        System.out.println("数据库连接对象:" + connection2);
    }
}

4.3 获取语句执行平台

4.3.1 Connection接口

  • 通过Connection 的 createStatement方法 获取sql语句执行对象。
Connection接口中的方法 描述
Statement createStatement() 创建一个SQL语句对象

4.3.2 Statement接口

  • Statement : 代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
Statement接口中的方法 描述
boolean execute(String sql) 作用:执行可以任意的SQL语句,通常用于执行DDL语句
返回值:如果第一个结果为 ResultSet 对象,则返回 true;如果其为更新计数或者不存在任何结果,则返回false。
int executeUpdate(String sql) 作用:用于执行增删改。返回值:表中影响的行数
ResultSet executeQuery(String sql) 作用:用于执行查询操作。返回值:查询到的结果集

1) SQL语句

-- 创建jdbc_user表
CREATE TABLE jdbc_user (
	id INT PRIMARY KEY AUTO_INCREMENT ,
	username VARCHAR(50),
	PASSWORD VARCHAR(50),
	birthday DATE
);
-- 添加数据
insert into jdbc_user (username, PASSWORD, birthday) values
('Curry', '123', '2001/1/02'),
('Kobe', '456', '1991/10/14'),
('James', '6666', '1987/11/24'),
('Hardon', '6666', '1987/3/24');

select * from jdbc_user;

2)代码示例

package cn.guardwhy.demo01;

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

public class JdbcDemo02 {
    public static void main(String[] args) throws Exception {
        // 1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.获取连接url,用户名,密码
        String url = "jdbc:mysql://localhost:3306/db_jdbc";
        Connection con = DriverManager.getConnection(url, "root", "root");
        // 3.获取Statement对象
        Statement statement = con.createStatement();
        // 4.执行创建表操作
        String sql = "create table jdbc02(id int, name varchar(20),age int)";
        // 5.增删改操作,增加一张表
        int i = statement.executeUpdate(sql);
        // 6.输出结果
        System.out.println(i);
        // 7.关闭流操作
        statement.close();
        con.close();
    }
}

4.3.3 ResultSet接口

作用:封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。

ResultSet接口中的方法 描述
boolean next() 1. 指针向下移动一行
2. 返回boolean,如果返回true表示当前行有数据,false表示结束了。
数据类型 get数据类型(参数) 1) 通过列名,参数是 String 类型。返回不同的类型。
2) 通过列号,参数是整数,从 1 开始。返回不同的类型。

1)代码示例

package cn.guardwhy.demo01;

import java.sql.*;

public class JdbcDemo03 {
    public static void main(String[] args) throws Exception {
        // 1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2.获取连接url,用户名,密码
        String url = "jdbc:mysql://localhost:3306/db_jdbc";
        Connection con = DriverManager.getConnection(url, "root", "root");
        // 3.获取Statement对象
        Statement statement = con.createStatement();
        String sql = "select * from jdbc_user";
        // 4.执行查询操作,返回结果集对象
        ResultSet resultSet = statement.executeQuery(sql);
        // 5.使用while循环
        while (resultSet.next()){
            // 5.1 获取id
            int id = resultSet.getInt("id");
            // 5.2 获取username
            String username = resultSet.getString("username");
            // 5.3 获取birthday
            Date birthday = resultSet.getDate("birthday");

            // 输出结果
            System.out.println("编号: " + id + ", 用户名:" + username + ", 生日:" + birthday);
        }

        // 6.关闭连接对象
        resultSet.close();
        statement.close();
        con.close();
    }
}

4.3.4 释放资源

  1. 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
  2. 释放原则:先开的后关,后开的先关。ResultSet ==> Statement ==> Connection
  3. 与IO流一样,使用后的东西都需要关闭!关闭的顺序是先开后关, 先得到的后关闭,后得到的先关闭。

4) 代码示例

package cn.guardwhy.demo01;

import java.sql.*;

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

        Connection con = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            // 2.获取连接url,用户名,密码
            String url = "jdbc:mysql://localhost:3306/db_jdbc";
            con = DriverManager.getConnection(url, "root", "root");
            // 3.获取Statement对象
            statement = con.createStatement();
            String sql = "select * from jdbc_user";
            // 4.执行查询操作,返回结果集对象
             resultSet = statement.executeQuery(sql);
            // 5.使用while循环
            while (resultSet.next()){
                // 5.1 获取id
                int id = resultSet.getInt("id");
                // 5.2 获取username
                String username = resultSet.getString("username");
                // 5.3 获取birthday
                Date birthday = resultSet.getDate("birthday");

                // 输出结果
                System.out.println("编号: " + id + ", 用户名:" + 
                username + ", 生日:" + birthday);
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            // 6.关闭连接对象
            try {
                resultSet.close();
                statement.close();
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

5) 执行结果

5-数据库操作(Java)

5.1 Jdbc工具类

package cn.guardwhy.utils;

import java.sql.*;

/*
* jdbc工具类
*/
public class JDBCUtils {
    //1. 定义字符串常量, 获取连接所需要的信息
    public static final String DRIVERNAME = "com.mysql.jdbc.Driver";
    public static final String URL = "jdbc:mysql://localhost:3306/db_jdbc?
    characterEncoding=UTF-8";
    public static final String USERNAME = "root";
    public static final String PASSWORD = "root";

    // 2.注册加载驱动
    static {
        // 2.1 注册驱动
        try {
            Class.forName(DRIVERNAME);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    // 3.获取连接对象
    public static Connection getConnection(){
        try {
            // 3.1获取连接对象
            Connection connection = DriverManager.getConnection(URL, USERNAME, PASSWORD);
            // 3.2 返回连接对象
            return connection;
        } catch (SQLException e) {
            e.printStackTrace();
            return null;
        }
    }
    // 4.关闭连接对象
    public static void close(Connection connection, Statement  statement){
        // 4.1 判断语句对象是否为空
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            // 4.2 判断语句连接对象是否为空
            if(connection != null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    // 5.关闭连接等对象
    public static void close(Connection connection, Statement statement,
                             ResultSet rs) {
        // 5.1判断结果集是否为空
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        close(connection, statement);
    }
}

5.1 执行DDL操作

1)代码示例

package cn.guardwhy.demo01;

import cn.guardwhy.utils.JDBCUtils;

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

public class JdbcDemo05 {
    public static void main(String[] args) {
        // 1.创建数据表
        String sql = "create table student ( id int primary key auto_increment, " +
                "name varchar(20) not null," +
                "sex boolean, " +
                "birthday date)";
        try {
            // 2.创建数据库连接
            Connection connection = JDBCUtils.getConnection();
            // 3.通过连接对象创建语句对象
            Statement statement = connection.createStatement();
            // 4.通过语句对象执行DDL
            statement.execute(sql);
            System.out.println("创建表成功...");
        } catch (SQLException e) {
            // 关闭语句和连接对象
            e.printStackTrace();
            System.out.println("创建数据表失败...");
        }
    }
}

5.2 执行DML操作

增删改使用statement接口中的executeUpdate( )方法。

1) 代码示例

package cn.guardwhy.demo01;
/**
 * JDBC:执行DML操作
 */
import cn.guardwhy.utils.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
public class JdbcDemo06 {

    @Test
    // 向学生表添加4条记录
    public void insert()throws SQLException {
        // 1.创建数据库连接对象
        Connection connection = JDBCUtils.getConnection();
        // 2.通过连接对象获得语句对象
        Statement statement = connection.createStatement();
        // 3.执行增删操作
        int row = statement.executeUpdate("insert into student (name,sex,birthday) 
        values ('侯大利',1,'1999-2-10')," +
                "('田甜',1,'1999-5-10'),
                ('杨红',1,'1999-2-10'),
                ('张晓',1,'1999-2-10')");
        // 4.输出影响的行数
        System.out.println("添加了" + row + "行记录");

        // 5.关闭资源
        JDBCUtils.close(connection, statement);
    }

    @Test
    // 更新其中1条记录
    public void update() throws SQLException{
        // 1.创建数据库连接对象
        Connection connection = JDBCUtils.getConnection();
        // 2.通过连接对象得到语句对象
        Statement statement = connection.createStatement();
        // 3.执行修改操作
        int row = statement.executeUpdate("update student set name='宁玲', 
        sex=0, birthday='1996-04-12'where id = 3");
        // 4.输出影响的行数
        System.out.println("更新了" + row + "行的数据");
        // 5.释放资源
        JDBCUtils.close(connection, statement);
    }

    @Test
    // 删除其中1条记录
    public void delete() throws SQLException{
        // 1.创建数据库连接对象
        Connection connection = JDBCUtils.getConnection();
        // 2.通过连接对象得到语句对象
        Statement statement = connection.createStatement();
        // 3.执行修改操作
        int row = statement.executeUpdate("delete from student where id = 4");
        // 4.输出影响的行数
        System.out.println("删除" + row + "行的数据");
        // 5.释放资源
        JDBCUtils.close(connection, statement);
    }
}

5.3 执行DQL操作

1) 代码示例

package cn.guardwhy.demo01;

import cn.guardwhy.utils.JDBCUtils;

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

/**
 * 查询学生表中的所有记录,并且输出
 */
public class JdbcDemo07 {
    public static void main(String[] args) throws SQLException {
        // 1.创建连接
        Connection connection = JDBCUtils.getConnection();
        // 2.通过连接对象得到语句对象
        Statement statement = connection.createStatement();
        // 3.通过语句对象执行sql语句,返回结果集
        ResultSet rs = statement.executeQuery("select * from student");
        // 4.遍历结果集
        while(rs.next()){
            int id = rs.getInt(1);
            String name = rs.getString(2);
            boolean sex = rs.getBoolean(3);
            Date birthday = rs.getDate(4);
            // 输出结果
            System.out.println("编号:" + id + ",姓名:" + name + ",
             性别:" + (sex? "男":"女") + ", 生日:" + birthday);
        }
        // 5.释放资源
        JDBCUtils.close(connection, statement, rs);
    }
}

2)执行结果

6- 预处理对象

6.1 PreparedStatement接口

  • PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句对象。
  • 预编译: 是指SQL 语句被预编译,并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

6.2 执行原理

1) 代码示例

package cn.guardwhy.demo02;

import cn.guardwhy.utils.JDBCUtils;

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

public class JdbcDemo01 {
    public static void main(String[] args) throws SQLException {
        // 1.创建连接对象
        Connection con = JDBCUtils.getConnection();
        // 2.执行Sql语句执行对象
        Statement st = con.createStatement();
        // 3.插入数据
        st.executeUpdate("insert into jdbc_user values
        (null,'侯大力','xyxwer123','1992/12/26')");
        st.executeUpdate("insert into jdbc_user values
        (null,'张小欣','wazg456','1995/2/21')");

        // 4.获取预处理对象
        PreparedStatement pst = con.prepareStatement
        ("insert into jdbc_user values(?,?,?,?)");
        // 5.插入数据
        pst.setString(1,null);
        pst.setString(2,"田甜");
        pst.setString(3,"tt134567");
        pst.setString(4,"1993/4/10");
        pst.executeUpdate();

        pst.setString(1,null);
        pst.setString(2,"杨帆");
        pst.setString(3,"yf223");
        pst.setString(4,"1991/5/1");
        pst.executeUpdate();

        // 6.释放资源
        st.close();
        pst.close();
        con.close();
    }
}

2)原理图

6.3 对比Statement接口

  1. 有预编译的功能,执行效率更高
  2. 更加安全性,没有SQL语句字符串拼接操作。没有SQL注入的安全隐患。
  3. 代码的可读性更强。需要使用set方法来替换占位符为真实的值。

6.4 获取PreparedStatement对象

  • 通过Connection创建PreparedStatement对象
Connection接口中的方法 描述
PreparedStatement prepareStatement(String sql) 创建语句对象并且提交预编译的SQL语句

6.5 PreparedStatement接口常用方法

PreparedStatement接口中的方法 描述
int executeUpdate() 执行增删改,不需要提供SQL语句
ResultSet executeQuery( ) 执行查询,不需要提供SQL语句

6.6 使用PreparedStatement的步骤

  1. 编写 SQL 语句,未知内容使用?占位
"SELECT * FROM jdbc_user WHERE username=? AND password=?";
  1. 获得 PreparedStatement 对象
  2. 设置实际参数:setXxx( 占位符的位置, 真实的值)
  3. 执行参数化 SQL 语句
  4. 关闭资源
setXxx重载方法 说明
void setDouble(int parameterIndex, double x) 将指定参数设置为给定 Java double 值。
void setInt(int parameterIndex, int x) 将指定参数设置为给定 Java int 值。
void setString(int parameterIndex, String x) 将指定参数设置为给定 Java String 值。
void setObject(int parameterIndex, Object x) 使用给定对象设置指定参数的值。

6.7 执行DML操作

package cn.guardwhy_04;

import cn.Utils.JdbcUtils;
import org.junit.Test;

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

/**
 使用PreparedStatement实现增删改操作
 */
public class PreparedStatementDemo01 {
    @Test
    public void insert() throws SQLException{
        // 1.得到连接对象
        Connection connection = JdbcUtils.getConnection();
        // 2.通过连接对象创建预编译语句,提供占位符的SQL语句
        PreparedStatement ps = connection.prepareStatement
        ("insert into student values(null,?,?,?)");
        // 3.替换占位符
        ps.setString(1, "丁浩");
        ps.setBoolean(2, false);
        ps.setDate(3, Date.valueOf("1991-03-22"));
        // 4.执行增删改操作
        int row = ps.executeUpdate();
        // 5.返回影响的行数
        System.out.println("添加了" + row + "行记录");
        // 6.释放资源
        JdbcUtils.close(connection, ps);
    }

    @Test
    public void update() throws SQLException{
        // 1.得到连接对象
        Connection connection = JdbcUtils.getConnection();
        // 2.通过连接对象创建预编译语句,提供占位符的SQL语句
        PreparedStatement ps = connection.prepareStatement
        ("update student set name=?, birthday=? where id=?");
        // 3.替换占位符
        ps.setString(1, "葛向东");
        ps.setDate(2, Date.valueOf("1986-03-12"));
        ps.setInt(3, 2);
        // 4.执行增删改操作
        int row = ps.executeUpdate();
        // 5.返回影响的行数
        System.out.println("更新了" + row + "行记录");
        // 6.释放资源
        JdbcUtils.close(connection, ps);
    }

    @Test
    public void delete() throws SQLException{
        // 1.得到连接对象
        Connection connection = JdbcUtils.getConnection();
        // 2.通过连接对象创建预编译语句,提供占位符的SQL语句
        PreparedStatement ps = connection.prepareStatement
        ("delete from student where id = ?");
        // 3.替换占位符
        ps.setInt(1, 1);
        // 4.执行增删改操作
        int row = ps.executeUpdate();
        // 5.返回影响的行数
        System.out.println("删除了" + row + "行记录");
        // 6.释放资源
        JdbcUtils.close(connection, ps);
    }
}

6.8 执行DQL封装成集合

需求:查询所有的学生类,封装成List<Student>返回。

1) 表与类之间的关系

  • 如果查询的结果集只有一条记录,封装成一个Student对象。(实体类:封装数据)

  • 如果有多个记录,封装成List<Student>对象

2) ORM 对象关系映射

  1. 类对应表结构
  2. 对象对象表中记录
  3. 成员变量对应字段名字

3) 实体类

package cn.guardwhy.demo03;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/*
学生实体类
*/
import java.util.Date;

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
    private int id;
    private String name;
    private boolean sex;
    private Date birthday;
}

4) 需求实现

package cn.guardwhy_04;

import cn.Enty.Student;
import cn.Utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class JDBCList01 {
    public static void main(String[] args) throws SQLException{
        // 1.创建stus集合对象
        List<Student> stus = new ArrayList<>();
        // 2.创建连接对象
        Connection connection = JdbcUtils.getConnection();
        // 3.得到预编译的语句对象
        PreparedStatement ps = connection.prepareStatement("select * from student");
        // 4.查询得到结果集
        ResultSet rs = ps.executeQuery();
        // 5.遍历结果集,将每条记录封装成一个Student对象
        while (rs.next()){
            Student stu = new Student();
            // 封装所有属性
            stu.setId(rs.getInt("id"));
            stu.setName(rs.getString("name"));
            stu.setSex(rs.getBoolean("sex"));
            stu.setBirthday(rs.getDate("birthday"));
            // 将stu添加到List中
            stus.add(stu);
        }
        // 6.释放资源
        JdbcUtils.close(connection, ps, rs);
        // 7.输出list集合
        stus.forEach(System.out::println);
    }
}

5) 执行结果

6.9 释放资源

每次访问数据库结束,都需要释放资源。

  1. 需要释放的对象:结果集,语句对象,连接对象
  2. 释放顺序:先开的后关,后开的先关。关闭顺序:ResultSet --> Statement -> Connection。

7- JDBC控制事务

7.1 事务相关API

使用JDBC来处理事务:实现银行转账的操作

Connection接口中与事务有关的方法 说明
void setAutoCommit(boolean autoCommit) 参数是 true 或 false 如果设置为 false,表示关闭自动提交,相当于开启事务。
void commit() 提交事务
void rollback() 回滚事务

7.2 SQL数据

-- 创建数据表
CREATE TABLE account (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(10),  -- 名字
    balance DOUBLE  -- 余额
);
 
-- 添加数据
INSERT INTO account (name, balance) VALUES ('Jack', 1000), ('Rose', 1000);
select * from account;

7.3 事务代码

package cn.guardwhy_03;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import cn.Utils.JdbcUtils;

public class TransactionDemo02 {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        try {
            //1.得到连接对象
            connection = JdbcUtils.getConnection();
            // 2.开启事务
            connection.setAutoCommit(false);
            //3.得到语句对象
            statement = connection.createStatement();
            //4.执行更新操作2次,扣钱,加钱
            statement.executeUpdate
            ("update account set balance = balance - 500 where name='Jack'");
            // 模拟代码出现异常
            int i = 10 / 0;
            statement.executeUpdate
            ("update account set balance = balance + 500 where name='Rose'");
            // 5.提交事务
            connection.commit();
            System.out.println("转账成功");
        } catch (Exception e) {
            e.printStackTrace();
            try {
                // 回滚事务
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            System.out.println("转账失败");
        } finally {
            //4.释放资源
            JdbcUtils.close(connection, statement);
        }
    }
}

7.4 用户登陆

需求实现

通过访问数据库,查询数据库中的用户,实现登录的功能。

7.4.1 创建user表

-- 建表
create table `user`(
    id int primary key auto_increment,
    name varchar(20),
    password varchar(32)
);

-- 插入记录
insert into `user` values(null,'Jack','123'),(null,'Rose','456');
select * from user;

7.4.2 实现用户登录

package cn.guardwhy_02;

import cn.Utils.JdbcUtils;

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

/**
 * 实现用户的登陆
 */
public class LoginDemo02 {
    public static void main(String[] args) throws SQLException {
        // 1.用于用户的输入
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String name = scanner.nextLine();

        // 2.密码输入
        System.out.println("请输入密码:");
        String password = scanner.nextLine();
        // 3.执行SQL语句
        String sql = "select * from user where name=? and password=?";

        // 4.通过工具类得到连接对象
        Connection connection = JdbcUtils.getConnection();
        // 5.通过连接对象创建预编译的语句对象
        PreparedStatement ps = connection.prepareStatement(sql);
        // 6.替换占位符
        ps.setString(1,name);
        ps.setString(2, password);

        // 7.执行SQL语句,使用字符串拼接的方式创建SQL语句
        ResultSet rs = ps.executeQuery();
        // 8.查询得到结果集,如果结果集中有记录表示登录成功,否则登录失败
        if(rs.next()){
            System.out.println("欢迎你" + name + ", 登陆成功!!");
        }else {
            System.out.println("登陆失败..");
        }

        // 释放工具类资源
        JdbcUtils.close(connection, ps, rs);
    }
}
posted @ 2021-10-28 18:22  guardwhy  阅读(100)  评论(0编辑  收藏  举报