SpringDataJpa的使用 -- 连接 MySQL、Oracle 数据库 一(配置数据库实现 ID 自增)

SpringDataJpa的使用 – 连接 MySQL、Oracle 数据库 一(配置数据库实现 ID 自增)

重要

简述 MySQL 数据库 和 Oracle 数据库 在结构方面、连接方面的 异同
  • (同)MySQL 数据库 和 Oracle 数据库 的默认用户都是 root。

  • (同)连接时都需要 IP 地址、端口号,连接配置处 配置的 username、password 一样是 用户名、密码。

  • (异)Oracle 数据库 是 库 -> 用户 -> 表 的形式,即 每个库是一个连接,而在一个库下有多个用户(包括默认用户),用户下有不同的、复数的表。

  • (异)MySQL 数据库 是 用户 -> 库 -> 表 的形式,即每个用户是一个连接,而在一个用户(包括默认用户)下有多个库,库下有不同的、复数的表。

  • (异)MySQL 数据库 只有一个默认用户,而 Oracle 数据库是每个库下 只有一个默认用户。

简述 MySQL 数据库 和 Oracle 数据库 在表命名、表字段命名 的 异同
  • (同)不管是表名还是表字段名,都 没有驼峰命名 的。

  • (异)在 MySQL 数据库中,如 ClassRoom 的表会被命名为 class_room 。表名全小写

  • (异)在 MySQL 数据库中,表字段 ClassRoomID 会在表中 命名为 class_room_id 。字段名全小写

  • (异)在 Oracle 数据库中,如 ClassRoom 的表会被命名为 CLASS_ROOM 。表名全大写

  • (异)在 Oracle 数据库中,表字段 ClassRoomID 会在表中 命名为 CLASS_ROOM_ID 。字段名全大写

连接两个数据库时,重复的依赖和配置

pom.xml

<dependencies>
    <!-- Spring Boot 都使用 2.4.5,看个人习惯 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.4.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.4.5</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <version>2.4.5</version>
        <scope>runtime</scope>
    </dependency>
    <!-- Spring Data JPA 使用 2.6.1,看个人习惯 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <!-- druid 数据库连接池 -->
    <dependency>
        <groupId>com.alibaba</groupId>
        <artifactId>druid-spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.jetbrains</groupId>
        <artifactId>annotations</artifactId>
        <version>1.1.24</version>
    </dependency>

    <!--   下面是可选的依赖,不是本文所必备的,可按需添加   -->
    <!-- lombok -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.20</version>
        <optional>true</optional>
    </dependency>
    <!--  Spring 热部署  -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <version>2.4.5</version>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
</dependencies>

application.yaml (同时存在 .properties 时,重复的内容以 .yaml 文件为准,相同选最近)

spring:
  jpa:
    # 显示 SQL 语句
    show-sql: true
    # 不允许在视图阶段 执行 sql
    open-in-view: false

server:
  # 项目端口号
  port: 8091
  # 项目路径
  servlet:
    context-path: /clond

可能有些同学不喜欢 .yaml 文件格式,下面是 .properties 文件格式的配置项,下文不在重复。
application.properties(同时存在 .yaml 时,重复的内容以 .yaml 文件为准,相同选最近)

# 项目端口号
server.port=8091
# 项目路径
server.servlet.context-path=/clond

# 显示 SQL 语句
spring.jpa.show-sql=true
# 不允许在视图阶段 执行 sql
spring.jpa.open-in-view=false

yaml 文件与 properties 文件的转换。
properties 文件

# 项目端口号
server.port=8091
# 项目路径
server.servlet.context-path=/clond

yaml 文件

server:
  # 项目端口号
  port: 8091
  # 项目路径
  servlet:
    context-path: /clond

连接 MySQL 数据库,并 设置 ID 自增

不再展示重复的依赖和配置了。
本文没有添加 关系映射,以单表测试连接是否成功。

