首页 > 数据库 >java小课设:使用MySQL做一个聊天室

java小课设:使用MySQL做一个聊天室

时间:2024-11-11 19:58:49浏览次数:4  
标签:ChatServer java String private server 小课 聊天 MySQL new

bro是个懒狗,耗时一个晚上,只写了一些基础功能,其他的可以根据需要自己添加


实现思路:在MySQL数据库中设置一个message表,用来存储聊天信息,聊天界面输入的内容写入message表,用户程序每秒从MySQL中获取一次聊天记录,并加载进入自己的页面,实现聊天室。


食用方法:

ChatServer类中的数据库信息修改为自己的数据库

从ChatApplication类启动

复制粘贴主类中的user语句,可以添加多个用户窗口进行测试。

new User(server);

用户名用来作为聊天室中的昵称

下方的输入框里输入信息,回车键发送,实现相互聊天。



下面是源代码(附注释)


pom依赖

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.1</version>
        </dependency>
        
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.32</version> <!-- 请根据需要更新版本号 -->
        </dependency>
        
        <!--        JSONObject.fromObject()的依赖, JSONArray.fromObject()-->
        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier>
        </dependency>

ChatApplication

import javax.swing.*;

// 定义一个名为ChatApplication的公共类,作为聊天应用程序的入口
public class ChatApplication {
    // main方法是Java程序的入口点
    public static void main(String[] args) {
        // 使用SwingUtilities.invokeLater确保GUI创建和更新在事件调度线程上进行
        SwingUtilities.invokeLater(() -> {
            // 创建ChatServer实例,用于管理聊天服务器和数据库交互
            ChatServer server = new ChatServer();
            // 创建三个User实例,模拟三个用户连接到聊天服务器
            new User(server);
            new User(server);
            new User(server);
        });
    }
}

ChatServer

import java.sql.*;

// ChatServer类,用于管理聊天服务器的功能,包括数据库连接、消息存储和检索
public class ChatServer {
    // 数据库连接对象
    private Connection connection;

    // ChatServer的构造函数,初始化数据库连接并准备聊天环境
    public ChatServer() {
        try {
            // 初始化数据库连接
            // 设置数据库URL、用户名和密码
            String url = "jdbc:mysql://localhost:3306/atguigudb"; // 数据库URL
            String user = "root"; // 数据库用户名
            String password = "123456"; // 数据库密码
            // 获取数据库连接
            connection = DriverManager.getConnection(url, user, password);

            // 创建消息表,如果表不存在则创建
            createMessagesTable();
            // 可选操作:清空聊天记录(根据需求决定是否执行)
            clearChatHistory();
        } catch (Exception e) {
            // 打印异常堆栈信息
            e.printStackTrace();
        }
    }

    // 创建消息表的方法
    private void createMessagesTable() {
        // SQL语句:如果消息表不存在,则创建它
        String createTableSQL = "CREATE TABLE IF NOT EXISTS messages ("
                + "id INT AUTO_INCREMENT PRIMARY KEY, " // 自增主键
                + "sender VARCHAR(255) NOT NULL, " // 发送者
                + "content TEXT NOT NULL, " // 消息内容
                + "timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP" // 时间戳,默认为当前时间
                + ")";
        try (Statement stmt = connection.createStatement()) {
            // 执行SQL语句
            stmt.execute(createTableSQL);
        } catch (Exception e) {
            // 打印异常堆栈信息
            e.printStackTrace();
        }
    }

    // 清空聊天记录的方法(可选)
    private void clearChatHistory() {
        try (PreparedStatement ps = connection.prepareStatement("DELETE FROM messages")) {
            // 执行删除操作,清空messages表
            ps.executeUpdate();
        } catch (Exception e) {
            // 打印异常堆栈信息
            e.printStackTrace();
        }
    }

    // 保存聊天消息的方法
    public void saveMessage(String sender, String message) {
        try (PreparedStatement ps = connection.prepareStatement("INSERT INTO messages (sender,content) VALUES (?, ?)")) {
            // 设置SQL语句中的参数值
            ps.setString(1, sender);
            ps.setString(2, message);
            // 执行插入操作
            ps.executeUpdate();
        } catch (Exception e) {
            // 打印异常堆栈信息
            e.printStackTrace();
        }
    }

