跳到主要内容

SpringDataJPA 连接 seekdb 示例程序

本文将介绍如何使用 SpringDataJPA 框架和 seekdb 构建一个应用程序,实现创建表、插入数据和查询数据等基本操作。

点击下载 java-oceanbase-springdatajpa 示例工程

前提条件

  • 您已安装 seekdb。

  • 您已安装 JDK 1.8 和 Maven。

  • 您已安装 IntelliJ IDEA。

    信息

    本文档运行代码使用的工具是 IntelliJ IDEA 2021.3.2 (Community Edition) 版本,您也可以根据个人喜好选择适合自己的工具运行示例代码。

操作步骤

信息

本文中给出的操作步骤是基于 Windows 环境生成。如果您使用的是其他操作系统环境或编译器,那么操作步骤可能会略有不同。

  1. 获取 seekdb 连接串。
  2. 导入 java-oceanbase-springdatajpa 项目到 IDEA 中。
  3. 修改 java-oceanbase-springdatajpa 项目中的数据库连接信息。
  4. 运行 java-oceanbase-springdatajpa 项目。

步骤一:获取 seekdb 连接串

  1. 联系 seekdb 部署人员或者管理员获取相应的数据库连接串。

    mysql -hxx.xx.xx.xx -P2881 -uroot -p**** -A
  2. 根据已部署的 seekdb 填写下面 URL 的对应信息。

    信息

    application.yml 文件中需要这里的 URL 信息。

    jdbc:oceanbase://host:port/schema_name?user=$user_name&password=$password&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8

    参数说明:

    • host:提供 seekdb 的连接 IP。使用实际的 IP 替换,也可以使用本地 IP 及 127.0.0.1。

    • port:提供 seekdb 接端口。使用实际的端口替换,默认是 2881,在部署 seekdb 时可自定义。

    • schema_name:需要访问的 Schema 名称。

    • user_name:通过 -u 参数指定,格式为 用户。默认用户为 root

    • password:提供账户密码。

    • characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8:为额外的连接属性。

      • characterEncoding:支持数据库 URL 选项的字符编码。默认值为 utf8
      • useSSL:强制连接时是否使用 SSL/TLS。 默认值为 false
      • serverTimezone:设置服务器时区。默认值为中国标准时间。

更多 URL 参数说明信息,请参见 数据库 URL

步骤二:将导入 java-oceanbase-springdatajpa 项目到 IDEA 中

  1. 打开 IntelliJ IDEA,选择 File > Open... 选项。

    file

  2. 在弹出的 Open File or Project 窗口中,选择对应的项目文件,单击 OK 完成项目文件导入。

  3. IntelliJ IDEA 将会自动识别项目中的各类文件,并在 Project 工具窗口中,可以查看项目的目录结构、文件列表、模块列表、依赖关系等信息。Project 工具窗口通常位于 IntelliJ IDEA 界面的最左侧,默认情况下是打开的。如果 Project 工具窗口被关闭了,可以通过点击菜单栏中的 View > Tool Windows > Project 或者使用快捷键 Alt + 1 来重新打开它。

    信息

    当使用 IntelliJ IDEA 导入项目时,IntelliJ IDEA 会自动检测项目中的 pom.xml 文件,并根据文件中描述的依赖关系自动下载所需的依赖库,并将它们添加到项目中。

  4. 查看项目情况。

springdatajpa

步骤三:修改 java-oceanbase-springdatajpa 项目中的数据库连接信息

根据 步骤一:获取 seekdb 连接串 中的信息修改 application.yml 文件中的数据库连接信息。

示例如下:

  • 数据库驱动的名称为:com.mysql.cj.jdbc.Driver
  • seekdb 的 IP 地址为 10.10.10.1
  • 访问端口使用的是 2881。
  • 需要访问的 Schema 名称为 test
  • 连接账户是 root
  • 密码是 ******

示例代码如下:

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://10.10.10.1:2881/test?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: root
password: ******
type: com.alibaba.druid.pool.DruidDataSource

步骤四:运行 java-oceanbase-springdatajpa 项目

运行路径

  1. 在项目结构中找到 src > test > java 中找到 TestSpringDataJpaApplicationTests.java 文件。
  2. 在工具菜单栏中选择 Run > Run... > TestSpringDataJpaApplicationTests.contextLoads,或直接单击右上角绿色三角形运行。
  3. 通过 IDEA 的控制台来查看项目的日志信息和输出结果。

