SpringBoot整合JPA詳細(xì)代碼實(shí)例
1、Spring Data JPA概述
SpringData
:Spring 的一個子項(xiàng)目。用于簡化數(shù)據(jù)庫訪問,支持NoSQL 和 關(guān)系數(shù)據(jù)存儲。其主要目標(biāo)是使數(shù)據(jù)
庫的訪問變得方便快捷。
JPA
:JPA(Java Persistence API,Java持久化API),定義了對象關(guān)系映射(Object Relation Mapping,ORM)以及實(shí)
體對象持久化的標(biāo)準(zhǔn)接口。Hibernate實(shí)現(xiàn)了JPA的一個ORM框架。
JPA Spring Data
:致力于減少數(shù)據(jù)訪問層 (DAO) 的開發(fā)量,開發(fā)者唯一要做的,就只是聲明持久層的接口,
其他都交給 Spring Data JPA 來完成。Spring Data JPA 是Spring基于ORM框架、JPA規(guī)范的基礎(chǔ)上封裝的一套JPA
應(yīng)用框架。
2、SpringBoot整合JPA
2.1 建庫建表
DROP TABLE IF EXISTS student ; CREATE TABLE student ( id int(11) NOT NULL AUTO_INCREMENT, name varchar(100) DEFAULT NULL, sex varchar(100) DEFAULT NULL, age int(11) DEFAULT NULL, PRIMARY KEY ( id ) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
2.2 新建項(xiàng)目
目錄結(jié)構(gòu)如下:
2.3 添加相關(guān)依賴
<?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.5.4</version> <relativePath/> </parent> <groupId>com.jpa.mysql</groupId> <artifactId>spring-data-jpa-mysql</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-data-jpa-mysql</name> <description>spring-data-jpa-mysql</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- jpa 依賴--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!-- lombok 依賴--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
2.4 修改application.properties配置文件
server.port=9000 spring.datasource.driver-class-name=com.mysql.jdbc.Driver spring.datasource.url=jdbc:mysql://127.0.0.1:3306/test spring.datasource.username=root spring.datasource.password=root spring.jpa.show-sql=true spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
2.5 編寫entity
package com.jpa.mysql.entity; import lombok.Data; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Table; import java.io.Serializable; @Data @Entity @Table(name = "student") public class Student implements Serializable { @Id @Column(name="id") private int id; @Column(name="name") private String name; @Column(name="sex") private String sex; @Column(name="age") private int age; }
2.6 編寫dao
package com.jpa.gbase.dao; import com.jpa.gbase.entity.Student; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface StudentDao extends JpaRepository<Student, Integer> { List<Student> findByName(String name); }
2.6 編寫service接口
package com.jpa.gbase.service; import com.jpa.gbase.entity.Student; import org.springframework.stereotype.Component; import java.util.List; @Component public interface IStudentService { Student findById(Integer id); List<Student> findAll(); List<Student> findByName(String name); Student save(String name) throws Exception; void delete(Integer id) throws Exception; }
2.7 編寫service實(shí)現(xiàn)類
package com.jpa.gbase.service.impl; import com.jpa.gbase.dao.StudentDao; import com.jpa.gbase.entity.Student; import com.jpa.gbase.service.IStudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Component public class StudentServiceImpl implements IStudentService { @Autowired private StudentDao studentDao; @Override public Student findById(Integer id) { return studentDao.findById(id).get(); } @Override public List<Student> findAll() { return studentDao.findAll(); } @Override public List<Student> findByName(String name) { return studentDao.findByName(name); } @Override @Transactional public Student save(String name) throws Exception { Student student = new Student(); student.setName(name); student.setSex("M"); student.setAge(18); return studentDao.save(student); } @Override @Transactional public void delete(Integer id) throws Exception { studentDao.deleteById(id); } }
2.8 編寫controller
package com.jpa.gbase.controller; import com.jpa.gbase.entity.Student; import com.jpa.gbase.service.IStudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RestController; import java.util.List; @RestController @RequestMapping(value = "/student") public class StudentController { @Autowired private IStudentService studentService; @GetMapping(value = "/findById/{id}") public Student findById(@PathVariable("id") Integer id) { return studentService.findById(id); } @GetMapping(value = "/findAll") public List<Student> findAll() { return studentService.findAll(); } @GetMapping(value = "/findByName/{name}") public List<Student> findByName(@PathVariable("name") String name) { return studentService.findByName(name); } @GetMapping(value = "/save/{name}") public Student save(@PathVariable("name") String name) { Student student = new Student(); try { student = studentService.save(name); } catch (Exception e) { e.printStackTrace(); } return student; } @GetMapping(value = "/delete/{id}") public boolean delete(@PathVariable("id") Integer id) { boolean flg = false; try { studentService.delete(id); flg = true; } catch (Exception e) { e.printStackTrace(); } return flg; } }
2.9 編寫啟動類
package com.jpa.mysql; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringDataJpaMysqlApplication { public static void main(String[] args) { SpringApplication.run(SpringDataJpaMysqlApplication.class, args); } }
3.測試
3.1 添加數(shù)據(jù)
http://localhost:9000/student/save/tom
3.2 根據(jù)id查詢數(shù)據(jù)
http://localhost:9000/student/findById/1
3.3 根據(jù)名字查詢數(shù)據(jù)
http://localhost:9000/student/findByName/tom
3.4 根據(jù)id刪除數(shù)據(jù)
http://localhost:9000/student/delete/1
3.5 查詢?nèi)繑?shù)據(jù)
http://localhost:9000/student/save/tom1 http://localhost:9000/student/save/tom2 http://localhost:9000/student/save/tom3 http://localhost:9000/student/save/tom4 http://localhost:9000/student/save/tom5 http://localhost:9000/student/findAll
4、簡單查詢
基本查詢也分為兩種,一種是 Spring Data 默認(rèn)已經(jīng)實(shí)現(xiàn),一種是根據(jù)查詢的方法來自動解析成 SQL。
4.1 預(yù)先生成方法
Spring Boot Jpa 默認(rèn)預(yù)先生成了一些基本的CURD的方法,例如:增、刪、改等等
1、繼承 JpaRepository
@Repository public interface StudentDao extends JpaRepository<Student, Integer> { }
2、使用默認(rèn)方法
@Autowired private StudentDao studentDao; studentDao.findAll(); studentDao.findOne(1l); studentDao.save(user); studentDao.delete(user); studentDao.count(); studentDao.exists(1l);
4.2 自定義簡單查詢
自定義的簡單查詢就是根據(jù)方法名來自動生成 SQL。
主要的語法是 findByXX
,readAByXX
,queryByXX
,countByXX
, getByXX
,XX
代表屬性名稱。
Student findByName(String name);
也使用一些加一些關(guān)鍵字And
、 Or
:
User findByNameOrSex(String username, int sex);
修改、刪除、統(tǒng)計也是類似語法:
Long deleteById(Long id); Long countByName(String mame);
基本上 SQL 體系中的關(guān)鍵詞都可以使用,例如:LIKE
、 IgnoreCase
、 OrderBy
。
List<Student> findByNameLike(String name); Student findByNameIgnoreCase(String name); List<Student> findByNameOrderByAgeDesc(String name);
具體的關(guān)鍵字,使用方法和生產(chǎn)成SQL如下表所示:
Keyword | Sample | JPQL snippet |
---|---|---|
And | findByLastnameAndFirstname | … where x.lastname = ?1 and x.firstname = ?2 |
Or | findByLastnameOrFirstname | … where x.lastname = ?1 or x.firstname = ?2 |
Is,Equals | findByFirstnameIs,findByFirstnameEquals | … where x.firstname = ?1 |
Between | findByStartDateBetween | … where x.startDate between ?1 and ?2 |
LessThan | findByAgeLessThan | … where x.age < ?1 |
LessThanEqual | findByAgeLessThanEqual | … where x.age <= ?1 |
GreaterThan | findByAgeGreaterThan | … where x.age > ?1 |
GreaterThanEqual | findByAgeGreaterThanEqual | … where x.age >= ?1 |
After | findByStartDateAfter | … where x.startDate > ?1 |
Before | findByStartDateBefore | … where x.startDate < ?1 |
IsNull | findByAgeIsNull | … where x.age is null |
IsNotNull,NotNull | findByAge(Is)NotNull | … where x.age not null |
Like | findByFirstnameLike | … where x.firstname like ?1 |
NotLike | findByFirstnameNotLike | … where x.firstname not like ?1 |
StartingWith | findByFirstnameStartingWith | … where x.firstname like ?1 (parameter bound with appended %) |
EndingWith | findByFirstnameEndingWith | … where x.firstname like ?1 (parameter bound with prepended %) |
Containing | findByFirstnameContaining | … where x.firstname like ?1 (parameter bound wrapped in %) |
OrderBy | findByAgeOrderByLastnameDesc | … where x.age = ?1 order by x.lastname desc |
Not | findByLastnameNot | … where x.lastname <> ?1 |
In | findByAgeIn(Collection ages) | … where x.age in ?1 |
NotIn | findByAgeNotIn(Collection age) | … where x.age not in ?1 |
TRUE | findByActiveTrue() | … where x.active = true |
FALSE | findByActiveFalse() | … where x.active = false |
IgnoreCase | findByFirstnameIgnoreCase | … where UPPER(x.firstame) = UPPER(?1) |
5、復(fù)雜查詢
在實(shí)際的開發(fā)中我們需要用到分頁、刪選、連表等查詢的時候就需要特殊的方法或者自定義 SQL。
5.1 分頁查詢
分頁查詢在實(shí)際使用中非常普遍了,Spring Boot Jpa 已經(jīng)幫我們實(shí)現(xiàn)了分頁的功能,在查詢的方法中,需要傳入
參數(shù)Pageable
,當(dāng)查詢中有多個參數(shù)的時候Pageable
建議做為最后一個參數(shù)傳入。
Page<Student> findALL(Pageable pageable); Page<Student> findByName(String name,Pageable pageable);
Pageable
是 Spring 封裝的分頁實(shí)現(xiàn)類,使用的時候需要傳入頁數(shù)、每頁條數(shù)和排序規(guī)則。
@Test public void testPageQuery() throws Exception { int page=1,size=10; Sort sort = new Sort(Direction.DESC, "id"); Pageable pageable = new PageRequest(page, size, sort); studentDao.findALL(pageable); studentDao.findByName("tom", pageable); }
5.2 限制查詢
有時候我們只需要查詢前N個元素,或者只取前一個實(shí)體。
Student findFirstByOrderByNameAsc(); Student findTopByOrderByAgeDesc(); Page<Student> queryFirst10ByName(String name, Pageable pageable); List<Student> findFirst10ByName(String name, Sort sort); List<Student> findTop10ByName(String name, Pageable pageable);
5.3 自定義SQL查詢
其實(shí) Spring Data 覺大部分的 SQL 都可以根據(jù)方法名定義的方式來實(shí)現(xiàn),但是由于某些原因我們想使用自定義的
SQL 來查詢,Spring Data 也是完美支持的;在 SQL 的查詢方法上面使用@Query
注解,如涉及到刪除和修改再需
要加上@Modifying
,也可以根據(jù)需要添加 @Transactional
對事物的支持,查詢超時的設(shè)置等。
@Modifying @Query("update student stu set stu.name = ?1 where stu.id = ?2") int modifyNameById(String name, Long id); @Transactional @Modifying @Query("delete from student where id = ?1") void deleteById(Long id); @Transactional(timeout = 10) @Query("select stu from student stu where stu.id = ?1") User findById(Long id);
5.4 多表查詢
多表查詢 Spring Boot Jpa 中有兩種實(shí)現(xiàn)方式,第一種是利用 Hibernate 的級聯(lián)查詢來實(shí)現(xiàn),第二種是創(chuàng)建一個結(jié)
果集的接口來接收連表查詢后的結(jié)果,這里主要第二種方式。
首先需要定義一個結(jié)果集的接口類:
public interface HotelSummary { City getCity(); String getName(); Double getAverageRating(); default Integer getAverageRatingRounded() { return getAverageRating() == null ? null : (int) Math.round(getAverageRating()); } }
查詢的方法返回類型設(shè)置為新創(chuàng)建的接口:
@Query("select h.city as city, h.name as name, avg(r.rating) as averageRating " - "from Hotel h left outer join h.reviews r where h.city = ?1 group by h") Page<HotelSummary> findByCity(City city, Pageable pageable); @Query("select h.name as name, avg(r.rating) as averageRating " - "from Hotel h left outer join h.reviews r group by h") Page<HotelSummary> findByCity(Pageable pageable);
使用:
Page<HotelSummary> hotels = this.hotelRepository.findByCity(new PageRequest(0, 10, Direction.ASC, "name")); for(HotelSummary summay:hotels){ System.out.println("Name" +summay.getName()); }
在運(yùn)行中 Spring 會給接口(HotelSummary)自動生產(chǎn)一個代理類來接收返回的結(jié)果,代碼匯總使用 getXX
的形式來獲取。
6、使用枚舉
使用枚舉的時候,我們希望數(shù)據(jù)庫中存儲的是枚舉對應(yīng)的 String 類型,而不是枚舉的索引值,需要在屬性上面添
加@Enumerated(EnumType.STRING)
注解
@Enumerated(EnumType.STRING) @Column(nullable = true) private UserType type;
7、不需要和數(shù)據(jù)庫映射的屬性
正常情況下我們在實(shí)體類上加入注解@Entity
,就會讓實(shí)體類和表相關(guān)連如果其中某個屬性我們不需要和數(shù)據(jù)庫
來關(guān)聯(lián)只是在展示的時候做計算,只需要加上@Transient
屬性既可。
@Transient private String userName;
8、多數(shù)據(jù)源的支持
8.1 同源數(shù)據(jù)庫的多源支持
日常項(xiàng)目中因?yàn)槭褂玫姆植际介_發(fā)模式,不同的服務(wù)有不同的數(shù)據(jù)源,常常需要在一個項(xiàng)目中使用多個數(shù)據(jù)源,因
此需要配置 Spring Boot Jpa 對多數(shù)據(jù)源的使用,一般分一下為三步:
1 配置多數(shù)據(jù)源
2 不同源的實(shí)體類放入不同包路徑
3 聲明不同的包路徑下使用不同的數(shù)據(jù)源、事務(wù)支持
8.2 異構(gòu)數(shù)據(jù)庫多源支持
比如我們的項(xiàng)目中,即需要對 mysql 的支持,也需要對 Mongodb 的查詢等。
實(shí)體類聲明@Entity
關(guān)系型數(shù)據(jù)庫支持類型,聲明@Document
為 Mongodb 支持類型,不同的數(shù)據(jù)源使用不同的
實(shí)體就可以了。
interface PersonRepository extends Repository<Person, Long> { … } @Entity public class Person { … } interface UserRepository extends Repository<User, Long> { … } @Document public class User { … }
但是,如果 User 用戶既使用 Mysql 也使用 Mongodb 呢,也可以做混合使用。
interface JpaPersonRepository extends Repository<Person, Long> { … } interface MongoDBPersonRepository extends Repository<Person, Long> { … } @Entity @Document public class Person { … }
也可以通過對不同的包路徑進(jìn)行聲明,比如 A 包路徑下使用 mysql,B 包路徑下使用 MongoDB。
@EnableJpaRepositories(basePackages = "com.neo.repositories.jpa") @EnableMongoRepositories(basePackages = "com.neo.repositories.mongo") interface Configuration { }
9、多數(shù)據(jù)源使用案例
9.1 導(dǎo)入pom依賴
<?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.5.4</version> <relativePath/> </parent> <groupId>com.example</groupId> <artifactId>spring-boot-multi-jpa</artifactId> <version>0.0.1-SNAPSHOT</version> <name>spring-boot-multi-jpa</name> <description>spring-boot-multi-Jpa</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- lombok 依賴--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
9.2 配置文件
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.primary.username=root spring.datasource.primary.password=root spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=true spring.datasource.secondary.username=root spring.datasource.secondary.password=root spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver spring.jpa.show-sql=true spring.jpa.properties.hibernate.hbm2ddl.auto=create spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect spring.jpa.properties.hibernate.format_sql=true
9.3 實(shí)體類
package com.example.springbootmultijpa.model; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; import javax.persistence.*; import java.io.Serializable; @Getter @Setter @Entity @NoArgsConstructor @AllArgsConstructor public class User implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "id") private long id; @Column(nullable = false, unique = true) private String userName; @Column(nullable = false) private String passWord; @Column(nullable = false, unique = true) private String email; @Column(nullable = true, unique = true) private String nickName; @Column(nullable = false) private String regTime; public User(String userName, String passWord, String email, String nickName, String regTime) { this.userName = userName; this.passWord = passWord; this.email = email; this.nickName = nickName; this.regTime = regTime; } }
9.4 config
package com.example.springbootmultijpa.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import javax.sql.DataSource; import java.util.Map; @Configuration public class DataSourceConfig { @Autowired private JpaProperties jpaProperties; @Autowired private HibernateProperties hibernateProperties; @Bean(name = "primaryDataSource") @Primary @ConfigurationProperties("spring.datasource.primary") public DataSource firstDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties("spring.datasource.secondary") public DataSource secondDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "vendorProperties") public Map<String, Object> getVendorProperties() { return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings()); } }
package com.example.springbootmultijpa.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactoryPrimary", transactionManagerRef = "transactionManagerPrimary", basePackages = {"com.example.springbootmultijpa.repository.test1"})//設(shè)置dao(repo)所在位置 public class PrimaryConfig { @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Autowired @Qualifier("vendorProperties") private Map<String, Object> vendorProperties; @Bean(name = "entityManagerFactoryPrimary") @Primary public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) { return builder .dataSource(primaryDataSource) .properties(vendorProperties) .packages("com.example.springbootmultijpa.model") //設(shè)置實(shí)體類所在位置 .persistenceUnit("primaryPersistenceUnit") .build(); } @Bean(name = "entityManagerPrimary") @Primary public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Bean(name = "transactionManagerPrimary") @Primary PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
package com.example.springbootmultijpa.config; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.persistence.EntityManager; import javax.sql.DataSource; import java.util.Map; @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactorySecondary", transactionManagerRef = "transactionManagerSecondary", basePackages = {"com.example.springbootmultijpa.repository.test2"}) public class SecondaryConfig { @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Autowired @Qualifier("vendorProperties") private Map<String, Object> vendorProperties; @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) { return builder .dataSource(secondaryDataSource) .properties(vendorProperties) .packages("com.example.springbootmultijpa.model") .persistenceUnit("secondaryPersistenceUnit") .build(); } @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
9.5 Repository
package com.example.springbootmultijpa.repository.test1; import com.example.springbootmultijpa.model.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserTest1Repository extends JpaRepository<User, Long> { User findById(long id); User findByUserName(String userName); User findByUserNameOrEmail(String username, String email); }
package com.example.springbootmultijpa.repository.test2; import com.example.springbootmultijpa.model.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserTest2Repository extends JpaRepository<User, Long> { User findById(long id); User findByUserName(String userName); User findByUserNameOrEmail(String username, String email); }
9.6 啟動類
package com.example.springbootmultijpa; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication public class SpringBootMultiJpaApplication { public static void main(String[] args) { SpringApplication.run(SpringBootMultiJpaApplication.class, args); } }
9.7 測試
package com.example.springbootmultijpa.repository; import com.example.springbootmultijpa.model.User; import com.example.springbootmultijpa.repository.test1.UserTest1Repository; import com.example.springbootmultijpa.repository.test2.UserTest2Repository; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import javax.annotation.Resource; import java.text.DateFormat; import java.util.Date; @RunWith(SpringRunner.class) @SpringBootTest public class UserRepositoryTests { @Resource private UserTest1Repository userTest1Repository; @Resource private UserTest2Repository userTest2Repository; @Test public void testSave() throws Exception { Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); String formattedDate = dateFormat.format(date); userTest1Repository.save(new User("aa", "aa123456", "aa@126.com", "aa", formattedDate)); userTest1Repository.save(new User("bb", "bb123456", "bb@126.com", "bb", formattedDate)); userTest2Repository.save(new User("cc", "cc123456", "cc@126.com", "cc", formattedDate)); } @Test public void testDelete() throws Exception { userTest1Repository.deleteAll(); userTest2Repository.deleteAll(); } @Test public void testBaseQuery() { Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.LONG, DateFormat.LONG); String formattedDate = dateFormat.format(date); User user = new User("ff", "ff123456", "ff@126.com", "ff", formattedDate); userTest1Repository.findAll(); userTest2Repository.findById(3l); userTest2Repository.save(user); user.setId(2l); userTest1Repository.delete(user); userTest1Repository.count(); userTest2Repository.findById(3l); } }
運(yùn)行testSave()
得到的結(jié)果:
運(yùn)行testBaseQuery()
得到的結(jié)果:
運(yùn)行testDelete()
得到的結(jié)果:
總結(jié)
到此這篇關(guān)于SpringBoot整合JPA的文章就介紹到這了,更多相關(guān)SpringBoot整合JPA內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例
這篇文章主要介紹了Spring Data Jpa 自動生成表結(jié)構(gòu)的方法示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java對象轉(zhuǎn)Json,關(guān)于@JSONField對象字段重命名和順序問題
這篇文章主要介紹了Java對象轉(zhuǎn)Json,關(guān)于@JSONField對象字段重命名和順序問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-08-08用html css javascript打造自己的RIA圖文教程
用html&css&javascript打造自己的RIA之一,包括了配置等2009-07-07使用Spring @DependsOn控制bean加載順序的實(shí)例
這篇文章主要介紹了使用Spring @DependsOn控制bean加載順序的實(shí)例講解,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2021-07-07IntelliJ-Idea導(dǎo)出可執(zhí)行Jar流程解析
這篇文章主要介紹了IntelliJ-Idea導(dǎo)出可執(zhí)行Jar流程解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-12-12Spring?Security過濾器鏈加載執(zhí)行流程源碼解析
Spring?Boot?對于?Spring?Security?提供了自動化配置方案,可以使用更少的配置來使用?Spring?Security。那么這個過濾器鏈?zhǔn)窃趺醇虞d和實(shí)現(xiàn)攔截的呢,對Spring?Security過濾器鏈加載執(zhí)行流程感興趣的朋友一起看看吧2021-12-12