spring-boot-starter-data-jpa 配置多个数据源与jpa实体类继承的问题、分页条件查询

article/2025/9/30 4:30:25

JPA的继承注解一般有四种

@MappedSuperclass 这个注解应用的场景是父类不对应任何单独的表,多个子类共用相同的属性。
注意:
@MappedSuperclass注解使用在父类上面,是用来标识父类的作用
@MappedSuperclass标识的类表示其不能映射到数据库表,因为其不是一个完整的实体类,但是它所拥有的属性能够映射在 其子类对用的数据库表中
@MappedSuperclass标识得类不能再有@Entity或@Table注解 但是可以使用@Id 和@Column注解

@Inheritence 此注解应用于根实体类以定义继承策略。 如果没有使用此注释定义策略类型,那么它遵循单表战略。
单表策略:
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
查询父类关联的表 在查询父类的时候 所有子类表中字段全部查询出来
连接策略:
@Inheritance(strategy=InheritanceType.JOINED)
在连接策略中,为每个实体类生成一个单独的表。 每个表的属性都与主键连接。 它消除了字段字重复的可能性。但是父类中除了主键的的其他字段 并不会在子表中查询出来
按类表策略:
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
在按类表策略中,为每个子实体类生成一个单独的表。 与连接策略不同,在按类表策略中不会为父实体类生成单独的表
@DiscriminatorColumn 鉴别器属性将一个实体与另一个实体区分开来。 因此,该注释用于提供鉴别器列的名称。 仅需要在根实体类上指定此注释。
@DiscriminatorValue 此注释用于指定表示特定实体的值的类型。 需要在子实体类中指定此注释。

@MappedSuperclass 测试

准备两张表:t_user,t_address。
t_user