    // 获取所有聊天消息的方法
    public String getAllMessages() {
        StringBuilder chatHistory = new StringBuilder();
        try (PreparedStatement ps = connection.prepareStatement(
                "SELECT sender, content FROM messages ORDER BY timestamp ASC")) {
            // 执行查询操作
            ResultSet rs = ps.executeQuery();
            // 遍历结果集,构建聊天历史字符串
            while (rs.next()) {
                String sender = rs.getString("sender");
                String content = rs.getString("content");
                chatHistory.append(sender).append(": ").append(content).append("\n");
            }
        } catch (Exception e) {
            // 打印异常堆栈信息
            e.printStackTrace();
        }
        return chatHistory.toString(); // 返回聊天历史字符串
    }
}

User

import javax.swing.*;
import java.awt.*;

// User类,用于管理用户登录界面和启动聊天客户端
public class User {
    private ChatServer server;

    // User的构造函数,接收ChatServer实例并启动用户登录界面
    public User(ChatServer server) {
        this.server = server;
        loginUser(); // 只启动一个用户的登录窗口,用于演示
    }

    // 启动用户登录界面的方法
    public void loginUser() {
        JFrame loginFrame = new JFrame("请输入用户名");
        JTextField usernameField = new JTextField(15);
        JButton loginButton = new JButton("登录");

        loginFrame.setLayout(new FlowLayout());
        loginFrame.add(new JLabel("用户名:"));
        loginFrame.add(usernameField);
        loginFrame.add(loginButton);

        loginFrame.setSize(400, 200);
        loginFrame.setLocationRelativeTo(null);
        loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        loginFrame.setVisible(true);

        // 为登录按钮添加事件监听器
        loginButton.addActionListener(e -> {
            String username = usernameField.getText().trim();
            if (!username.isEmpty()) {
                loginFrame.dispose();
                new ChatClient(username, server); // 启动聊天客户端
            } else {
                JOptionPane.showMessageDialog(loginFrame, "请输入用户名", "错误", JOptionPane.ERROR_MESSAGE);
            }
        });
    }
}

ChatClient

import javax.swing.*;
import java.awt.*;

// ChatClient类,用于管理聊天客户端的界面和功能
public class ChatClient {
    private JFrame frame;
    private JTextArea chatArea;
    private JTextField inputField;

    private ChatServer server;
    private String username;

    // ChatClient的构造函数,接收用户名和ChatServer实例并初始化聊天客户端
    public ChatClient(String username, ChatServer server) {
        this.server = server;
        this.username = username;

        frame = new JFrame(username + " - 聊天室");
        frame.setSize(600, 400);
        frame.setLocationRelativeTo(null);

        chatArea = new JTextArea();
        chatArea.setFont(new Font("Noto Sans CJK", Font.PLAIN, 16));
        chatArea.setEditable(false); // 禁止编辑聊天区域
        inputField = new JTextField();
        inputField.setFont(new Font("Noto Sans CJK", Font.PLAIN, 16));

        frame.setLayout(new BorderLayout());
        frame.add(new JScrollPane(chatArea), BorderLayout.CENTER);
        frame.add(inputField, BorderLayout.SOUTH);

        loadChatHistory(); // 加载聊天历史

        // 为输入框添加事件监听器,用于发送消息
        inputField.addActionListener(e -> sendMessage());

        // 启动一个线程,定期加载聊天历史以更新聊天区域
        new Thread(() -> {
            while (true) {
                try {
                    Thread.sleep(1000); // 每秒更新一次
                    loadChatHistory();
                } catch (InterruptedException ex) {
                    ex.printStackTrace();
                }
            }
        }).start();

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }

    // 发送消息的方法
    private void sendMessage() {
        String message = inputField.getText();
        if (!message.trim().isEmpty()) {
            server.saveMessage(username, message); // 保存消息到服务器
            inputField.setText(""); // 清空输入框
        }
    }

    // 加载聊天历史的方法
    private void loadChatHistory() {
        String chatHistory = server.getAllMessages(); // 从服务器获取聊天历史
        chatArea.setText(chatHistory); // 设置聊天区域的内容
        chatArea.setCaretPosition(chatArea.getDocument().getLength()); // 将光标移动到文本末尾
    }
}