运行结果

User{id=1, username='insert1'}
User{id=2, username='update'}
User{id=3, username='insert3'}
User{id=4, username='insert4'}
User{id=5, username='insert5'}

常见问题

1. 连接超时

如果遇到连接超时问题,可以在 JDBC URL 中配置连接超时参数:

jdbc:mysql://host:port/database?connectTimeout=30000&socketTimeout=60000

2. 字符集问题

为确保正确的字符编码,在 JDBC URL 中设置正确的字符集参数:

jdbc:mysql://host:port/database?characterEncoding=utf8&useUnicode=true

3. SSL 连接

要启用与 seekdb 的 SSL 连接,在 JDBC URL 中添加以下参数:

jdbc:mysql://host:port/database?useSSL=true&requireSSL=true

4. 账号密码中的特殊字符

如果用户名或密码包含特殊字符(如 #),需要进行 URL 编码:

String encodedPassword = URLEncoder.encode(password, "UTF-8");
提示

使用 MySQL Connector/J 8.x 时,确保账号密码不包含井号(#)。否则,可能会遇到连接错误。

项目代码介绍

点击 java-oceanbase-springdatajpa 下载项目代码,这是一个名为 java-oceanbase-springdatajpa 的压缩包。

解压后,得到一个名为 java-oceanbase-springdatajpa 的文件夹。目录结构如下所示:

│--pom.xml

├─.idea

├─src
│ ├─main
│ │ ├─java
│ │ │ └─com
│ │ │ └─oceanbase
│ │ │ └─testspringdatajpa
│ │ │ │--TestSpringDataJpaApplication.java
│ │ │ │
│ │ │ ├─dao
│ │ │ │ └─UserRepository.java
│ │ │ │
│ │ │ ├─entity
│ │ │ │ └─User.java
│ │ │ │
│ │ │ └─service
│ │ │ │--UserService.java
│ │ │ │
│ │ │ └─impl
│ │ │ └─--UserServiceImpl.java
│ │ │
│ │ └─resources
│ │ │--application.yml
│ │ │
│ │ ├─static
│ │ └─templates
│ └─test
│ └─java
│ └─com
│ └─oceanbase
│ └─testspringdatajpa
│ └─--TestSpringDataJpaApplicationTests.java

└─target

文件说明:

  • pom.xml:Maven 项目的配置文件,包含了项目的依赖、插件、构建等信息。
  • .idea:IDE(集成开发环境)中使用的目录,用于存储项目相关的配置信息。
  • src:通常用于表示项目中存放源代码的目录。
  • main: 存放主要的源代码和资源文件的目录。
  • java: 存放 Java 源代码的目录。
  • com: 存放 Java 包的根目录。
  • oceanbase: 存放项目的根目录。
  • testspringdatajpa:Java 包的根目录,包含了项目的所有 Java 类。
  • TestSpringDataJpaApplication.java:Spring Boot 应用程序的入口类。
  • dao: 存放数据访问对象(Data Access Object)包,用于访问数据库或其他数据存储服务。
  • UserRepository.java:用户数据访问接口,定义了对用户数据的增删改查操作。
  • entity:实体类的目录,用于存放与数据库表对应的 Java 类。
  • User.java:用户持久化对象,用于映射用户数据表的字段。
  • service:服务接口目录,用于定义业务逻辑接口。
  • UserService.java:用户服务接口,定义了对用户数据的操作方法。
  • impl:服务实现目录,用于存放业务逻辑的实现类。
  • UserServiceImpl.java:用户服务的实现类,实现了 UserService 接口中定义的方法。
  • resources: 存放资源文件的目录,如配置文件、SQL 文件等。
  • application.yml:应用程序的配置文件,用于配置数据库连接等信息。
  • static:存放静态文件,如 CSS、JavaScript 等。
  • templates:存放模板文件,如 HTML 模板。
  • test: 存放测试代码和资源文件的目录。
  • TestSpringDataJpaApplicationTests.java: 存放用于执行和验证与 Spring Data JPA 相关的功能的类。
  • target: 存放编译后的 Class 文件、Jar 包等文件的目录。

pom.xml 代码介绍

提示

如果您只是想验证示例,那么请使用默认代码,无需修改。您也可以按照以下讲解,根据自己的需求修改 pom.xml 文件。

pom.xml 配置文件内容如下:

  1. 文件声明语句。

    声明本文件是一个 XML 文件,使用的 XML 版本是 1.0,字符编码方式是 UTF-8

    代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
  2. 配置 POM 的命名空间和 POM 模型版本。

    1. 通过 xmlns 指定 POM 的命名空间为 http://maven.apache.org/POM/4.0.0
    2. 通过 xmlns:xsi 指定 XML 命名空间为 http://www.w3.org/2001/XMLSchema-instance
    3. 通过 xsi:schemaLocation 指定 POM 的命名空间为 http://maven.apache.org/POM/4.0.0,并指定 POM 的 XSD 文件的位置为 https://maven.apache.org/xsd/maven-4.0.0.xsd
    4. 通过 <modelVersion> 元素指定该 POM 文件使用的 POM 模型版本为 4.0.0

    代码如下:

    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
  3. 配置父项信息。

    1. 通过 <groupId> 指定父项标识为 org.springframework.boot
    2. 通过 <artifactId> 指定父项依赖为 spring-boot-starter-parent
    3. 通过 <version> 指定父项的版本号为 2.7.0
    4. 通过 relativePath 表示父项的路径为空。

    代码如下:

     <parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.7.0</version>
    <relativePath/>
    </parent>
  4. 配置基本信息。

    1. 通过 <groupId> 指定项目标识为 com.oceanbase
    2. 通过 <artifactId> 指定项目依赖为 java-oceanbase-springdatajpa
    3. 通过 <version> 指定项目的版本号为 0.0.1-SNAPSHOT
    4. 通过 description 介绍项目信息为 Demo project for Spring Boot

    代码如下:

     <groupId>com.oceanbase</groupId>
    <artifactId>java-oceanbase-springdatajpa</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>java-oceanbase-springdatajpa</name>
    <description>Demo project for Spring Boot</description>
  5. 配置 java 版本。

    指定项目使用的 Java 版本为 1.8。

    代码如下:

      <properties>
    <java.version>1.8</java.version>
    </properties>
  6. 配置核心依赖。

    1. 指定依赖项所属的组织为 org.springframework.boot,名称为 spring-boot-starter-data-jpa,该依赖库包含了使用 JPA 进行数据访问的必要依赖和配置,Spring Boot Starter Data JPA 是一个 Spring Boot 的启动器。

      代码如下:

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-data-jpa</artifactId>
      </dependency>
    2. 指定依赖项所属的组织为 org.springframework.boot,名称为 spring-boot-starter-web,该依赖库包含了使用 Spring Boot 进行 Web 开发所需的依赖和配置,它是一个 Spring Boot 的启动器。

      代码如下:

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
    3. 指定依赖项所属的组织为 org.springframework.boot,名称为 spring-boot-starter-test,作用范围为 test,通过该依赖可以使用 Spring Boot 提供的测试框架和工具,如 JUnit、Mockito、Hamcrest 等。

      代码如下:

      <dependency>
      <groupId>org.springframework.boot</groupId>
      <artifactId>spring-boot-starter-test</artifactId>
      <scope>test</scope>
      </dependency>
    4. 指定依赖项所属的组织为 com.alibaba,名称为 druid,版本号为 1.2.8,通过该依赖可以使用 Druid 库,管理和优化数据库连接的获取和释放。

      代码如下:

      <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.2.8</version>
      </dependency>
    5. 指定依赖项所属的组织为 com.oceanbase,名称为 oceanbase-client,版本号为 2.4.2,通过该依赖可以使用 seekdb 提供的客户端功能,如连接、查询、事务等。

      代码如下:

          <dependencies>
      <dependency>
      <groupId>com.oceanbase</groupId>
      <artifactId>oceanbase-client</artifactId>
      <version>2.4.2</version>
      </dependency>
      </dependencies>
  7. 配置 Maven 插件。

    指定依赖项所属的组织为 org.springframework.boot,名称为 spring-boot-maven-plugin,该插件用于将 Spring Boot 应用程序打包成可执行的 JAR 包或 WAR 包,并且可以直接运行。以为了避免与其他插件或工具产生冲突,在构建的过程中 Lombok 依赖。

    代码如下:

     <build>
    <plugins>
    <plugin>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-maven-plugin</artifactId>
    <configuration>
    <excludes>
    <exclude>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    </exclude>
    </excludes>
    </configuration>
    </plugin>
    </plugins>
    </build>

application.yml 代码介绍

application.yml 文件是一个 Spring Boot 应用程序的配置文件,其中包含了一些关键配置项。它配置了应用程序的上下文路径、监听端口号,以及数据库连接信息和 JPA 相关的属性。

application.yml 文件的代码主要包括以下几个部分:

  • Server 部分

    • servlet:用于配置 Servlet 相关的属性。
    • context-path:指定应用程序的上下文路径为 testspringdatajpa
    • port:指定应用程序监听的端口号为 8890。

    代码如下:

    server:
    servlet:
    context-path: /testspringdatajpa
    port: 8890
  • Spring 部分

    • datasource:用于配置数据源相关的属性,即数据库连接信息。

      • driver-class-name:指定数据库驱动的类名为 com.mysql.cj.jdbc.Driver
      • url:指定数据库的连接 URL,包括数据库的地址、端口号、数据库名称等信息。
      • username:指定连接数据库的用户名。
      • password:指定连接数据库的密码。
      • type:指定使用 Druid 连接池作为数据源。

      代码如下:

      spring:
      datasource:
      driver-class-name: com.mysql.cj.jdbc.Driver
      url: jdbc:mysql://host:port/schema_name?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
      username: user_name
      password: ******
      type: com.alibaba.druid.pool.DruidDataSource
    • JPA 部分

      • hibernate:用于配置 Hibernate 相关的属性。
        • ddl-auto:指定 Hibernate 在启动时自动更新数据库结构为 update
        • show-sql:指定是否在控制台打印 SQL 语句,值为 true
        • format-sql:指定是否格式化打印的 SQL 语句,值为 true
      • open-in-view:指定是否开启 Open-in-View 模式,值为 false

      代码如下:

      jpa:
      hibernate:
      ddl-auto: update
      show-sql: true
      format-sql: true
      open-in-view: false

userRepository.java 文件介绍

userRepository.java 文件通过 DAO 接口用于定义对用户实体(User)进行数据库操作的方法。它包含了自定义的更新和查询方法,使用 SQL 语句和 HQL 语句进行操作。

userRepository.java 文件的代码主要包括以下几个部分:

  1. 引用其他类和接口。

    声明当前文件包含以下接口和类:

    • User 类:用于在服务类中操作和处理用户对象。
    • JpaRepository 接口:用于继承该接口以获得基本的 CRUD 操作方法。
    • Modifying 注解:用于标记修改操作的方法。
    • Query 注解,用于定义自定义查询方法。
    • Param 注解,用于将方法参数与查询语句中的参数进行映射。
    • Repository 注解,用于将 DAO 接口标记为 Spring 的仓库组件。

    代码如下:

    import com.oceanbase.testspringdatajpa.entity.User;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.Modifying;
    import org.springframework.data.jpa.repository.Query;
    import org.springframework.data.repository.query.Param;
    import org.springframework.stereotype.Repository;
  2. 定义 UserRepository 接口。

    UserRepository 接口用于访问用户数据。标记为一个 Spring 的 Repository 组件,并指定 bean 的名称为 userRepository

    1. 通过 @Query 注解指定 SQL 语句,并使用 nativeQuery = true 使用原生 SQL 语句。
    2. 通过 @Modifying 注解自定义的更新方法,使用原生 SQL 语句进行更新操作。
    3. 通过 @Query 注解指定 HQL(Hibernate Query Language)语句,并使用 @Param 注解将方法参数与 HQL 语句中的参数进行映射。

    代码如下:

    @Repository("userRepository")
    public interface UserRepository extends JpaRepository<User, Integer> {

    @Query(value = "update test_springdatajpa_2 set username=?1 where id=?2", nativeQuery = true)
    @Modifying
    int updateById(String name, String id);

    @Query("SELECT u FROM User u WHERE u.username = :username")
    User findUser(@Param("username") String username);
    }

User.java 文件介绍

User.java 文件通过定义 User 类用于表示用户对象。

User.java 文件的代码主要包括以下几个部分:

  1. 引入其他类。 javax.persistence.*:用于引入 javax.persistence 包中的所有类。javax.persistence 是 Java Persistence API(JPA)的标准包,提供了一组用于进行对象关系映射(ORM)的接口和注解。

    代码如下:

    import javax.persistence.*;
  2. 定义 User 对象。 使用 JPA 注解来标识实体类和表的映射关系,包括表名、主键、字段名等。 通过 @Entity 注解标记该类为一个实体类,@Table 注解指定了对应的数据库表名,@Id 注解标记了实体类的主键,@GeneratedValue 注解指定了主键的生成策略,@Column 注解用于指定字段名和约束条件。该类具有 idusername 两个属性,分别表示用户的唯一标识和用户名。还提供了一个默认构造方法,用于创建空的 User 对象。

    代码如下:

    @Entity
    @Table(name = "test_springdatajpa_2")
    public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.TABLE)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "username")
    private String username;

    public User() {
    }
    }
  3. 获取和设置 idname 值。 该实体类提供了一个带参构造方法,用于创建实体类对象并初始化 idusername 属性。 定义四个方法,用于获取和设置 idname 属性的值。

    • getId 方法用于获取 id 值。
    • setId 方法用于设置 id 值。
    • getName 方法用于获取用户名 name 的值。
    • setName 方法用于设置用户名 name 的值。

    代码如下:


    public User(Integer id, String username) {
    this.id = id;
    this.username = username;
    }

    public Integer getId() {
    return id;
    }

    public void setId(Integer id) {
    this.id = id;
    }

    public String getUsername() {
    return username;
    }

    public void setUsername(String username) {
    this.username = username;
    }
  4. 返回 User 对象的字符串表示形式。

    重写 User 类中的 toString 方法,用于返回 User 对象的字符串表示形式。 定义 @Override 覆盖父类中的同名方法。定义 toString 方法,用于返回 User 对象的字符串表示形式。通过字符串拼接,将 idname 属性的值格式化为一个字符串,返回给调用者 User

    代码如下:

    @Override
    public String toString() {
    return "User{" +
    "id=" + id +
    ", username='" + username + '\'' +
    '}';
    }

