章节索引
前提
在 索引文章 中我提到过,我们用MySQL做数据库,这篇文章我会少许的讲一些MySQL的东西,注意数据库账号密码、数据库名称、字段名称等数据与后面Java 连接数据库那篇博文保持一致性(严格区分大小写)。
一、访问数据库流程梳理
为了数据的安全,不建议远程连接数据库,下面梳理一下每次请求访问数据库的流程。
- 客户端发送请求(例如登录请求)到Servlet。
- Servlet从请求带的参数中将账号
username
和密码password
拿出来,取出来。 - Servlet调用DAO类(Data Access Object,数据访问对象,用于访问数据库,做数据库查询)去(服务器本地)数据库中查询用户信息:
SELECT username, password FROM user WHERE username=:username
注意:这里的:username表示请求中传入的username
- DAO将查询结果返回给Servlet,Servlet判断用户的账号密码是否存在且匹配,逻辑如:
User user = userDAO.queryByUsername(username);
bool loginSuccess = null != username && password == user.password;
- Servlet根据上述判断结果在响应体中返回登录结果。
二、新建数据库、表、属性
1. 启动数据库(管理系统)
// Linux
service mysql start
// CentOS
systemctl start mariadb
2. 登入数据库(管理系统)
mysql -u root -p
,输入root账号的密码
3. 新建数据库
为了演示和统一,我们创建一个名为myfirstapp
的数据库:
CREATE DATABASE myfirstapp;
SHOW DATABASES;
4. 创建数据表
数据表(也称为关系)用于存储数据记录,我们创建一个user
表,它有三个属性,id
、username
和password
:
// 切换到myfirstapp数据库
USE myfirstapp;
// 创建数据表user
CREATE TABLE user(
// id:整型,自增主键
id INT PRIMARY KEY AUTO_INCREMENT,
// username:字符串,最大长度32字节,非空,默认为空字符串
username varchar(32) NOT NULL DEFAULT '',
// password:字符串,最大长度64字节,非空,默认为空字符串
password varchar(64) NOT NULL DEFAULT ''
);
// 展示表结构
DESC user
5. 插入测试数据
为了便于后面的测试,我们插入一条记录,构造一个账号:
// 插入记录
INSERT INTO user(username, password) VALUES('imple', '123');
// 查询插入的记录
SELECT id, username, password FROM user;
三、 Java连接数据库
1. 数据库连接管理类——DBManager
这个类负责数据库连接的创建、管理和销毁。下面贴出代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.ResultSet;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* 数据库管理类,提供连接数据库和拆解链接功能
*
* @author Implementist
*/
public class DBManager {
//定义的数据库用户名,数据库用户名,一般为root
private final static String DB_USERNAME = "DB_USERNAME";
//定义的数据库连接密码,安装数据库时设置的密码
private final static String DB_PASSWORD = "DB_PASSWORD";
//定义数据库连接URL
private final static String DB_CONNECTION_URL = "jdbc:mysql://localhost:3306/myfirstapp?characterEncoding=utf8";
/**
* 获得数据库连接对象
*
* @return 数据库连接对象
*/
public static Connection getConnection() {
try {
Class.forName("com.mysql.jdbc.Driver").newInstance();
Connection connection = DriverManager.getConnection(DB_CONNECTION_URL, DB_USERNAME, DB_PASSWORD);
return connection;
} catch (ClassNotFoundException | InstantiationException
| IllegalAccessException | SQLException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
return null;
}
}
/**
* 关闭所有的数据库连接资源
*
* @param connection Connection 数据库连接
* @param statement Statement 资源
* @param resultSet ResultSet 结果集合
*/
public static void closeAll(Connection connection, Statement statement, ResultSet resultSet) {
try {
if (resultSet != null) {
resultSet.close();
}
if (statement != null) {
statement.close();
}
if (connection != null) {
connection.close();
}
} catch (SQLException ex) {
Logger.getLogger(DBManager.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
注解*:从
getConnection
方法中可以看到,我们连接数据库所用的依赖是jdbc
驱动器,使用它连接数据库时,需要传入一串遵循特定语法的url,具体为jdbc:mysql://{套接字}/{数据库名}[?额外配置]
,此处:
- 套接字:
localhost:3306
——本地:mysql默认端口- 数据库名:
myfirstapp
- 额外配置:
characterEncoding=utf8
,设置连接所接受的字符集为utf8
2. 数据库访问对象——UserDAO
DAO的意思是数据访问对象(Data Access Object),可以理解为对数据库中User表进行增删改查用的类,我只写一个查询函数,其他函数类推即可,下面贴出代码:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
* @author Administrator
*/
public class UserDAO {
/**
* 查询给定用户名的用户的详细信息
*
* @param userName 给定的用户名
* @return 查询到的封装了详细信息的User对象
*/
public static User queryUser(String username) {
//获得数据库的连接对象
Connection connection = DBManager.getConnection();
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
//生成SQL代码
String sqlStatement = "SELECT * FROM user WHERE username=?";
//设置数据库的字段值
try {
preparedStatement = connection.prepareStatement(sqlStatement);
// 构建数据库查询表达式,下面这行代码会将上面的“?”替换为函数传入的username值
preparedStatement.setString(1, username);
resultSet = preparedStatement.executeQuery();
User user = new User();
// 判断如果查询结果中至少有一条记录,将数据封装成一个User对象
if (resultSet.next()) {
user.setUserName(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
return user;
}
return null;
} catch (SQLException ex) {
Logger.getLogger(UserDAO.class.getName()).log(Level.SEVERE, null, ex);
return null;
} finally {
// 关闭数据库连接相关的对象
DBManager.closeAll(connection, preparedStatement, resultSet);
}
}
}
四、调用方法
在LoginServlet中,我们需要查询是否存在一个用户他的用户名等于请求中的username
,且密码等于password
:
User user = UserDAO.queryUser(username);
判断登录是否成功:
null != user && password.equals(user.getPassword())
后记
这篇文章只是简单介绍如何创建用于测试程序的数据库和表,关于数据库的知识还是要求你去找本书好好的学习一遍, 弄清楚模式、外模式与内模式的区别与联系,创建数据库之前就要进行详尽的设计以使自己的数据库满足各种完整性约束…