文章目录
GUI用户登录
- 用户登录界面
- 功能实现要利用JDBC操作数据库
- 登录成功,弹出消息框提示用户 -
欢迎登录系统~
- 登录失败,弹出消息框提示用户
- 用户名或密码错误!
- 要求采用
MVC
架构
编程实现
1.创建数据库和表
(1) 创建学生数据库
- 执行命令:
CREATE DATABASE student CHARSET='utf8mb4'
(2)创建用户表
- 执行命令:
USE student
,打开student
数据库 - 创建用户表
t_user
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`username` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户名',
`password` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '用户密码',
`telephone` varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL COMMENT '联系电话',
`register_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '注册时间',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4;
- 执行语句,查看结果
- 插入三条记录
INSERT INTO t_user (username, password, telephone, register_time) VALUES ('admin', '12345', '13945456780', '2022-01-01 09:10:34');
INSERT INTO t_user (username, password, telephone, register_time) VALUES ('brown', '11111', '13878789089', '2022-03-12 19:05:44');
INSERT INTO t_user (username, password, telephone, register_time) VALUES ('alice', '22222', '15834345670', '2022-04-04 15:16:24');
- 执行语句,查看结果
查看用户表记录
- 使用
select*from t_user;
查询
- 或点击表查询
- 一条用户记录对应一个实体,这是一个映射
2. 创建用户实体类
- 在
net.lixin.p03.t09.bean
包里创建User
类
package net.lixin.p03.t09.bean;
import java.util.Date;
/**
* 功能:用户实体类
* 作者:李信
* 日期:2022年06月09日
*/
public class User {
private int id;
private String username;
private String password;
private String telephone;
private Date registerTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
public Date getRegisterTime() {
return registerTime;
}
public void setRegisterTime(Date registerTime) {
this.registerTime = registerTime;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", telephone='" + telephone + '\'' +
", registerTime=" + registerTime +
'}';
}
}
3、添加数据库驱动程序包
- 在项目根目录创建
libs
目录,添加数据库驱动程序包
- 此时,这个
jar
包还不能被项目使用,需要作为库添加到项目里
- 单击【Add as Library…】菜单项
- 此时,数据库驱动程序包就可以被项目使用了
- 查看JDBC重要的接口和类
4、创建数据库连接管理类
- 创建
net.lixin.p03.t09.dbutils
包,在包里创建ConnectionManager
类
package net.lixin.p03.t09.dbutils;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 功能:数据库连接管理类
* 作者:李信
* 日期:2022年06月09日
*/
public class ConnectionManager {
// 数据库连接属性
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc:mysql://localhost:3306/student?useSSL=false";
private static final String USER = "root";
private static final String PASSWORD = "111111"; // 改成自己数据库的密码
/**
* 私有化构造方法,拒绝实例化
*/
private ConnectionManager() {
}
/**
* 获取数据库连接静态方法
*
* @return 数据库连接
*/
public static Connection getConnection() {
// 定义数据库连接
Connection conn = null;
try {
// 安装数据库驱动
Class.forName(DRIVER);
// 获取数据库连接
conn = DriverManager.getConnection(URL, USER, PASSWORD);
// 提示用户数据库连接成功
System.out.println("提示:数据库连接成功~");
} catch (ClassNotFoundException e) {
System.err.println("异常:数据库驱动程序未找到!");
} catch (SQLException e) {
System.err.println("异常:数据库连接失败!");
}
// 返回数据库连接
return conn;
}
/**
* 关闭数据库连接静态方法
*
* @param conn
*/
public static void closeConnection(Connection conn) {
// 判断连接是否为空
if (conn != null) {
try {
// 判断连接是否关闭
if (!conn.isClosed()) {
// 关闭数据库连接,释放资源
conn.close();
// 提示用户
System.out.println("提示:数据库连接关闭~");
}
} catch (SQLException e) {
System.err.println(e.getMessage());
}
}
}
/**
* 主方法测试数据库连接
*
* @param args
*/
public static void main(String[] args) {
// 获取数据库连接
Connection conn = getConnection();
// 关闭数据库连接
closeConnection(conn);
}
}
- 运行程序,查看结果
- 故意把
DRIVER
改错,就会抛出异常被捕获
5、创建用户数据访问接口
- 在
net.lixini.p03.t09.dao
包里创建UserDao
接口(DAO: Data Access Object)
package net.lixin.p03.t09.dao;
import net.lixin.p03.t09.bean.User;
import java.util.List;
/**
* 功能:用户数据访问接口
* 作者:李信
* 日期:2022年06月09日
*/
public interface UserDao {
int insert(User user);
int delete(int id);
int update(User user);
User findById(int id);
List<User> findAll();
User login(String username, String password);
}
6、创建用户数据访问接口实现类
- 在
net.lixin.p03.t09.dao.impl
包里创建UserDaoImpl
类
- 实现
UserDao接口
,就要去实现接口里的抽象方法
- 默认全选
- 单击Ok
package net.lixin.p03.t09.dao.impl;
import net.lixin.p03.t09.bean.User;
import net.lixin.p03.t09.dao.UserDao;
import java.util.List;
/**
* 功能
* 作者:李信
* 日期:2022年06月09日
*/
public class UserDaoImpl implements UserDao {
@Override
public int insert(User user) {
return 0;
}
@Override
public int delete(int id) {
return 0;
}
@Override
public int update(User user) {
return 0;
}
@Override
public User findById(int id) {
return null;
}
@Override
public List<User> findAll() {
return null;
}
@Override
public User login(String username, String password) {
return null;
}
}
- 下面,我们来编写登陆的方法
login()
@Override
public User login(String username, String password) {
// 定义用户对象
User user = null;
// 1. 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 2. 创建SQL字符串
String strSQL = "select * from t_user where username = ? and password = ?";
try {
// 3. 创建预备语句对象(准备提供参数)
PreparedStatement pstmt = conn.prepareStatement(strSQL);
// 4. 用参数值设置占位符的值
pstmt.setString(1, username);
pstmt.setString(2, password);
// 5. 执行SQL查询,返回结果集
ResultSet rs = pstmt.executeQuery();
// 6. 遍历结果集,用记录值填充用户对象
while (rs.next()) {
// 创建用户对象
user = new User();
// 用当前记录字段值设置用户对象属性
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setTelephone(rs.getString("telephone"));
user.setRegisterTime(rs.getTimestamp("register_time"));
}
} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
ConnectionManager.closeConnection(conn);
}
// 返回用户对象
return user;
}
- 我们再编写查询全部用户记录的方法
- findAll()
@Override
public List<User> findAll() {
// 定义用户列表
List<User> users = new ArrayList<>();
// 1. 获取数据库连接
Connection conn = ConnectionManager.getConnection();
// 2. 创建SQL字符串
String strSQL = "select * from t_user";
try {
// 3. 创建语句对象
Statement stmt = conn.createStatement();
// 4. 执行SQL查询,返回结果集
ResultSet rs = stmt.executeQuery(strSQL);
// 5. 遍历结果集,构建用户列表
while (rs.next()) {
// 创建用户对象
User user = new User();
// 用当前记录字段值设置用户对象属性
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setTelephone(rs.getString("telephone"));
user.setRegisterTime(rs.getTimestamp("register_time"));
// 将用户对象添加到用户列表
users.add(user);
}
} catch (SQLException e) {
System.err.println(e.getMessage());
} finally {
ConnectionManager.closeConnection(conn);
}
// 返回用户列表
return users;
}
对UserDaoImpl进行单元测试
- 在
net.lixin.p03.t09.test
包里创建TestUserDaoImpl
类
- 编写测试方法 -
testFindAll()
package net.huawei.p03.t09.test;
import net.huawei.p03.t09.bean.User;
import net.huawei.p03.t09.dao.UserDao;
import net.huawei.p03.t09.dao.impl.UserDaoImpl;
import org.junit.Before;
import org.junit.Test;
import java.util.List;
/**
* 功能:测试用户数据访问接口实现类
* 作者:李信
* 日期:2022年06月09日
*/
public class TestUserDaoImpl {
private UserDao userDao;
@Before
public void init() {
userDao = new UserDaoImpl();
}
@Test
public void testFindAll() {
List<User> users = userDao.findAll();
// 判断用户表是否有记录
if (users.size() > 0) {
for(User user : users) {
System.out.println(user);
}
} else {
System.out.println("提示:用户表里没有记录~");
}
}
}
- 运行测试方法 -
testFindAll()
,查看结果
- 编写测试登录的方法 -
testLogin()
@Test
public void testLogin() {
String username = "admin";
String password = "11111";
User user = userDao.login(username, password);
if (user != null) {
System.out.println("恭喜,[" + username + "]登录成功~");
} else {
System.out.println("遗憾,[" + username + "]登录失败~");
}
}
- 运行
testLogin()
测试方法
- 修改密码:
11111
-
package net.huawei.p03.t09.service;
import net.huawei.p03.t09.bean.User;
import net.huawei.p03.t09.dao.UserDao;
import net.huawei.p03.t09.dao.impl.UserDaoImpl;
import java.util.List;
/**
* 功能:用户服务类
* 作者:李信
* 日期:2022年06月09日
*/
public class UserService {
private UserDao userDao;
public UserService() {
userDao = new UserDaoImpl();
}
public int addUser(User user) {
return userDao.insert(user);
}
public int deleteUser(int id) {
return userDao.delete(id);
}
public int updateUser(User user) {
return userDao.update(user);
}
public User findUserById(int id) {
return userDao.findById(id);
}
public List<User> findAllUsers() {
return userDao.findAll();
}
public User login(String username, String password) {
return userDao.login(username, password);
}
}
8、创建用户登录界面
-在net.lixini.p03.t09.gui
包里创建LoginFrame
类
package net.huawei.p03.t09.gui;
import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
/**
* 功能:用户登录窗口
* 作者:李信
* 日期:2022年06月09日
*/
public class LoginFrame extends JFrame {
private String username;
private String password;
private JLabel lblUsername;
private JLabel lblPassword;
private JTextField txtUsername;
private JPasswordField txtPassword;
private JButton btnOK;
private JButton btnCancel;
private JPanel panel, panel1, panel2, panel3;
/**
* 有参构造方法
*
* @param title
*/
public LoginFrame(String title) {
super(title);
initGUI(); // 调用初始化图形用户界面方法
}
/**
* 初始化图形用户界面方法
*/
private void initGUI() {
// 实例化组件(面板与控件)
panel = (JPanel) getContentPane();
panel1 = new JPanel();
panel2 = new JPanel();
panel3 = new JPanel();
lblUsername = new JLabel("用户名:");
lblPassword = new JLabel("密 码:");
txtUsername = new JTextField(15);
txtPassword = new JPasswordField(15);
btnOK = new JButton("确定[O]");
btnCancel = new JButton("取消[C]");
// 将控件添加到三个小面板
panel1.add(lblUsername);
panel1.add(txtUsername);
panel2.add(lblPassword);
panel2.add(txtPassword);
panel3.add(btnOK);
panel3.add(btnCancel);
// 设置主面板为三行一列的网格布局
panel.setLayout(new GridLayout(3, 1));
// 将三个小面板依次添加到主面板
panel.add(panel1);
panel.add(panel2);
panel.add(panel3);
// 设置按钮热键字母
btnOK.setMnemonic(KeyEvent.VK_O);
btnCancel.setMnemonic(KeyEvent.VK_C);
// 设置密码框回显字符
txtPassword.setEchoChar('*');
// 设置窗口大小
setSize(250, 200);
// 设置窗口屏幕居中
setLocationRelativeTo(null);
// 设置窗口不可调整大小
setResizable(false);
// 设置窗口刚好容纳组件
pack();
// 设置窗口可见
setVisible(true);
// 设置窗口默认关闭操作
setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
}
public static void main(String[] args) {
new LoginFrame("用户登录");
}
}
- 运行程序,查看结果
9、实现用户登录功能
- 涉及GUI的事件处理机制:事件、事件源、监听器(事件处理方法)
- 创建事件处理方法
eventHanding()
,并在构造方法里调用
/**
* 事件处理
*/
private void eventsHandling() {
// 给【确定】按钮注册监听器
btnOK.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
// 获取用户输入的用户名和密码
username = txtUsername.getText().trim();
password = new String(txtPassword.getPassword());
// 创建用户服务对象
UserService userService = new UserService();
// 调用服务对象的登录方法
User user = userService.login(username, password);
// 判断用户登录是否成功
if (user != null) {
// 弹出消息框提示用户
JOptionPane.showMessageDialog(null, "恭喜,[" + username + "]登录成功~");
dispose(); // 关闭登录窗口
} else {
// 弹出消息框提示用户
JOptionPane.showMessageDialog(null, "遗憾,用户名或密码错误~");
// 清空两个文本框
txtUsername.setText("");
txtPassword.setText("");
// 让姓名文本框获取焦点
txtUsername.requestFocus();
}
}
});
// 给【取消】按钮注册监听器
btnCancel.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0); // 退出应用程序
}
});
}
运行程序,查看结果