UserServiceImpl.java 文件介绍

UserServiceImpl.java 文件通过使用 JPA 操作数据库进行用户数据的增删改查。

UserServiceImpl.java 文件的代码主要包括以下几个部分:

  1. 引用其他类和接口。

    声明当前文件包含以下接口和类:

    • UserRepository 类:用于在服务类中注入并调用数据访问对象(DAO)中定义的方法。
    • User 类:用于在服务类中操作和处理用户对象。
    • UserService 类:用于在其他类中注入并调用服务类中定义的方法。
    • Autowired 注解:用于自动注入依赖对象。
    • Page 类:用于分页查询结果的封装。
    • PageRequest 类:用于创建分页请求对象。
    • Pageable 接口:用于定义分页请求的接口。
    • Sort 类:用于定义排序规则。
    • Service 注解:用于将类标记为服务类。
    • Transactional 注解:用于标记事务方法。
    • Iterator 类:用于遍历集合。
    • Optional 类:用于处理可能为空的对象。

    代码如下:

    import com.oceanbase.testspringdatajpa.dao.UserRepository;
    import com.oceanbase.testspringdatajpa.entity.User;
    import com.oceanbase.testspringdatajpa.service.UserService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.data.domain.Page;
    import org.springframework.data.domain.PageRequest;
    import org.springframework.data.domain.Pageable;
    import org.springframework.data.domain.Sort;
    import org.springframework.stereotype.Service;
    import org.springframework.transaction.annotation.Transactional;

    import java.util.Iterator;
    import java.util.Optional;
  2. UserServiceImpl 类实现了 UserService 接口中声明的方法。

    通过依赖注入 UserRepository 实现对数据库的访问。具体实现了插入、删除、更新和查询用户数据的方法,并支持分页查询。使用 @Transactional 注解开启事务支持,确保数据库操作在事务中执行。

    1. 构造 UserRepository 属性。 定义一个私有的 UserRepository 属性,并在构造方法上使用 @Autowired 注解进行依赖注入。通过构造方法注入 UserRepository 依赖,使用 userRepository 属性来访问和操作用户数据。

      代码如下:

      private final UserRepository userRepository;

      @Autowired
      public UserServiceImpl(UserRepository userRepository) {
      this.userRepository = userRepository;
      }
    2. 插入用户数据。 在 insertUser 方法接受一个 User 对象作为参数,通过调用 UserRepositorysave 方法,将用户对象保存到数据库中。

      代码如下:

      @Override
      public void insertUser(User user) { userRepository.save(user); }
    3. 删除用户数据。 在 deleteUser 方法中,通过调用 UserRepositoryexistsById 方法判断指定 id 的用户是否存在,如果存在则进行删除操作,如果不存在则直接返回。

      代码如下:

      @Override
      public void deleteUser(Integer id) {
      if (!userRepository.existsById(id)) {
      return;
      }
      }
    4. 修改用户数据。 在 updateUser 方法中,通过调用 UserRepositorysave 方法,将用户对象保存到数据库中,实现更新操作。同时,返回一个整数值 1,表示更新操作成功。 另外,还根据用户名和 id 更新用户数据的方法,通过调用 UserRepositoryupdateById 方法实现更新操作,并返回更新的结果。

      代码如下:

      @Override
      public int updateUser(User user) {
      userRepository.save(user);
      return 1;
      }

      //update based on name and id
      @Override
      public int updateUserById(String name, String id) {
      return userRepository.updateById(name, id);
      }
    5. 查询用户数据。

      1. 根据 ID 查询用户数据。 在 selectUserById 方法中,通过调用 UserRepositoryfindById 方法,查询到用户数据,并将结果封装为 Optional 对象。然后,通过调用 OptionalorElse 方法,获取 Optional 对象中的值,将其赋值给 user 变量。最后,返回查询到的用户对象。
      2. 根据用户名查询用户数据。 在 selectUserByName 方法中,通过调用 UserRepositoryfindUser 方法,根据用户名查询用户数据,并直接返回查询到的用户对象。

      代码如下:

      @Override
      public User selectUserById(Integer id) {
      Optional<User> optional = userRepository.findById(id);
      User user = optional.orElse(null);
      return user;
      }
      @Override
      public User selectUserByName(String username) {
      return userRepository.findUser(username);
      }
    6. 分页查询所有用户数据。 在 selectUserAll 方法中,通过创建 Sort 对象指定排序规则,创建 Pageable 对象指定分页参数,调用 UserRepositoryfindAll 方法查询用户数据,并返回一个 Page 对象。然后,通过调用 Page 对象的 iterator 方法,获取一个用户数据的迭代器。最后,返回用户数据的迭代器。

      代码如下:

      @Override
      public Iterator<User> selectUserAll(Integer pageNum, Integer pageSize) {
      Sort sort = Sort.by(Sort.Direction.ASC, "id");
      Pageable pageable = PageRequest.of(pageNum, pageSize, sort);
      Page<User> users = userRepository.findAll(pageable);
      Iterator<User> userIterator = users.iterator();
      return userIterator;
      }

