杰瑞科技汇

Java select语句的语法规则是什么?

  1. JDBC (Java Database Connectivity):这是 Java 官方提供的、最基础的数据库连接方式,它适用于所有关系型数据库(如 MySQL, Oracle, SQL Server, PostgreSQL 等),代码量稍多,但灵活性和可控性最高。
  2. MyBatis / JPA:这是目前主流的 ORM (Object-Relational Mapping) 框架,它们将数据库表和 Java 对象进行映射,让你可以用面向对象的方式操作数据库,极大地简化了数据访问层的代码。

下面我将分别详细介绍这两种方式,并提供从简单到复杂的完整示例。

Java select语句的语法规则是什么?-图1
(图片来源网络,侵删)

使用原生 JDBC (最基础、最灵活)

使用 JDBC 的核心步骤是:

  1. 加载数据库驱动。
  2. 获取数据库连接。
  3. 创建 StatementPreparedStatement 对象。
  4. 执行查询,返回 ResultSet 结果集。
  5. 遍历 ResultSet,将数据封装到 Java 对象中。
  6. 关闭所有资源(ResultSet, Statement, Connection)。

完整示例:查询用户列表

假设我们有一个 users 表,结构如下:

CREATE TABLE `users` (
  `id` INT PRIMARY KEY AUTO_INCREMENT,
  `name` VARCHAR(50) NOT NULL,
  `email` VARCHAR(100) NOT NULL,
  `age` INT
);

准备工作:添加数据库驱动依赖

MySQL 为例,如果你使用 Maven,在 pom.xml 中添加依赖:

Java select语句的语法规则是什么?-图2
(图片来源网络,侵删)
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.33</version> <!-- 建议使用较新版本 -->
</dependency>

编写 Java 代码

