前言
上篇分析了Java Web注册/登录过程,数据存储仅仅存在于内存。而实际的场景肯定是缺不了数据库,因此本篇通过注册/登录过程演示MySQL数据库CRUD过程。
通过本篇文章,你将了解到:
- Mac 搭建MySQL 环境
- IDEA 引入MySQL 依赖
- Java 驱动MySQL
- 数据库CRUD
- 小结
1. Mac 搭建MySQL 环境
有两种方式:
- 通过Homebrew 安装
- 官网下载安装包
先说第一种方式:通过Homebrew 安装
可以查看brew支持安装的mysql版本:
brew info mysql
输出如下:
说明当前默认下载的版本是9.0.1(截至本文,MySQL最新版本9.3.0)
确认好版本后即可按如下步骤操作:
a. 打开终端输入: brew install mysql
b. 启动mysql: brew services start mysql
c. 修改密码: mysql_secure_installation
再说第二种方式:官网下载安装包
点击进入 MySQL 官网 查看
此处可选MySQL的版本、系统类型以及系统版本。
下载后的.dmg文件像普通软件一样安装即可。
安装完成后修改MySQL密码:
a. 登录MySQL: mysql -u root -p
b. 修改密码: ALTER USER 'root'@'localhost' IDENTIFIED BY '你的新密码';
然后查看已安装的MySQL 版本:
mysql --version
最后登录MySQL
mysql -u root -p
如上,成功登录了MySQL,此时我们可以在命令行对数据库进行CRUD操作。
2. IDEA 引入MySQL 依赖
本地数据库安装完成,并且可以在终端使用命令访问,说明数据库环境已经准备好了,接着来看看如何使用代码操作数据库。
说到数据库我们都知道大名鼎鼎的CRUD(Create(创建)、Read(读取)、Update(更新)、Delete(删除)),那Java 如何操作数据库呢?
答案是通过JDBC。
JDBC(Java Database Connectivity)是Java语言中用于与数据库交互的标准API,提供了一套统一的接口规范,使开发者能够通过Java程序访问各种关系型数据库。
通常涉及到以下知识点:
DriverManager 管理数据库驱动,负责建立与数据库的连接(Connection对象)。
Connection 表示与数据库的物理连接,用于创建Statement或PreparedStatement。
Statement / PreparedStatement 用于执行SQL语句,后者支持预编译和参数化查询,防止SQL注入。
ResultSet 存储查询结果,通过游标逐行遍历数据
JDBC 约定了标准的API,但数据库厂商又有多个,如MySQL,PostgreSQL、Oracle、SQLite等,每个厂商对JDBC具体的实现有所不同,因此衍生出不同类型的JDBC驱动。
此处我们使用了MySQL数据库,因此需要使用MySQL的JDBC驱动。
在pom.xml里引入JDBC驱动:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.29</version>
</dependency>
如此一来,JDBC依赖引入完成。
3. Java 驱动MySQL
添加依赖之后,接着来看如何使用代码操作数据库。
- 加载驱动
static {
try {
// 加载 MySQL JDBC 驱动
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
这一步的作用是将驱动实例注册到驱动管理类里:
- 获取数据库连接
// 获取数据库连接
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(URL, USER, PASSWORD);
}
其中URL形如:
jdbc:mysql://localhost:3306/school_db
school_db 指的是数据库名字
USER表示用户名,PASSWORD表示登录数据库的密码。
4. 数据库CRUD
有了数据库连接后,我们就可以进行CRUD了。
- 创建表
conn = DatabaseUtil.getConnection();
// 检查users表是否存在,如果不存在则创建
String checkTableSql = "CREATE TABLE IF NOT EXISTS users (id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) UNIQUE, phone VARCHAR(255), password VARCHAR(255))"; // 将 captcha 改为 password
pstmt = conn.prepareStatement(checkTableSql);
pstmt.executeUpdate();
先定义SQL语句,而后创建执行语句的对象,最后执行语句。
此处是创建了名为users的表,该表里有四个字段:id、name、phone、password。
- C动作(添加数据)
表建立好之后即可往里面添加数据:
public void addUser(User user) {
String sql = "INSERT INTO users (name, phone, password) VALUES (?, ?, ?)";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, user.getName());
pstmt.setString(2, user.getPhone());
pstmt.setString(3, user.getPassword());
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
一样的套路,书写SQL语句,构造PreparedStatement对象,最后执行语句。
此处(?, ?, ?)表示占位,后续通过 pstmt.setString(xx, yy)赋值。
这方法表示往users表里插入一条用户记录(数据库行)。
- R动作(读取数据)
public List<User> getAllUsers() {
List<User> users = new ArrayList<>();
String sql = "SELECT * FROM users";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql);
ResultSet rs = pstmt.executeQuery()) {
while (rs.next()) {
User user = new User(rs.getString("name"), rs.getString("phone"), rs.getString("password"));
user.setId(rs.getInt("id"));
users.add(user);
}
} catch (Exception e) {
e.printStackTrace();
}
return users;
}
从表里查询所有的记录。
此处涉及到返回值,封装在ResultSet里,通过遍历ResultSet可以取出所有的记录。
- U动作(更新数据)
现在想对表里的其中一条数据进行更新,比如更新用户的名字。
public void updateUser(int id, String name) {
String sql = "UPDATE users SET name = ? WHERE id = ?";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setString(1, name);
pstmt.setInt(2, id);
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
要想指定更新某个用户的名字,那么得知道这个用户是存在表里的哪条记录,因此需要通过唯一标识来索引(此处是id)。
- D动作(删除数据)
不想要某个用户数据了,可以选择物理删除。
public void deleteUser(int id) {
String sql = "DELETE FROM users WHERE id = ?";
try (Connection conn = DatabaseUtil.getConnection();
PreparedStatement pstmt = conn.prepareStatement(sql)) {
pstmt.setInt(1, id);
pstmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}
}
综合以上的CRUD示例,你会发现他们有共通之处,也多了一些模板代码。
最核心之处在于如何编写SQL语句,因此需要我们能够比较熟练的使用MySQL命令。
可在这个网址学习MySQL常用语句:MySQL在线练习
5. 小结
以上我们一步步分解了Java操作MySQL数据库的步骤,结合之前的Servlet,编写了简单的数据管理后台。
效果如下:
本篇代码请查看:管理后台代码
下篇将分析前后端分离场景下,后端如何提供接口与前端交互。