UserService.java 文件介绍

UserService.java 文件通过使用 JPA 操作数据库进行用户数据的增删改查。

UserService.java 文件的代码主要包括以下几个部分:

  1. 引用其他类和接口。

    声明当前文件包含以下类:

    • User 类:用于在服务类中操作和处理用户对象。
    • Iterator 类,用于遍历集合。

    代码如下:

    import com.oceanbase.testspringdatajpa.entity.User;

    import java.util.Iterator;
  2. 定义 UserService 接口。 通过 UserService 接口对用户数据进行插入、删除、更新和查询的方法。包含以下方法和类:

    • insertUser 方法,用于插入用户数据。

    • deleteUser 方法,用于删除用户数据。

    • updateUser 方法,用于更新用户数据。

    • updateUserById 方法,用于根据 id 修改用户的 name

    • selectUserById 方法,用于根据 id 查询用户数据。

    • selectUserByName 方法,用于根据用户名查询用户数据。

    • selectUserAll 方法,用于分页查询所有用户数据。

    • User 类,用于在服务类中操作和处理用户对象。

    • Iterator 类,用于遍历集合。

    代码如下:

    public interface UserService {
    void insertUser(User user);

    void deleteUser(Integer id);

    int updateUser(User user);

    int updateUserById(String name, String id);

    User selectUserById(Integer id);

    User selectUserByName(String username);
    Iterator<User> selectUserAll(Integer pageNum, Integer pageSize);
    }