CREATE TABLE `t_user` (`rid` bigint NOT NULL,`user_name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,`email` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,`phone` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

t_address

CREATE TABLE `t_address` (`rid` bigint NOT NULL,`province` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,`city` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,`county` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL,PRIMARY KEY (`rid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

BaseEntity 实体类,使用@MappedSuperclass注解,标识属性能够映射在其子类对用的数据库表中

@MappedSuperclass
public class BaseEntity {@Id@Column(name = "rid",nullable = false)private Long rid;public Long getRid() {return rid;}public void setRid(Long rid) {this.rid = rid;}
}

t_user实体类:

@Entity
@Table(name = "t_address")
public class Address extends BaseEntity{@Column(name = "province")private String province;@Column(name = "city")private String city;@Column(name = "county")private String county;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getCounty() {return county;}public void setCounty(String county) {this.county = county;}
}

t_address:

@Entity
@Table(name = "t_address")
public class Address extends BaseEntity{@Column(name = "province")private String province;@Column(name = "city")private String city;@Column(name = "county")private String county;public String getProvince() {return province;}public void setProvince(String province) {this.province = province;}public String getCity() {return city;}public void setCity(String city) {this.city = city;}public String getCounty() {return county;}public void setCounty(String county) {this.county = county;}
}

userRepository接口继承JpaRepository,JpaSpecificationExecutor实现crud操作。

public interface UserRepository extends JpaRepository<User,Long>,JpaSpecificationExecutor<User> {
}

addressRepository接口继承JpaRepository,JpaSpecificationExecutor实现crud操作。

public interface AddressRepository extends JpaRepository<Address,Long>, JpaSpecificationExecutor<Address> {
}

配置数据库连接在application.yml

spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: 123456url: jdbc:mysql://127.0.0.1:3306/testdemo?serverTimezone=UTC

测试:

    @Autowiredprivate AddressRepository addressRepository;@Testvoid contextLoads() {Address address = new Address();address.setRid(1L);address.setProvince("四川省");address.setCity("成都市");address.setCounty("金牛区");addressRepository.save(address);}

在这里插入图片描述

    @Autowiredprivate UserRepository userRepository;@Testvoid userTest(){User user = new User();user.setRid(1L);user.setUserName("祝八一");user.setEmail("123@qq.com");user.setPhone("1878265xxxx");userRepository.save(user);}

在这里插入图片描述
可见在baseEntity里面的rid也插入进了数据库

jpa配置多数据源

1.首先把application.yml里面的数据源的配置先注释了。

在这里插入图片描述
换成如下的配置

spring:datasource:db1:url: jdbc:mysql://127.0.0.1:3306/testdemo?serverTimezone=UTC#数据库用户名username: root#数据库密码password: 123456#mysql数据库驱动程序(重要)driverClassName: com.mysql.cj.jdbc.Driverdb2:url: jdbc:mysql://127.0.0.1:3306/shop?serverTimezone=UTC#数据库用户名username: root#数据库密码password: 123456#mysql数据库驱动程序(重要)driverClassName: com.mysql.cj.jdbc.Driver

2.编写数据源配置类

@ConfigurationProperties(prefix = "spring.datasource.db1")
@Component
@Data
public class Db1Properties {private String url;private String username;private String password;private String driverClassName;
}
@ConfigurationProperties(prefix = "spring.datasource.db2")
@Component
@Data
public class Db2Properties {private String url;private String username;private String password;private String driverClassName;
}

Db1Config、Db2Config
以下两个是需要修改的配置信息

设置@EnableJpaRepositories注解里的basePackages属性配置jpa持久化类的包路径
设置db1EntityManagerFactory方法中的packages方法设置实体类所在的包路径

@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "db1EntityManagerFactory",transactionManagerRef = "db1TransactionManager",//basePackages = {"com.zhubayi.jpademo.repository.user"})// 指定该数据源操作的DAO接口包basePackageClasses = UserRepository.class) //定一个要扫描包中的一个类或接口,将扫描所在包中的所有repository。 
public class Db1Config {@Autowired@Qualifier("db1DataSource")private DataSource db1DataSource;@PersistenceUnit(name = "db1PersistenceUnit")@Primary@Bean(name = "db1EntityManagerFactory")public LocalContainerEntityManagerFactoryBean db1EntityManagerFactory() {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();em.setDataSource(db1DataSource);em.setPersistenceUnitName("db1PersistenceUnit");em.setPackagesToScan(new String[]{"com.zhubayi.jpademo.entity"});HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();//开启sql展示vendorAdapter.setShowSql(true);em.setJpaVendorAdapter(vendorAdapter);return em;}@Primary@Bean(name = "db1TransactionManager")public PlatformTransactionManager db1TransactionManager(@Qualifier("db1EntityManagerFactory") EntityManagerFactory factory) {return new JpaTransactionManager(factory);}}@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef = "db2EntityManagerFactory",transactionManagerRef = "db2TransactionManager",//basePackages = {"com.zhubayi.jpademo.repository.address})// 指定该数据源操作的DAO接口包basePackageClasses = AddressRepository.class)//定一个要扫描包中的一个类或接口,将扫描所在包中的所有repository。 
public class Db2Config {@Autowired@Qualifier("db2DataSource")private DataSource db2DataSource;@PersistenceUnit(name  ="db2PersistenceUnit")@Bean(name = "db2EntityManagerFactory")public LocalContainerEntityManagerFactoryBean db2EntityManagerFactory() {LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();em.setDataSource(db2DataSource);em.setPersistenceUnitName("db2PersistenceUnit");em.setPackagesToScan(new String[]{"com.zhubayi.jpademo.entity"});HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();//开启sql展示vendorAdapter.setShowSql(true);em.setJpaVendorAdapter(vendorAdapter);return em;}@Bean(name = "db2TransactionManager")public PlatformTransactionManager db2TransactionManager(@Qualifier("db2EntityManagerFactory") EntityManagerFactory factory) {return new JpaTransactionManager(factory);}
}

@EnableJpaRepositories注解说明
  value:basePackages的别名,简化basePackages。
  basePackages:用于配置扫描Repositories所在的包。填写字符串(或字符串数组)形式的包名。
  basePackageClassesbasePackages的安全替代选选项。指定一个要扫描包中的一个类或接口,将扫描所在包中的所有repository
    可以考虑在每个要扫描的包中创建一个类或接口,它除了被这个属性引用外,没有其他用途。
  includeFilters:指定哪些类型的组件被扫描。
  **excludeFilters**:指定哪些类型的组件不被扫描。
  repositoryImplementationPostfix:查找自定义存储库实现时要使用的后缀。默认为Impl。对于名为PersonRepository的存储库,将通过扫描PersonRepositoryImpl来查找相应的实现类。
  namedQueriesLocation:配置Spring-Data的named queries 属性文件的位置,默认META-INF/jpa-named-queries.properties。
  queryLookupStrategy:查询方法的查询策略。默认为QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND。
  repositoryFactoryBeanClass:用于每个存储库实例的FactoryBean类。默认为JpaRepositoryFactoryBean。
  repositoryBaseClass:配置存储库基类,以用于为该特定配置创建存储库代理。
  entityManagerFactoryRef:配置EntityManagerFactory bean定义的名称。默认为entityManagerFactory。
  transactionManagerRef:配置PlatformTransactionManager bean定义的名称。默认为transactionManager。
  considerNestedRepositories:配置是否发现嵌套的Repository接口(如定义为内部类)。默认为false。
 enableDefaultTransactions:配置Spring-Data-Jpa 的Repositories是否启用默认事务,默认为true。如果禁用,则必须在外层使用。
  bootstrapMode:配置在引导生命周期中何时初始化Repository。默认为BootstrapMode.DEFAULT,除了添加了BootstrapMode.LAZY的接口外,其他接口立即初始化。
    BootstrapMode.LAZY,Repository的bean定义被认为是懒加载注入,并且只在首次使用时初始化,即应用程序可能在没有初始化Repository的情况下完全启动。
    BootstrapMode.DEFERRED,Repository的bean定义被认为是懒加载注入,但存储库初始化在应用程序上下文引导完成时触发。
  escapeCharacter:配置在包含contains、startsWith或endsWith子句的派生查询中用于转义 _ 或 % 的通配符字符。

3.目录结构

在这里插入图片描述
测试:
user测试:
根据配置文件application.yml得知usertestdemo数据库中。
在这里插入图片描述
此时数据库没有数据。
在这里插入图片描述
然后执行之前的userTest测试。
在这里插入图片描述
插入成功!

address测试:
根据配置文件application.yml得知addressshop数据库中。
在这里插入图片描述

此时数据库没有数据。
在这里插入图片描述
然后执行之前的contextLoads测试。
在这里插入图片描述

shop数据库查看
在这里插入图片描述
插入成功!

jpa分页条件查询

首先在t_address数据库添加五条数据。
在这里插入图片描述
然后在Address实体类里重写oString方法。

@Overridepublic String toString() {return "Address{" +"province='" + province + '\'' +", city='" + city + '\'' +", county='" + county + '\'' +'}';}

然后进行测试

@Testvoid pageTest(){int pageNum=1;int pageSize=2;Specification<Address> specification =(root, criteriaQuery, criteriaBuilder) -> {//Pridicate:表示一个查询条件List<Predicate> predicates = new ArrayList<>();//创建一个条件集合//获取属性Path<String> rid = root.get("province");//构造查询条件predicates.add(criteriaBuilder.equal(rid,  "四川省"));//必须使用toArray(T[])的有参数方法,因为cq.where(p)中的参数的类型必须是Predicate[]数组类型。//toArray()无参返回的是一个Object类型。//新建数组方式之一:new A[number]return criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()]));};Pageable pageable = PageRequest.of(pageNum - 1, pageSize, Sort.Direction.ASC, "rid");Page<Address> addressPage = addressRepository.findAll(specification, pageable);addressPage.forEach(System.out::println);System.out.println("总页数:"+addressPage.getTotalPages());}

输出:
在这里插入图片描述


http://chatgpt.dhexx.cn/article/lsQSkAZY.shtml

相关文章

Springboot多数据源+Jpa配置

随着业务复杂程度的增加&#xff0c;单一数据源越来越不满足具体的业务逻辑以及实现。 这里我用到了MySQL和Presto两种数据源&#xff1a; 多数据源配置GlobalDataSourceConfiguration&#xff1a; Configuration public class GlobalDataSourceConfiguration {Bean(name …

springboot--jpa 配置多数据库

使用spring boot jpa 配置多数据源 由于项目整合 以前的功能 但是以前功能存储的数据库是另一个数据库 这两天搜索了一下 遇见了许多坑 在这里记录一下 首先附上我的项目结构 可能有些乱 忘见谅。 pom.xml(把数据库的依赖引入) <!-- mariadb --><dependen…

Spring Data Jpa 配置多数据源

文章目录 1.配置数据库连接信息2.编写数据源配置类3.编写数据库配置4.目录结构 1.配置数据库连接信息 spring:datasource:db1: # 1.0 Datasourceurl: jdbc:mysql://127.0.0.1:3306/test1?useSSLfalse&serverTimezoneGMT%2b8&characterEncodingutf8&connectTimeo…

springboot2+JPA 配置多数据源(不同类型数据库)

注意&#xff1a;看此篇文章之前&#xff0c;springbootjpa的配置环境应搭建好&#xff0c;不会搭可以自行百度。本文章主要讲述配置JPA多数据源。 1.数据源配置文件 application.properties # 数据源thirded&#xff08;oracle数据库&#xff09; spring.jpa.thirded.databa…

jpa配置(jpa配置连接池)

JPA的实体状态有哪些呢&#xff1f; 该接口拥有众多执行数据查询的接口方法&#xff1a; Object getSingleResult()&#xff1a;执行SELECT查询语句&#xff0c;并返回一个结果&#xff1b; List getResultList() &#xff1a;执行SELECT查询语句&#xff0c;并返回多个结果&…

SpringBoot系列之数据库初始化-jpa配置方式

上一篇博文介绍如何使用spring.datasource来实现项目启动之后的数据库初始化&#xff0c;本文作为数据库初始化的第二篇&#xff0c;将主要介绍一下&#xff0c;如何使用spring.jpa的配置方式来实现相同的效果 I. 项目搭建 1. 依赖 首先搭建一个标准的SpringBoot项目工程&am…

Jpa环境配置及入门(增删改查)

案例&#xff1a;客户的相关操作&#xff08;增删改查&#xff09; 1.分析&#xff1a; 1.搭建环境&#xff1a; 创建maven工程&#xff0c;导入相关坐标&#xff1b; 配置使用jpa的核心配置文件&#xff1b; 位置&#xff1b;需要配置到类路径下叫做 META-INF的文件夹下 命…

PHP多国语言开发:CodeIgniter 2PHP框架中的多国语言,语言包(i18n)库

PHP多国语言开发&#xff1a;CodeIgniter 2PHP框架中的多国语言&#xff0c;语言包&#xff08;i18n&#xff09;多国语言库 引言 我们在CodeIgniter开发中经常会碰到多国语言网站&#xff0c;这里我们就来介绍一种简单有效的多国语言的操作方法。 做什么 语言在地址中是这…

Win 10 添加多国语言

不同用户对电脑系统的语言需求也不一样&#xff0c;出于工作原因需要使用其它语言&#xff0c;比如外国友人需要使用英语&#xff0c;俄罗斯语言等&#xff0c;此时很多用户都以为要下载对应语言版本的系统&#xff0c;然后重新安装系统&#xff0c;其实Win10是支持多国语言的&…

手工编译Flex SDK 多国语言包

项目需要将目前版本提供给其它地区&#xff1a;台湾、日韩等&#xff0c;面临着项目语言的国际化问题。 语言代号&#xff1a; 大陆&#xff1a;zh_CN 台湾&#xff1a;zh_TW 香港&#xff1a;zh_HK … 例如想支持繁体&#xff0c;没有zh_TW语言包怎么办&#xff1f; fl…

DevExpress去除多国语言包

DevExpress作为windows开发中较为强大的第三方组件&#xff0c;能极大的提高编程效率和界面效果。但也要引用它较多的dll文件&#xff0c;它专门有个查看dll程序集依赖的工具&#xff0c;在VS的工具菜单下&#xff1a; 在VS的工具菜单内有"DevExpress Assembly Deploymen…

关于VS编译DevExpress默认产生几个多余的多国语言包的问题解决

关于VS编译DevExpress默认产生几个多余的多国语言包的问题解决 VS15开始对于非系统的Dll都会默认复制到本地&#xff0c;即bin\debug下面&#xff0c;复制dll到本地好处在于发布的时候不用再去寻找相关dll,对于dev这么庞大的组件来说&#xff0c;更是如此&#xff0c;当然&…

php源码添加多国语言包,为win7系统添加多国语言包的方法

现在使用win7系统的人越来越多了&#xff0c;对于一些需求也是有所增长&#xff0c;很多用户希望能够将自己的操作系统安装成英文&#xff0c;法文&#xff0c;德文等语言&#xff0c;尤其是对经常出去外国出处的用户很有好吃&#xff0c;比如要和外国客户沟通交流时能看的懂自…

laravel框架安装多国语言包

laravel的一些提示信息都是默认英文&#xff0c;想更改为中文需要下载语言包&#xff0c;执行以下命令 composer require caouecs/laravel-lang:~3.0 执行完后将vendor中的caouecs中的src中的zh-CN文件夹放到views的lang文件夹中 然后还要更改配置项&#xff0c;将config里面…

window10c语言下载,[下载备用]Windows 10多国语言包和独立语言包下载

微软在上周发布Windows 10 周年更新版本之前&#xff0c;已经更新了微软支持库中的Windows 10多国语言包。 此次更新的Windows 10 多国语言包已经可以支持到Windows 10 Version 1607版本&#xff0c;也就是Windows 10 周年更新版本。 不过完整的多国语言包含有超过100种语言的独…

Android多国语言包

生成中文名称的APP如下&#xff1a; step1. step2. step3. step4. step5. 以上步骤仅仅是添加values-zh-rCN文件夹&#xff0c;在AS的res中是看不到的&#xff0c;即使同步后。 这是因为里面没有内容&#xff0c;只需要把默认的string.xml copy到刚才的文件夹中&#xff0c;将…

android语言包,安卓系统添加多国语言包

虽然Android 从 2.3 开始已经支持50种以上的语言,但是不是每种语言都有字体可以显示。遇到一个新需求, 有客户要求对 hindi  语言的支持。于是上 网找了一些资料,发现网上介绍的大部分是如何替换默认字体,就 是替换./works//data/fonts /DroidSansFallback.ttf,但是替换完…

invoke和begininvoke的使用

首先说下&#xff0c;invoke和begininvoke的使用有两种情况&#xff1a; 1. control中的invoke、begininvoke。 2. delegrate中的invoke、begininvoke。 这两种情况是不同的&#xff0c;我们这里要讲的是第1种。下面我们在来说下.NET中对invoke和begininvoke的官方定义。 con…

异步编程模式BeginInvoke和EndInvoke方法

转载自&#xff1a;异步编程模式BeginInvoke与EndInvoke方法 为什么要进行异步回调&#xff1f;众所周知&#xff0c;普通方法运行&#xff0c;是单线程的&#xff0c;如果中途有大型操作&#xff08;如&#xff1a;读取大文件&#xff0c;大批量操作数据库&#xff0c;网络传…

C# 异步委托 BeginInvoke EndInvoke

1. 简单主线程中委托: static void Main(string[] args) {//定义一个委托&#xff0c;并初始化Func<int, int, string> delFunc (a, b) > (a b).ToString();//黄色底纹部分换成{ return (a b).ToString(); }更好理解//同步方法调用&#xff08;跟调用一个方法一样…