SQL 文件
-- ----------------------------
-- Table structure for teacher
-- ----------------------------
DROP TABLE IF EXISTS `teacher`;
CREATE TABLE `teacher` (
   `teacher_id` tinyint unsigned NOT NULL AUTO_INCREMENT COMMENT '教师主键',
   `teacher_name` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师姓名',
   `teacher_age` int unsigned DEFAULT NULL COMMENT '教师年龄',
   `teacher_sex` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师性别',
   `teacher_course` varchar(255) COLLATE utf8_bin DEFAULT NULL COMMENT '教师教授科目',
   PRIMARY KEY (`teacher_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb3 COLLATE=utf8_bin;
依赖和配置

不要在一个项目中同时添加 MySQL 驱动和 Oracle 驱动,就像 不能同时添加 JPA 依赖和 MyBatis 依赖一样,会报错。

<dependencies>
    <!-- Mysql驱动 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.25</version>
        <scope>runtime</scope>
    </dependency>
</dependencies>

URL: jdbc:mysql://[IP 地址]:[端口号]/[库名]?[参数 1]&[参数 2]&[参数 3]&...&[参数 n]
[IP 地址] :表示 这个整体需要用 方括号内文字所表示的 内容来替换这个整体。即 需要 用 IP地址 来替换,如 localhost 。
[端口号] :同理,需要用 端口号 来替代,一般都是 3306。
[库名] :同理,需要用 库名 来替代。
[参数]:自使用 MySQL 驱动的版本为 8.0.0 起的,都需要添加时区,推荐使用北京时区 serverTimezone=GMT%2B8 。

以 yaml 文件来展示,需要转换的同学可以根据上文的转换方式来转换。

spring:
  # DataBase Connection -- JPA
  datasource:
    druid:
      # serverTimezone可以设置为北京时间GMT%2B8、上海时间Asia/Shanghai或者香港时间Hongkong
      url: jdbc:mysql://localhost:3306/cloudtext?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
      username: root
      password: [用户名]
      min-idle: [密码]
      max-active: 10
      driver-class-name: com.mysql.cj.jdbc.Driver
      login-timeout: 600000
实体类、操作接口、测试

Teacher.java

package com.ljm.exmaple.entity;


import java.util.List;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

/**
 * 教师 类
 *
 * @author LJM
 */
@Entity
@Table(name = "TEACHER")
public class Teacher {
	/**
	 * 教师 id
	 */
	@Id
	@Column(name = "teacher_id", nullable = false)
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	private Long teacherId;
	/**
	 * 教师 姓名
	 */
	@Column(name = "teacher_name", nullable = false)
	private String teacherName;
	/**
	 * 教师 年龄
	 */
	@Column(name = "teacher_age")
	private Integer teacherAge;
	/**
	 * 教师 性别
	 */
	@Column(name = "teacher_sex", nullable = false)
	private String teacherSex;
	/**
	 * 教师 所教的 科目
	 */
	@Column(name = "teacher_course", nullable = false)
	private String teacherCourse;

    /** 省略 Constructor、Getter、Setter、toString 方法 **/	  
}

TeacherRepository.java

package com.example.demo.repository;

import com.example.demo.entity.Teacher;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 老师类 操作 接口
 *
 * @author LJM
 */
public interface TeacherRepository extends JpaRepository<Teacher, Long> {
}

TeacherRepositoryImplText.java

package com.example.demo.repository;

import com.example.demo.entity.Teacher;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;

import javax.annotation.Resource;
import java.util.List;
import java.util.Objects;

@SpringBootTest
public class TeacherRepositoryTest {
    
    @Resource
    private TeacherRepository teacherRepository;

    @Test
    void save () {
        Teacher teacher = new Teacher("黄芳", 34, "女", "英语");
        teacherRepository.save(teacher);
    }
    
    @Test
    void update () {
        Teacher teacher = new Teacher(12L,"黄芳", 34, "女", "英语");
        teacherRepository.save(teacher);
    }

    @Test
    void deleteById () {
        teacherRepository.deleteById(6L);
    }
    
    @Test
    void findAll () {
        List<Teacher> teacherList = teacherRepository.findAll();
        teacherList.stream().map(Objects::toString).forEach(System.out::println);
    }
    
}

连接 Oracle 数据库,并 实现 ID 自增

不再展示重复的依赖和配置了。
本文没有添加 关系映射,以单表测试连接是否成功。
Oracle 没有主键自增,需要添加 序列 来实现 ID 自增。

SQL 文件

注意:下面的 SQL 文件不能直接使用,需要将 你的用户名替换掉 [用户名] 再运行。

-- ----------------------------
-- Table structure for TEACHER
-- ----------------------------
DROP TABLE "[用户名]"."TEACHER";
CREATE TABLE "[用户名]"."TEACHER" (
  "TEACHER_ID" NUMBER(11,0) NOT NULL,
  "TEACHER_NAME" VARCHAR2(50 BYTE),
  "TEACHER_AGE" NUMBER(10,0),
  "TEACHER_SEX" VARCHAR2(20 BYTE),
  "TEACHER_COURSE" VARCHAR2(255 BYTE)
)
LOGGING
NOCOMPRESS
PCTFREE 10
INITRANS 1
STORAGE (
  INITIAL 65536 
  NEXT 1048576 
  MINEXTENTS 1
  MAXEXTENTS 2147483645
  BUFFER_POOL DEFAULT
)
PARALLEL 1
NOCACHE
DISABLE ROW MOVEMENT
;
COMMENT ON COLUMN "[用户名]"."TEACHER"."TEACHER_ID" IS '教师主键';
COMMENT ON COLUMN "[用户名]"."TEACHER"."TEACHER_NAME" IS '教师名称';
COMMENT ON COLUMN "[用户名]"."TEACHER"."TEACHER_AGE" IS '教师年龄';
COMMENT ON COLUMN "[用户名]"."TEACHER"."TEACHER_SEX" IS '教师性别';
COMMENT ON COLUMN "[用户名]"."TEACHER"."TEACHER_COURSE" IS '教师教授科目';

-- ----------------------------
-- Sequence structure for TEACHER_SEQ
-- 添加一个 每次增长 1 的 序列。当然还有其它写法。
-- ----------------------------
DROP SEQUENCE "[用户名]"."TEACHER_SEQ";
CREATE SEQUENCE "[用户名]"."TEACHER_SEQ" MINVALUE 1 MAXVALUE 9999999999999999999999999999 INCREMENT BY 1 NOCACHE;

-- ----------------------------
-- Primary Key structure for table TEACHER
-- ----------------------------
ALTER TABLE "[用户名]"."TEACHER" ADD CONSTRAINT "SYS_C00514610" PRIMARY KEY ("TEACHER_ID");

-- ----------------------------
-- Checks structure for table TEACHER
-- ----------------------------
ALTER TABLE "[用户名]"."TEACHER" ADD CONSTRAINT "SYS_C00514679" CHECK ("TEACHER_ID" IS NOT NULL) NOT DEFERRABLE INITIALLY IMMEDIATE NORELY VALIDATE;
依赖和配置

不要在一个项目中同时添加 MySQL 驱动和 Oracle 驱动,就像 不能同时添加 JPA 依赖和 MyBatis 依赖一样,会报错。

因为版权问题,没有官方的驱动,不过还有很多解决方案的,这个依赖便是其中一种。

<dependency>
    <groupId>com.oracle.database.jdbc</groupId>
    <artifactId>ojdbc8</artifactId>
    <version>21.1.0.0</version>
</dependency>

URL:jdbc:oracle:thin:@[IP地址]:[端口号]:[服务名/SID]
[IP 地址] :表示 这个整体需要用 方括号内文字所表示的 内容来替换这个整体。即 需要 用 IP地址 来替换,如 localhost (不建议用这个)。
[端口号] :同理,需要用 端口号 来替代,一般都是 1521。
[服务名/SID] :同理,需要用 服务名/SID 来替代。

我先使用 Navicat 15这个工具测试连接 Oracle、MySql 这两个数据库。
在这里插入图片描述
在这里插入图片描述

以 yaml 文件来展示,需要转换的同学可以根据上文的转换方式来转换。

spring:
  # DataBase Connection -- JPA
  datasource:
    druid:
      driver-class-name: oracle.jdbc.driver.OracleDriver
      username: [用户名]
      password: [密码]
      # jdbc:oracle:thin:@[IP地址]:[端口号]:[服务名/SID]
      url: jdbc:oracle:thin:@192.168.188.252:1521:EDU
      min-idle: 3
      max-active: 10
      login-timeout: 600000
实体类、操作接口、测试

Teacher.java

package com.example.demo.workflow.entity;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.io.Serializable;

/**
 * 教师 类
 * 
 * 需要 将下面的 [用户名] 替换掉才能用
 *
 * @author LJM
 */
@Entity
@Table(name = "TEACHER")
@SequenceGenerator(name = "TEACHER_SEQUENCE", sequenceName = "[用户名].TEACHER_SEQ", allocationSize = 1)
public class Teacher implements Serializable {

    /**
     * 教师 id
     */
    @Id
    @Column(name = "TEACHER_ID", nullable = false)
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "TEACHER_SEQUENCE")
    private Integer teacherId;
    /**
     * 教师 姓名
     */
    @Column(name = "TEACHER_NAME", nullable = false)
    private String teacherName;
    /**
     * 教师 年龄
     */
    @Column(name = "TEACHER_AGE")
    private Integer teacherAge;
    /**
     * 教师 性别
     */
    @Column(name = "TEACHER_SEX", nullable = false)
    private String teacherSex;
    /**
     * 教师 所教的 科目
     */
    @Column(name = "TEACHER_COURSE", nullable = false)
    private String teacherCourse;

    /** 省略 Constructor、Getter、Setter、toString 方法 **/
}

@SequenceGenerator(name = "[别名]", sequenceName = "[用户名].TEACHER_SEQ", allocationSize = 1)
注解写在类上,name 用来 起别名,sequenceName 用来指向 SQL 语句中创建的那个 序列,allocationSize 是,序列的增长值。
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "[别名]")
注解写在 主键 属性上,如 MySQL 连接版比较,将 GenerationType.IDENTITY 替换成了 GenerationType.SEQUENCE,generator 指向 前面给 序列起的别名。

TeacherRepository.java

package com.example.demo.workflow.repository;

import com.example.demo.workflow.entity.Teacher;
import org.springframework.data.jpa.repository.JpaRepository;

/**
 * 老师类 操作 接口
 *
 * @author LJM
 */
public interface TeacherRepository extends JpaRepository<Teacher, Integer> {
}

TeacherRepositoryTest.java

package com.example.demo.workflow.repository;

import com.example.demo.workflow.entity.Teacher;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import javax.annotation.Resource;
import java.util.List;

@SpringBootTest
public class TeacherRepositoryTest {

    @Resource
    private TeacherRepository teacherRepository;

    @Test
    public void save() {
        Teacher teacher = new Teacher("黄1", 45, "男", "化学");
        Teacher save = teacherRepository.save(teacher);
        System.out.println(save);
    }

    @Test
    public void deleteById() {
        teacherRepository.deleteById(5);
    }

    @Test
    public void update() {
        Teacher teacher = new Teacher(2, "黄迪", 45, "男", "化学");
        Teacher save = teacherRepository.save(teacher);
        System.out.println(save);
    }

    @Test
    public void findAll() {
        List<Teacher> teacherList = teacherRepository.findAll();
        teacherList.stream().map(Object::toString).forEach(System.out::println);
    }
}

参考:《springboot + oracle + jpa + 序列 简单实现id自增》

简述 GenerationType 类的几个 属性

这个类里是 JPA 提供的四种主键生成策略

  • AUTO 自动选择一个最适合底层数据库的主键生成策略。

  • IDENTITY 主键由数据库自动生成,ID 自增长。Oracle 不支持

  • SEQUENCE 主键由数据库序列生成,通过 @SequenceGenerator 注解指定序列。MySql 不支持

  • TABLE 通过特定的数据库表或表格生成主键。

参考:JPA–4种主键生成策略
参考:jpa设置自增主键_jpa主键生成策略

(首发)如果对你有帮助,点赞可好!!

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

十⑧

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值