杰瑞科技汇

mysql bigint java

Of course! Let's break down how to handle MySQL's BIGINT data type in Java. This is a very common task, and understanding the nuances is key to writing robust and bug-free applications.

mysql bigint java-图1
(图片来源网络,侵删)

The Short Answer: The Java Type

The standard and recommended Java type to map to MySQL's BIGINT is java.lang.Long.

  • Why Long? A BIGINT in MySQL can store values from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807. This range perfectly matches the range of a Java long primitive type (64-bit signed integer). Since Long is the wrapper class for long, it's the natural object-oriented choice for representing a database column that can be NULL.

Detailed Breakdown

JDBC Data Types (The Bridge)

When you retrieve data from a MySQL database using JDBC, the driver converts the database types into Java types. This mapping is defined by the JDBC specification.

MySQL Type Java JDBC Type (java.sql.Types) Recommended Java Object Type Primitive Type
BIGINT BIGINT java.lang.Long long

Important Note: The JDBC type for BIGINT is BIGINT (value -5). When you use methods like resultSet.getObject("column_name"), the JDBC driver will correctly return a Long object. If you use resultSet.getLong("column_name"), you get the primitive long value.

Handling NULL Values

This is the most critical difference between the primitive long and the object Long.

mysql bigint java-图2
(图片来源网络,侵删)
  • Long can be NULL: If a BIGINT column in your database contains NULL, resultSet.getObject() will return a null Long object. This is essential for preserving the database state.
  • long cannot be NULL: If you try to use resultSet.getLong() on a NULL value, it will return 0. This is silent data loss! You will have no way to know if the original value was 0 or NULL.

Best Practice: Always use Long when mapping to a BIGINT column that can be NULL.

// Correct way to handle a nullable BIGINT
Long id = resultSet.getObject("user_id", Long.class);
if (id != null) {
    System.out.println("User ID is: " + id);
} else {
    System.out.println("User ID is NULL");
}
// Dangerous way - loses the distinction between 0 and NULL
long primitiveId = resultSet.getLong("user_id"); // Returns 0 if NULL
// You have no idea if it was originally 0 or NULL!

Example: Full JDBC Workflow

Here is a complete example showing how to insert, retrieve, and update a BIGINT column.

Database Table:

CREATE TABLE users (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    account_balance BIGINT,
    created_at BIGINT -- Often used to store a timestamp in milliseconds
);