import java.sql.*;
import java.util.ArrayList;
import java.util.List;
// 1. 定义一个与 users 表对应的 Java 实体类
class User {
    private int id;
    private String name;
    private String email;
    private int age;
    // 构造方法、Getter 和 Setter
    public User() {}
    public User(int id, String name, String email, int age) {
        this.id = id;
        this.name = name;
        this.email = email;
        this.age = age;
    }
    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", email='" + email + '\'' +
                ", age=" + age +
                '}';
    }
    // Getter 和 Setter 方法
    public int getId() { return id; }
    public void setId(int id) { this.id = id; }
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public String getEmail() { return email; }
    public void setEmail(String email) { this.email = email; }
    public int getAge() { return age; }
    public void setAge(int age) { this.age = age; }
}
public class JdbcSelectExample {
    // 数据库连接信息 (请根据你的实际情况修改)
    private static final String DB_URL = "jdbc:mysql://localhost:3306/your_database?useSSL=false&serverTimezone=UTC";
    private static final String USER = "your_username";
    private static final String PASS = "your_password";
    public static void main(String[] args) {
        List<User> users = selectAllUsers();
        for (User user : users) {
            System.out.println(user);
        }
    }
    /**
     * 查询所有用户
     * @return 用户列表
     */
    public static List<User> selectAllUsers() {
        List<User> userList = new ArrayList<>();
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        String sql = "SELECT id, name, email, age FROM users";
        try {
            // 1. 加载驱动 (对于新版JDBC驱动,这步通常可以省略)
            // Class.forName("com.mysql.cj.jdbc.Driver");
            // 2. 获取连接
            conn = DriverManager.getConnection(DB_URL, USER, PASS);
            // 3. 创建 PreparedStatement (推荐使用,可以防止SQL注入)
            pstmt = conn.prepareStatement(sql);
            // 4. 执行查询
            rs = pstmt.executeQuery();
            // 5. 遍历结果集
            while (rs.next()) {
                // 通过列名获取数据,更健壮,不易因列顺序改变而出错
                int id = rs.getInt("id");
                String name = rs.getString("name");
                String email = rs.getString("email");
                int age = rs.getInt("age");
                // 创建 User 对象并添加到列表
                User user = new User(id, name, email, age);
                userList.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 6. 关闭资源 (非常重要!)
            try {
                if (rs != null) rs.close();
                if (pstmt != null) pstmt.close();
                if (conn != null) conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return userList;
    }
}

关键点解释:

  • Connection:代表与数据库的连接。
  • PreparedStatement vs Statement
    • Statement:用于执行静态 SQL 语句。不推荐,因为它容易受到 SQL 注入攻击。
    • PreparedStatement:是 Statement 的子接口,SQL 语句可以带参数(用 占位符),可以防止 SQL 注入,并且对于多次执行的相似 SQL,数据库可以进行预编译,性能更高。强烈推荐使用 PreparedStatement
  • ResultSet:代表查询结果集,它像一个指向数据行的游标。rs.next() 将游标移动到下一行,如果存在下一行则返回 true
  • rs.getXXX()XXX 是数据类型(如 String, Int, Date 等),可以使用列名或列索引来获取值,使用列名是更好的实践。
  • try-finallytry-with-resources:数据库连接等资源非常宝贵,必须在使用后关闭。try-with-resources 是 Java 7 引入的语法,可以自动关闭实现了 AutoCloseable 接口(如 Connection, PreparedStatement, ResultSet)的资源,代码更简洁、安全。

使用 MyBatis 框架 (主流、高效)

MyBatis 将 SQL 语句与 Java 代码分离,通过 XML 或注解配置,让开发者只需关注 SQL 本身和对象映射。

完整示例:查询用户列表

准备工作:添加 MyBatis 依赖

Java select语句的语法规则是什么?-图3
(图片来源网络,侵删)

pom.xml 中添加 MyBatis 和 MySQL 驱动的依赖:

<dependencies>
    <!-- MyBatis 核心库 -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.13</version>
    </dependency>
    <!-- MySQL 驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.33</version>
    </dependency>
    <!-- 日志实现,方便调试 -->
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.36</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.2.12</version>
    </dependency>
</dependencies>

配置 MyBatis

src/main/resources 目录下创建 mybatis-config.xml 文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 1. 设置别名,方便在 Mapper 中使用 -->
    <typeAliases>
        <typeAlias type="com.example.User" alias="User"/>
    </typeAliases>
    <!-- 2. 配置环境,比如开发环境、测试环境 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/your_database?useSSL=false&amp;serverTimezone=UTC"/>
                <property name="username" value="your_username"/>
                <property name="password" value="your_password"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 3. 映射 Mapper 文件 -->
    <mappers>
        <mapper resource="mappers/UserMapper.xml"/>
    </mappers>
</configuration>

创建 Mapper 接口

src/main/java 下创建一个 Mapper 接口,它定义了要执行的 SQL 操作。

package com.example;
import java.util.List;
public interface UserMapper {
    // 方法名对应 SQL 的 id,返回值类型对应 SQL 的 resultType
    List<User> selectAllUsers();
}

创建 Mapper XML 文件

src/main/resources 下创建 mappers 目录,并在其中创建 UserMapper.xml 文件。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.UserMapper">
    <!-- id 必须与 Mapper 接口中的方法名完全一致 -->
    <!-- resultType 指定返回的 Java 对象类型 -->
    <select id="selectAllUsers" resultType="User">
        SELECT id, name, email, age
        FROM users
    </select>
</mapper>

编写 Java 代码进行查询

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class MyBatisSelectExample {
    public static void main(String[] args) {
        // 1. 读取 MyBatis 配置文件
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 2. 构建 SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        // 3. 从 SqlSessionFactory 中获取 SqlSession
        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 4. 获取 Mapper 接口的代理对象
            UserMapper userMapper = session.getMapper(UserMapper.class);
            // 5. 调用 Mapper 方法,MyBatis 会自动执行对应的 SQL
            List<User> users = userMapper.selectAllUsers();
            // 6. 处理结果
            for (User user : users) {
                System.out.println(user);
            }
        }
    }
}

MyBatis 的优势:

  • 关注点分离:SQL 和 Java 代码分离,结构清晰。
  • 强大的映射能力:可以轻松处理复杂的对象关系(如一对一、一对多)。
  • 动态 SQL:可以方便地在 XML 中拼接 SQL 语句(如 if, where, foreach 标签)。
  • 性能好:有内置的一级和二级缓存机制。

总结与对比

特性 原生 JDBC MyBatis / JPA
易用性 :需要编写大量模板代码(获取连接、关闭资源等) :代码简洁,专注于业务逻辑
灵活性 极高:可以执行任何复杂的 SQL,对 SQL 的控制力最强 :通过 XML 或注解配置,能满足绝大多数需求
SQL 与代码耦合 :SQL 语句直接写在 Java 代码中 :SQL 通常配置在 XML 文件中,实现解耦
性能 取决于开发者,写得好性能就好 有缓存等优化机制,性能稳定且优秀
适用场景 简单的、一次性的脚本;对性能要求极高且需要极致优化的场景;学习数据库原理 绝大多数企业级应用,特别是项目复杂、团队协作多的场景

给新手的建议:

  • 先理解 JDBC:虽然不推荐在实际项目中直接使用,但学习 JDBC 是理解 Java 数据库操作原理的基础。
  • 直接上手 MyBatis:对于绝大多数项目,MyBatis 是更现代、更高效、更易维护的选择,它能够让你将精力更多地放在业务逻辑上,而不是繁琐的 JDBC 细节上,如果你喜欢更彻底的面向对象,也可以学习 JPA (如 Hibernate)。
分享:
扫描分享到社交APP
上一篇
下一篇