JavaSE基础知识分享(十一)

cnblogs 2024-08-21 08:09:13 阅读 85

今天继续讲Java连接MySQL数据库和Java中的对象流(序列化与反序列化)的知识!

写在前面

今天继续讲Java连接MySQL数据库和Java中的对象流(序列化与反序列化)的知识!

Java 与 MySQL 连接

要使用 Java 操作 MySQL 数据库,我们需要通过 JDBC(Java Database Connectivity)进行连接。JDK 本身不提供对具体数据库的操作能力,因此需要使用数据库提供的驱动包来实现。

JDBC 编程 6 步

    <li>

    注册驱动

    告诉 Java 程序即将连接的数据库类型。

    <code>Class.forName("com.mysql.cj.jdbc.Driver");

    li>
  1. 获取连接

    打开 JVM 进程和数据库进程之间的通道。

    Connection conn = DriverManager.getConnection(

    "jdbc:mysql://主机的IP地址:3306/数据库名?useUnicode=true&characterEncoding=utf-8&useSSL=false",

    "root", "123456");

  2. 获取数据库操作对象

    创建用于执行 SQL 语句的对象。

    Statement state = conn.createStatement();

    注意:进行查询操作时,推荐使用 PreparedStatement,以防止 SQL 注入。

    PreparedStatement ps = conn.prepareStatement(

    "UPDATE user SET password=? WHERE username=?");

  3. 执行 SQL 语句

    • executeQuery: 用于查询(DQL)。
    • executeUpdate: 用于增删改(DML)。

    // 执行查询

    ResultSet resultSet = state.executeQuery("SELECT * FROM tableName");

    // 执行更新

    int rowsAffected = state.executeUpdate("UPDATE tableName SET column=value WHERE condition");

  4. 处理查询结果集

    • 仅在执行查询语句(SELECT)时需要处理。

    while (resultSet.next()) {

    // 获取每列的值

    int eno = resultSet.getInt("eno");

    }

  5. 释放资源

    使用完资源后关闭连接。

    state.close();

    conn.close();

MySQL Connector/J 版本对比

    <li>

    MySQL Connector/J 5.1

    • 支持 Java 5 及以上版本。
    • 支持 MySQL 5.6、5.7 和 8.0。
    • 支持 JDBC 3.0、4.0、4.1 和 4.2。
    • Driver 实现类:<code>com.mysql.jdbc.Driver.li>
  • MySQL Connector/J 8.0

    • 支持 Java 8 及以上版本。
    • 支持 MySQL 5.6、5.7 和 8.0。
    • 支持 JDBC 4.2。
    • Driver 实现类:com.mysql.cj.jdbc.Driver.

Properties 集合

Properties 类用于封装和管理与 MySQL 连接相关的参数配置。

Properties 概述

Properties 类是 Map 集合的一个特殊实现,主要用于处理键值对形式的配置数据。它提供了对配置文件的读取和写入功能。

Properties 的特殊功能

  • 设置属性

    public Object setProperty(String key, String value);

    用于将指定的键值对添加到 Properties 集合中。

  • 获取属性

    public String getProperty(String key);

    根据键获取对应的值。

  • 获取所有键名

    public Set<String> stringPropertyNames();

    获取所有的键名集合。

Properties 和 IO 流的结合使用

  • 加载属性

    public void load(Reader reader);

    从指定的 Reader 中读取属性列表(键值对)。

  • 存储属性

    public void store(Writer writer, String comments);

    将属性列表(键值对)写入到指定的 Writer 中,带有注释。

使用示例

  1. 创建 Properties 类对象

    Properties properties = new Properties();

  2. 指定要读取的配置文件

    properties.load(new BufferedReader(new FileReader("路径/info.properties")));

  3. 获取配置项

    String url = properties.getProperty("url");

    String username = properties.getProperty("user");

    String password = properties.getProperty("password");

  4. 使用获取的参数建立数据库连接

    Connection conn = MysqlTool.getConnection(url, username, password);

    System.out.println("成功获取与数据库的链接对象:" + conn);

示例配置文件 (info.properties)

password=123456

user=root

url=jdbc:mysql://主机的IP地址:3306/具体数据库名?useUnicode=true&characterEncoding=utf-8&useSSL=false

序列化与反序列化

序列化流

  • 序列化:将对象转换为可以通过网络传输的字节流。

    • 对象输出流:ObjectOutputStream
  • 反序列化:将字节流还原为对象。

    • 对象输入流:ObjectInputStream

示例代码

读取对象

ObjectInputStream ois = new ObjectInputStream(new FileInputStream("和输出文件路径一样的路径,编码不一样也会出现不能反序列化"));

Object o = ois.readObject(); // 例如 new Student("魏一民", 18);

Student student = (Student) o;

System.out.println(student);

写入对象

ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("输入文件路径"));

Student s1 = new Student("魏一民", 18, "安徽合肥", "110");

oos.writeObject(s1);

oos.flush(); // 确保数据写入文件

序列化操作问题

  • 为什么要实现序列化?

    • 持久化:将对象状态保存到磁盘或数据库中,以便后续恢复。
    • 通信:在网络中将对象通过字节流发送到远程计算机。
    • 深度复制:通过序列化和反序列化实现对象的深度复制。
  • 如何实现序列化?

    • 类必须实现 java.io.Serializable 接口。这个接口是一个标记接口,没有方法需要实现。

    import java.io.Serializable;

    public class MyClass implements Serializable {

    private static final long serialVersionUID = 1L; // 推荐使用

    private String name;

    private int age;

    // Getter 和 Setter 方法

    }

    • serialVersionUID:用于版本控制,确保序列化和反序列化时的类版本一致。
  • 使用 transient 关键字声明不需要序列化的成员变量

    import java.io.Serializable;

    public class MyClass implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    private transient int age; // 不会被序列化

    // Getter 和 Setter 方法

    }

  • 序列化数据后,再次修改类文件,如何解决问题?

    • 版本控制:使用 serialVersionUID 来控制版本匹配,确保序列化和反序列化的类版本一致。
    • 自定义 readObjectwriteObject 方法:处理类的版本变化。
    • transient 关键字:标记不需要序列化的字段,避免因字段缺失导致问题。


声明

本文内容仅代表作者观点,或转载于其他网站,本站不以此文作为商业用途
如有涉及侵权,请联系本站进行删除
转载本站原创文章,请注明来源及作者。