TestSpringDataJpaApplication.java 文件介绍

TestSpringDataJpaApplication.java 文件用于启动和配置 Spring Boot 应用程序。

TestSpringDataJpaApplication.java 文件的代码主要包括以下几个部分:

  1. 定义类和接口。 声明当前文件包含以下类:

    • SpringApplication 类,用于启动 Spring Boot 应用程序。
    • @SpringBootApplication 注解,用于标记 Spring Boot 应用程序的入口类。

    代码如下:

    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
  2. 定义 TestSpringDataJpaApplication 类。 通过使用 @SpringBootApplication 注解标识 Spring Boot 应用的入口类,并在 main 方法中调用 SpringApplication.run 方法来启动应用。

    代码如下:

    @SpringBootApplication
    public class TestSpringDataJpaApplication {

    public static void main(String[] args) {
    SpringApplication.run(TestSpringDataJpaApplication.class, args);
    }
    }

TestSpringDataJpaApplicationTests.java 文件介绍

TestSpringDataJpaApplicationTests.java 文件用于启动和配置 Spring Boot 应用程序。

TestSpringDataJpaApplicationTests.java 文件的代码主要包括以下几个部分:

  1. 引用其他类和接口。 声明当前文件包含以下类:

    • User 类:用于在服务类中操作和处理用户对象。
    • UserService 类,用于在其他类中注入并调用服务类中定义的方法。
    • @Test 注解,用于标记测试方法。
    • Autowired 注解,用于自动注入依赖对象。
    • @SpringBootTest 注解,用于测试 Spring Boot 应用程序。
    • Iterator 类,用于遍历集合。

    代码如下:

    import com.oceanbase.testspringdatajpa.entity.User;
    import com.oceanbase.testspringdatajpa.service.UserService;
    import org.junit.jupiter.api.Test;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.boot.test.context.SpringBootTest;

    import java.util.Iterator;
  2. 定义 UserService 方法。 用于测试 Spring Boot 应用程序中的 UserService 服务的各个方法。它通过注入 UserService 依赖,调用各个方法来测试插入、删除、更新和查询用户数据的功能,并打印相关结果。

    1. 通过 @Autowired 注解。 将 UserService 接口的实现类自动注入到 userService 变量中。

      代码如下:

      @Autowired
      private UserService userService;
    2. 使用 contextLoads 方法测试。

      1. 插入用户数据。 使用 for 循环,调用 userServiceinsertUser 方法插入 10 个用户数据。

        代码如下:

        for (int i = 1; i <= 10; i++) {
        userService.insertUser(new User(i, "insert" + i));
        }
      2. 删除用户数据。 调用 userServicedeleteUser 方法,删除 id 为 1 的用户数据。

        代码如下:

        userService.deleteUser(1);
      3. 修改用户数据。 调用 userServiceupdateUser 方法,更新 id 为 2 的用户数据。

        代码如下:

        userService.updateUser(new User(2, "update"));
      4. 查询用户数据。

        • 调用 userServiceselectUserById 方法,根据 id 查询用户数据,并将结果赋值给 user 变量。打印输出 user 对象。
        • 调用 userServiceselectUserByName 方法,根据用户名查询用户数据,并将结果赋值给 userByName 变量。打印输出 userByName 对象。

        代码如下:

        User user = userService.selectUserById(2);
        System.out.println("user = " + user);
        User userByName = userService.selectUserByName("insert");
        System.out.println("userByName = " + userByName);
      5. 分页查询用户数据。 调用 userServiceselectUserAll 方法,分页查询所有用户数据,并将结果赋值给 userIterator 变量。使用 forEachRemaining 方法遍历 userIterator,并打印输出每个用户对象。

        代码如下:

        Iterator<User> userIterator = userService.selectUserAll(0, 5);
        userIterator.forEachRemaining(System.out::println);

