JavaSE-数据库(JDBC)
1- JDBC概念
Java DataBase Connectivity 是Java的数据库连接技术,它是一组接口。使用Java编程来访问各种数据库。
2-JDBC特点
由一组接口组成,代码针对接口进行编程的。不需要自己去实现接口,这些接口的实现类由第三方数据库厂商来实现。
3- JDBC访问数据库
3.1 创建JDBC工程
- 创建普通的Java工程.
- 将普通的Java项目转换成Maven项目
- 倒入相关依赖
<?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 访问数据库步骤
-
通过DriverManager创建连接对象。
-
创建好连接对象以后, 由客户端通过Statement发送SQL语句给MySQL服务器。
-
在数据库服务器端执行SQL语句
-
将执行的结果以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 释放资源
- 需要释放的对象:ResultSet 结果集,Statement 语句,Connection 连接
- 释放原则:先开的后关,后开的先关。ResultSet ==> Statement ==> Connection
- 与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接口
- 有预编译的功能,执行效率更高
- 更加安全性,没有SQL语句字符串拼接操作。没有SQL注入的安全隐患。
- 代码的可读性更强。需要使用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的步骤
- 编写 SQL 语句,未知内容使用?占位
"SELECT * FROM jdbc_user WHERE username=? AND password=?";
- 获得 PreparedStatement 对象
- 设置实际参数:setXxx( 占位符的位置, 真实的值)
- 执行参数化 SQL 语句
- 关闭资源
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 对象关系映射
- 类对应表结构
- 对象对象表中记录
- 成员变量对应字段名字
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 释放资源
每次访问数据库结束,都需要释放资源。
- 需要释放的对象:结果集,语句对象,连接对象
- 释放顺序:先开的后关,后开的先关。关闭顺序: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);
}
}