微服務作為Java技術圈最火的技術架構,所以核心SpringBoot作為最基礎單元值得我們好好研究。
PG作為數據庫圈最全面的數據庫,有著全站型數據庫之稱。
在下面這篇文章中,我將介紹如何使用SpringBoot2.0+SpringDataJPA+PostgreSQL構建一個。
我們將使用到如下技術和工具:
首先我們創建一個SpringBoot+SpringDataJPA(先使用H2內存數據庫構建)
1.項目目錄
2. Maven構建
pom.xml 文件中的依賴
<code>
<project> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
\t\t http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0/<modelversion>
<artifactid>spring-data-jpa/<artifactid>
<packaging>jar/<packaging>
<name>Spring Boot Spring Data JPA/<name>
<version>1.0/<version>
<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>2.1.2.RELEASE/<version>
/<parent>
<properties>
<java.version>1.8/<java.version>
<downloadsources>true/<downloadsources>
<downloadjavadocs>true/<downloadjavadocs>
/<properties>
<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-data-jpa/<artifactid>
/<dependency>
<dependency>
<groupid>com.h2database/<groupid>
<artifactid>h2/<artifactid>
/<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>
/<plugin>
<plugin>
<groupid>org.apache.maven.plugins/<groupid>
<artifactid>maven-surefire-plugin/<artifactid>
<version>2.22.0/<version>
/<plugin>
/<plugins>
/<build>
/<project>/<code>
3. 構建Spring Data JPA
Book.java
<code>package com.mkyong;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Book {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public Book() {
}
public Book(String name) {
this.name = name;
}
//getters, setters, toString...
}
複製/<code>
BookRepository.java
<code>package com.mkyong;
import org.springframework.data.repository.CrudRepository;
import java.util.List;
public interface BookRepository extends CrudRepository<book> {
List<book> findByName(String name);
/<book>/<book>/<code>
4. @SpringBootApplication啟動
4.1啟動Spring Boot,將3本書插入H2數據庫,然後測試該find()方法。
StartApplication.java
<code>package com.mkyong;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class StartApplication implements CommandLineRunner {
private static final Logger log = LoggerFactory.getLogger(StartApplication.class);
@Autowired
private BookRepository repository;
public static void main(String[] args) {
SpringApplication.run(StartApplication.class, args);
}
@Override
public void run(String... args) {
log.info("StartApplication...");
repository.save(new Book("Java"));
repository.save(new Book("Node"));
repository.save(new Book("Python"));
System.out.println("\\nfindAll()");
repository.findAll().forEach(x -> System.out.println(x));
System.out.println("\\nfindById(1L)");
repository.findById(1l).ifPresent(x -> System.out.println(x));
System.out.println("\\nfindByName('Node')");
repository.findByName("Node").forEach(x -> System.out.println(x));
}
}/<code>
5. 使用HikariCP連接池
默認情況下,Spring Boot 2使用HikariCP作為默認連接池。
5.1啟用com.zaxxer調試的日誌記錄級別,它將打印出默認的HikariCP配置。
application.properties
<code>logging.level.org.springframework=INFO
logging.level.com.mkyong=INFO
logging.level.com.zaxxer=DEBUG
logging.level.root=ERROR/<code>
5.2運行Spring Boot,查看日誌:
<code>DEBUG com.zaxxer.hikari.HikariConfig - Driver class org.h2.Driver found in Thread context class loader jdk.internal.loader.ClassLoaders$AppClassLoader@28c97a5
DEBUG com.zaxxer.hikari.HikariConfig - HikariPool-1 - configuration:
DEBUG com.zaxxer.hikari.HikariConfig - allowPoolSuspension.............false
DEBUG com.zaxxer.hikari.HikariConfig - autoCommit......................true
DEBUG com.zaxxer.hikari.HikariConfig - catalog.........................none
DEBUG com.zaxxer.hikari.HikariConfig - connectionInitSql...............none
DEBUG com.zaxxer.hikari.HikariConfig - connectionTestQuery.............none
DEBUG com.zaxxer.hikari.HikariConfig - connectionTimeout...............30000
DEBUG com.zaxxer.hikari.HikariConfig - dataSource......................none
DEBUG com.zaxxer.hikari.HikariConfig - dataSourceClassName.............none
DEBUG com.zaxxer.hikari.HikariConfig - dataSourceJNDI..................none
DEBUG com.zaxxer.hikari.HikariConfig - dataSourceProperties............{password=<masked>}
DEBUG com.zaxxer.hikari.HikariConfig - driverClassName................."org.h2.Driver"
DEBUG com.zaxxer.hikari.HikariConfig - healthCheckProperties...........{}
DEBUG com.zaxxer.hikari.HikariConfig - healthCheckRegistry.............none
DEBUG com.zaxxer.hikari.HikariConfig - idleTimeout.....................600000
DEBUG com.zaxxer.hikari.HikariConfig - initializationFailTimeout.......1
DEBUG com.zaxxer.hikari.HikariConfig - isolateInternalQueries..........false
DEBUG com.zaxxer.hikari.HikariConfig - jdbcUrl.........................jdbc:h2:mem:testdb;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=FALSE
DEBUG com.zaxxer.hikari.HikariConfig - leakDetectionThreshold..........0
DEBUG com.zaxxer.hikari.HikariConfig - maxLifetime.....................1800000
DEBUG com.zaxxer.hikari.HikariConfig - maximumPoolSize.................10
DEBUG com.zaxxer.hikari.HikariConfig - metricRegistry..................none
DEBUG com.zaxxer.hikari.HikariConfig - metricsTrackerFactory...........none
DEBUG com.zaxxer.hikari.HikariConfig - minimumIdle.....................10
DEBUG com.zaxxer.hikari.HikariConfig - password........................<masked>
DEBUG com.zaxxer.hikari.HikariConfig - poolName........................"HikariPool-1"
DEBUG com.zaxxer.hikari.HikariConfig - readOnly........................false
DEBUG com.zaxxer.hikari.HikariConfig - registerMbeans..................false
DEBUG com.zaxxer.hikari.HikariConfig - scheduledExecutor...............none
DEBUG com.zaxxer.hikari.HikariConfig - schema..........................none
DEBUG com.zaxxer.hikari.HikariConfig - threadFactory...................internal
DEBUG com.zaxxer.hikari.HikariConfig - transactionIsolation............default
DEBUG com.zaxxer.hikari.HikariConfig - username........................"sa"
DEBUG com.zaxxer.hikari.HikariConfig - validationTimeout...............5000
INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Starting...
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:testdb user=SA
INFO com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Start completed.
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Pool stats (total=1, active=0, idle=1, waiting=0)
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn1: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn2: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn3: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn4: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn5: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn6: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn7: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn8: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - Added connection conn9: url=jdbc:h2:mem:testdb user=SA
DEBUG com.zaxxer.hikari.pool.HikariPool - HikariPool-1 - After adding stats (total=10, active=0, idle=10, waiting=0)
複製/<masked>/<masked>/<code>
5.2我們可以使用spring.datasource.hikari.*覆蓋默認設置。
application.properties
<code>logging.level.org.springframework=INFO
logging.level.com.mkyong=INFO
logging.level.com.zaxxer=DEBUG
logging.level.root=ERROR
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
spring.datasource.hikari.poolName=HikariPoolZZZ
複製/<code>
6.單元測試
6.1 @DataJpaTest並TestEntityManager測試一個Spring數據JPA存儲庫。
BookRepositoryTest.java
<code>package com.mkyong;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;
import org.springframework.boot.test.autoconfigure.orm.jpa.TestEntityManager;
import org.springframework.test.context.junit4.SpringRunner;
import java.util.List;
import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.Assert.assertEquals;
@RunWith(SpringRunner.class)
@DataJpaTest
public class BookRepositoryTest {
@Autowired
private TestEntityManager entityManager;
@Autowired
private BookRepository repository;
@Test
public void testFindByName() {
entityManager.persist(new Book("C++"));
List<book> books = repository.findByName("C++");
assertEquals(1, books.size());
assertThat(books).extracting(Book::getName).containsOnly("C++");
}
}
複製/<book>/<code>
7.演示
<code>$ mvn spring-boot:run
INFO com.mkyong.StartApplication - Started StartApplication in 2.79 seconds (JVM running for 10.883)
INFO com.mkyong.StartApplication - StartApplication...
findAll()
DEBUG com.zaxxer.hikari.pool.PoolBase - HikariPoolZZZ - Reset (readOnly) on connection conn0: url=jdbc:h2:mem:testdb user=SA
Book{id=1, name='Java'}
Book{id=2, name='Node'}
Book{id=3, name='Python'}
findById(1L)
DEBUG com.zaxxer.hikari.pool.PoolBase - HikariPoolZZZ - Reset (readOnly) on connection conn0: url=jdbc:h2:mem:testdb user=SA
Book{id=1, name='Java'}
findByName('Node')
Book{id=2, name='Node'}/<code>
到這裡構建一個SpringBoot+SpringDataJPA的框架已經完成,但是這裡使用的H2內存數據庫,下面我們要將H2數據庫轉換成PostgreSQL數據庫。
pom.xml修改添加
<code>\t<dependency>
\t\t<groupid>org.postgresql/<groupid>
\t\t<artifactid>postgresql/<artifactid>
\t/<dependency>/<code>
1. Maven
pom.xml
<code>
<project> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
\t\t http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelversion>4.0.0/<modelversion>
<artifactid>spring-boot-data-jpa/<artifactid>
<packaging>jar/<packaging>
<name>Spring Boot Spring Data JPA/<name>
<version>1.0/<version>
<parent>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-parent/<artifactid>
<version>2.1.2.RELEASE/<version>
/<parent>
<properties>
<java.version>1.8/<java.version>
<downloadsources>true/<downloadsources>
<downloadjavadocs>true/<downloadjavadocs>
/<properties>
<dependencies>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-data-jpa/<artifactid>
/<dependency>
<dependency>
<groupid>org.postgresql/<groupid>
<artifactid>postgresql/<artifactid>
/<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>
/<plugin>
<plugin>
<groupid>org.apache.maven.plugins/<groupid>
<artifactid>maven-surefire-plugin/<artifactid>
<version>2.22.0/<version>
/<plugin>
/<plugins>
/<build>
/<project>/<code>
2. 配置 PostgreSQL數據庫
application.properties
<code>## default connection pool
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
## PostgreSQL
spring.datasource.url=jdbc:postgresql://localhost:5432/postgres
spring.datasource.username=postgres
spring.datasource.password=password
#drop n create table again, good for testing, comment this in production
spring.jpa.hibernate.ddl-auto=create/<code>
最後 源碼下載地址:
https://github.com/mkyong/spring-boot.git閱讀更多 程序style 的文章
關鍵字: PostgreSQL 數據庫 XML