完整的代码展示

tab pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.7.0</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.oceanbase</groupId>
<artifactId>java-oceanbase-springdatajpa</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>java-oceanbase-springdatajpa</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.2.8</version>
</dependency>

<dependency>
<groupId>com.oceanbase</groupId>
<artifactId>oceanbase-client</artifactId>
<version>2.4.2</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<excludes>
<exclude>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</exclude>
</excludes>
</configuration>
</plugin>
</plugins>
</build>

</project>

tab application.yml

server:
servlet:
context-path: /testspringdatajpa
port: 8890

spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:oceanbase://host:port/schema_name?characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
username: user_name
password: ******
type: com.alibaba.druid.pool.DruidDataSource
jpa:
hibernate:
ddl-auto: update
show-sql: true
format-sql: true
open-in-view: false

tab userRepository.java

package com.oceanbase.testspringdatajpa.dao;

import com.oceanbase.testspringdatajpa.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;


@Repository("userRepository")
public interface UserRepository extends JpaRepository<User, Integer> {
//Custom repository handwritten SQL, placeholder value transfer form
@Query(value = "update test_springdatajpa_2 set username=?1 where id=?2", nativeQuery = true)
@Modifying
int updateById(String name, String id);

//SPEL expression, hql syntax
@Query("SELECT u FROM User u WHERE u.username = :username")
User findUser(@Param("username") String username);//Mapping parameter username to database field username
}