Java Code:

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class BigIntExample {
    private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database";
    private static final String USER = "your_user";
    private static final String PASS = "your_password";
    public static void main(String[] args) {
        // Use try-with-resources to ensure connections are closed automatically
        try (Connection conn = DriverManager.getConnection(DB_URL, USER, PASS)) {
            System.out.println("Connection to MySQL successful!");
            // --- 1. Insert a new user with a BIGINT value ---
            insertUser(conn, 150000L, 1672531200000L); // Balance in cents, timestamp in ms
            // --- 2. Retrieve and display users with BIGINT values ---
            retrieveUsers(conn);
            // --- 3. Update a user's BIGINT value ---
            updateUserBalance(conn, 1L, 160000L);
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    private static void insertUser(Connection conn, Long balance, Long createdAt) throws SQLException {
        String sql = "INSERT INTO users (account_balance, created_at) VALUES (?, ?)";
        // Using try-with-resources for the PreparedStatement
        try (PreparedStatement pstmt = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS)) {
            pstmt.setObject(1, balance); // setObject handles nulls correctly
            pstmt.setObject(2, createdAt);
            pstmt.executeUpdate();
            // Get the generated ID (which is also a BIGINT)
            try (ResultSet rs = pstmt.getGeneratedKeys()) {
                if (rs.next()) {
                    Long generatedId = rs.getLong(1); // or rs.getObject(1)
                    System.out.println("Inserted user with ID: " + generatedId);
                }
            }
        }
    }
    private static void retrieveUsers(Connection conn) throws SQLException {
        String sql = "SELECT id, account_balance, created_at FROM users";
        try (Statement stmt = conn.createStatement();
             ResultSet rs = stmt.executeQuery(sql)) {
            System.out.println("\n--- User List ---");
            while (rs.next()) {
                // Using getObject to safely get nullable LONGs
                Long id = rs.getObject("id", Long.class);
                Long balance = rs.getObject("account_balance", Long.class);
                Long createdAt = rs.getObject("created_at", Long.class);
                // Handle potential nulls gracefully
                String balanceStr = (balance != null) ? "$" + (balance / 100.0) : "NULL";
                String dateStr = (createdAt != null) ? new java.util.Date(createdAt).toString() : "NULL";
                System.out.printf("ID: %d, Balance: %s, Created: %s%n", id, balanceStr, dateStr);
            }
        }
    }
    private static void updateUserBalance(Connection conn, Long userId, Long newBalance) throws SQLException {
        String sql = "UPDATE users SET account_balance = ? WHERE id = ?";
        try (PreparedStatement pstmt = conn.prepareStatement(sql)) {
            pstmt.setObject(1, newBalance);
            pstmt.setObject(2, userId);
            int rowsAffected = pstmt.executeUpdate();
            System.out.println("\nUpdated " + rowsAffected + " user(s).");
        }
    }
}

Special Cases and Considerations

Unsigned BIGINT (BIGINT UNSIGNED)

MySQL also supports BIGINT UNSIGNED, which ranges from 0 to 18,446,744,073,709,551,615.

  • The Problem: This range is larger than Java's long (max ~9.2 quintillion). You cannot fit the maximum unsigned BIGINT into a Java long.
  • The Solution: You must use java.math.BigInteger. It can handle integers of arbitrary precision.

How to handle it: When retrieving an unsigned BIGINT, use rs.getBigDecimal() or rs.getObject() with BigInteger.class.

// Assuming 'unsigned_bigint_col' is a BIGINT UNSIGNED column
BigInteger unsignedValue = resultSet.getObject("unsigned_bigint_col", BigInteger.class);
// If you get it as a BigDecimal, you can convert it
// BigDecimal unsignedValueBD = resultSet.getBigDecimal("unsigned_bigint_col");
// BigInteger unsignedValue = unsignedValueBD.toBigInteger();

When inserting, use preparedStatement.setObject() with a BigInteger.

BigInteger bigNumber = new BigInteger("18446744073709551615"); // Max unsigned BIGINT
preparedStatement.setObject("unsigned_bigint_col", bigNumber);

Using an ORM (like JPA/Hibernate)

If you are using an Object-Relational Mapper, the mapping is declarative in your entity class.

JPA/Hibernate Example:

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import java.math.BigInteger; // For unsigned
import java.util.Objects;
@Entity
@Table(name = "users")
public class User {
    @Id
    private Long id; // Standard nullable BIGINT
    @Column(name = "account_balance")
    private Long balance; // Standard nullable BIGINT
    // For an UNSIGNED BIGINT column
    @Column(name = "unsigned_value")
    private BigInteger unsignedValue;
    // Getters and Setters...
    // Remember to handle null checks in getters!
    public Long getBalance() {
        return balance;
    }
    public void setBalance(Long balance) {
        this.balance = balance;
    }
    // ... other getters/setters
}

Summary Table

Scenario Recommended Java Type Why?
Standard BIGINT (signed) java.lang.Long Correctly handles the full range and NULL values.
Primitive long long Use only if you are 100% certain the column is NOT NULL and performance is critical. Risky due to silent NULL -> 0 conversion.
BIGINT UNSIGNED java.math.BigInteger The only type that can hold the full range of an unsigned BIGINT.
ORM (JPA/Hibernate) Long or BigInteger Use Long for standard BIGINT and BigInteger for BIGINT UNSIGNED. Annotate with @Column.
分享:
扫描分享到社交APP
上一篇
下一篇