标签:ChatServer,java,String,private,server,小课,聊天,MySQL,new
From: https://www.cnblogs.com/h4o3/p/18539133

相关文章

  • 【Azure Developer】在使用Azure Bot Service JavaScript的实例代码遇见Cannot find m
    问题描述从Github中下载了JavaScript的BotServiceEchoBot实例代码,本地执行,总是报错Cannotfindmodule'node:crypto' 错误信息Error:Cannotfindmodule'node:crypto'Requirestack:atFunction.Module._resolveFilename(internal/modules/cjs/loader.js:902:15)......
  • WEB 漏洞 - SQL 注入之 MySQL 注入深度解析
    目录WEB漏洞-SQL注入之MySQL注入深度解析一、从宇宙奇想到SQL注入二、SQL注入原理回顾(一)基本概念(二)以简单PHP代码示例说明三、MySQL注入步骤(一)确定注入点(二)判断注入类型(三)利用注入获取信息或执行恶意操作四、防御MySQL注入的方法(一)使用参数化查询(二)......
  • Java流程控制语句-for
    什么是for?在Java流程控制语句中,for属于循环语句,用来进行循环执行代码块,根据条件来进行循环,直到条件不符合则退出循环,具体用法如下for的用法主要用法:for for(inti=0;i<5;i++){System.out.println("i="+i);}该代码执行的结果是:i=0i=1i=2i=......
  • 算法:LeetCode448_找出所有数组中消失的数字_java实现
    packagecom.leetcode;importjava.util.*;/***LeetCode448FindDisappearedNumInArr:找出所有数组中消失的数字*/publicclassLeetCode448FindDisappearedNumInArr{/***方法1.hashset,找出没出现的数字*/publicstaticList<Integer>findD......
  • Java List——针对实习面试
    目录JavaListJavaList的三种主要实现是什么?它们各自的特点是什么?JavaList和Array(数组)的区别?JavaList和Set有什么区别?ArrayList和Vector有什么区别?什么是LinkedList?它与ArryList有什么区别?什么是ArrayList扩容机制?JavaListJavaList的三种主要实现是什么?它们各......
  • Java灵魂拷问13个为什么,你都会哪些?
    大家好,我是V哥。今天看了阿里云开发者社区关于Java的灵魂拷问,一线大厂在用Java时,都会考虑哪些问题呢,对于工作多年,又没有大厂经历的小伙伴不妨看看,V哥总结的这13个为什么,你都会哪些?先赞后看,绝不摆烂。V哥推荐:2024最适合入门的JAVA课程1.为什么禁止使用BigDe......
  • MySQL主从复制
    MySQL主从复制  概要  随着业务的增长,一台数据服务器已经满足不了需求了,负载过重。这个时候就需要减压了,实现负载均衡读写分离,一主一丛或一主多从。  主服务器只负责写,而从服务器只负责读,从而提高了效率减轻压力。  主从复制可以分为:  主从同步:当用户写数据......
  • java整合sse
    目录sse工作原理 SSE的优缺点优点:缺点:Servlet方式的基本逻辑SSE与WebSocket的对比示例代码总结sse工作原理SSE的工作原理基于HTTP协议,它通过以下几个步骤完成:客户端请求:客户端通过GET请求来开启SSE通道。客户端的请求必须设置适当的请求头,告诉服......
  • 深入理解Java对象结构
    一、Java对象结构实例化一个Java对象之后,该对象在内存中的结构是怎么样的?Java对象(Object实例)结构包括三部分:对象头、对象体和对齐字节,具体下图所示1、Java对象的三部分(1)对象头对象头包括三个字段,第一个字段叫作MarkWord(标记字),用于存储自身运行时的数据,例如GC标志位......
  • Java-关于final关键字不得不知道的几大特点
    final-最终的修饰类:表示类不可被继承修饰方法:表示方法不可被子类覆盖,但是可以重载修饰变量:表示变量一旦被赋值就不可以更改它的值。(1)修饰成员变量如果final修饰的是类变量,只能在静态初始化块中指定初始值或者声明该类变量时指定初始值。如果final修饰的是成员变量,可......