tab User.java

package com.oceanbase.testspringdatajpa.entity;

import javax.persistence.*;

@Entity
@Table(name = "test_springdatajpa_2")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.TABLE)

@Column(name = "id", nullable = false)
private Integer id;

@Column(name = "username")
private String username;

public User() {
}

public User(Integer id, String username) {
this.id = id;
this.username = username;
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
'}';
}
}

tab UserServiceImpl.java

package com.oceanbase.testspringdatajpa.service.impl;

import com.oceanbase.testspringdatajpa.dao.UserRepository;
import com.oceanbase.testspringdatajpa.entity.User;
import com.oceanbase.testspringdatajpa.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Iterator;
import java.util.Optional;


@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
private final UserRepository userRepository;

@Autowired
public UserServiceImpl(UserRepository userRepository) {
this.userRepository = userRepository;
}


//insert
@Override
public void insertUser(User user) { userRepository.save(user); }

//delete
@Override
public void deleteUser(Integer id) {
if (!userRepository.existsById(id)) {
return;
}
}

//update
@Override
public int updateUser(User user) {
userRepository.save(user);
return 1;
}

//update based on name and id
@Override
public int updateUserById(String name, String id) {
return userRepository.updateById(name, id);
}

// select one user
@Override
public User selectUserById(Integer id) {
Optional<User> optional = userRepository.findById(id);
User user = optional.orElse(null);
return user;
}

//query user based on username
@Override
public User selectUserByName(String username) {
return userRepository.findUser(username);
}


@Override
public Iterator<User> selectUserAll(Integer pageNum, Integer pageSize) {
//By passing parameters to this method, physical pagination can be achieved, which is very simple.
Sort sort = Sort.by(Sort.Direction.ASC, "id");
Pageable pageable = PageRequest.of(pageNum, pageSize, sort);
Page<User> users = userRepository.findAll(pageable);
Iterator<User> userIterator = users.iterator();
return userIterator;
}
}

tab UserService.java

package com.oceanbase.testspringdatajpa.service;

import com.oceanbase.testspringdatajpa.entity.User;

import java.util.Iterator;



public interface UserService {
//insert
void insertUser(User user);

//delete
void deleteUser(Integer id);

//update
int updateUser(User user);

//customize SQL and modify name based on id
int updateUserById(String name, String id);

//select one user
User selectUserById(Integer id);

//customize SQL to query users based on username
User selectUserByName(String username);

//query all users
Iterator<User> selectUserAll(Integer pageNum, Integer pageSize);
}

tab TestSpringDataJpaApplication.java

package com.oceanbase.testspringdatajpa;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;



@SpringBootApplication
public class TestSpringDataJpaApplication {

public static void main(String[] args) {
SpringApplication.run(TestSpringDataJpaApplication.class, args);
}

}

tab TestSpringDataJpaApplicationTests.java

package com.oceanbase.testspringdatajpa;

import com.oceanbase.testspringdatajpa.entity.User;
import com.oceanbase.testspringdatajpa.service.UserService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.Iterator;


@SpringBootTest
class TestSpringDataJpaApplicationTests {
@Autowired
private UserService userService;

@Test
void contextLoads() {
//insert
for (int i = 1; i <= 10; i++) {
userService.insertUser(new User(i, "insert" + i));
}
//delete
userService.deleteUser(1);
//update
userService.updateUser(new User(2, "update"));
//selectUserById
User user = userService.selectUserById(2);
System.out.println("user = " + user);
//selectUserByName
User userByName = userService.selectUserByName("insert");
System.out.println("userByName = " + userByName);
//query all users
Iterator<User> userIterator = userService.selectUserAll(0, 5);
userIterator.forEachRemaining(System.out::println);
}
}

相关文档

更多 OceanBase Connector/J 的信息,请参见 OceanBase JDBC 驱动程序