我应该如何使用 Spring Boot 创建 H2?
How should I create H2 using SpringBoot?
我开始玩 Spring Boot,作为其中的一部分,我想创建一个内存中的 DB 来处理 bootstrap 应用程序。
鉴于下面的 config/code 我在启动日志中没有发现任何错误并且可以正常访问应用程序,所以它确实启动了(我得到关于对象不存在的模板错误),但我没有得到任何调用 findAll() 时从 DAO 返回数据(或者如果我尝试调用 findById(int) )。
所以虽然看起来一切正常(日志中没有错误,日志显示它发现 sql 创建模式广告尝试 运行 data.sql 语句)当我尝试通过 DAO 访问数据时没有出现异常,但没有返回数据。
对可能存在问题的代码有任何想法或观察吗?
我已经将 Spring 数据/H2 内容添加到我的 pom 中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Spring DAO:
public interface PersonDao extends CrudRepository<Person, Integer> {
}
application.properties 中的数据库道具:
server.contextPath=/
server.port=8080
spring.mvc.view.suffix=.ftl
datasource.mine.jdbcUrl=jdbc:h2:tcp://localhost/mem:clubmanagement
datasource.mine.user=sa
datasource.mine.password=
datasource.mine.poolSize=30
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.hibernate.ddl-auto=create
我的服务:
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
PersonDao dao;
@Override
public Optional<ClubMember> getClubMember(int id) {
Person dbPerson = dao.findOne(id);
if(dbPerson == null) {
return Optional.empty();
}
return Optional.of(fromEntity(dbPerson));
}
@Override
public List<ClubMember> allMembers() {
Iterable<Person> people = dao.findAll();
List<ClubMember> members = new ArrayList<>();
people.forEach(person -> {
members.add(fromEntity(person));
});
return members;
}
private ClubMember fromEntity(Person p) {
ClubMember member = new ClubMember();
member.setCurrentGrade(p.getCurrentGrade());
member.setFirstName(p.getFirstName());
member.setLastName(p.getLastName());
member.setAssociationMemberId(p.getAssociationMemberId());
member.setLastGradingDate(p.getLastGradingDate());
return member;
}
}
Schema.sql 在资源/ :
create table CLUB
(id int not null, name varchar(60), association_member_id int);
create table PERSON
(
id int not null, grade_id int, first_name varchar(35), last_name varchar(35),
association_membership varchar(12), last_grading_date date
);
create table GRADE
(id int not null, name varchar(20));
在data.sql中(同样在资源目录中):
insert into club (id, name, association_member_id) values (1, 'some club', '123');
insert into person (id, grade_id, first_name, last_name, association_membership, last_grading_date)
values (1, 1, 'name', 'lastname', 'a1234', '2016-03-23');
实体 class 我正在尝试检索(尝试使用对我来说也是新手的 Lombock 来生成 getters/setters):
@Entity
@Table(name = "person")
public @Data class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@JoinColumn(name = "grade_id")
private GRADE currentGrade;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "association_membership")
private String associationMemberId;
@Column(name = "last_grading_date")
@Temporal(value = TemporalType.DATE)
private Date lastGradingDate;
}
你想添加H2数据库,但是你添加了HSQLDB,请替换
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
和
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
编辑
我注意到您的代码中存在多个问题:
- 默认架构文件名是 schema.sql 而不是 Schema.sql
- schema.sql 中的表名与 data.sql 中的表名不同(人对人)
- 您在 application.properties(默认选项)中使用了此
spring.jpa.hibernate.ddl-auto=create
,在这种情况下,将仅自动创建 JPA 数据库架构(不创建数据) ,所以 data.sql 不会被执行,要解决这个问题,您可以使用 validate
或 update
选项
我将编写一个简单的示例,说明如何通过 spring 引导和 JPA
使用 H2 数据库
这是项目结构:
实体等级
package com.shijazi;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="GRADE")
public class Grade {
@Id
@GeneratedValue
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Grade() {
}
}
GradeRepository.java
package com.shijazi;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GradeRepository extends JpaRepository<Grade, Integer> {
}
Application.java
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private GradeRepository gradeRepo;
@RequestMapping(value="api/test")
public List<Grade> getall()
{
return gradeRepo.findAll();
}
}
application.properties
spring.jpa.hibernate.ddl-auto=validate
schema.sql
create table GRADE (id int not null, name varchar(20));
data.sql
insert into GRADE (id, name) values (2, 'name');
pom.xml
中的依赖项
<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.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
现在只需 运行 应用程序并调用此 URL:http://localhost:8080/api/test
尝试更改 spring.jpa.hibernate.ddl-auto
并查看结果
如果你激活 ddl-auto 并有一个 schema.sql,它们都会被执行。但通常先执行 schema.sql 。所以 ddl-auto 丢弃了由 schema.sql 和 data.sql
创建的所有内容
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
只是给你一个 spring 引导自以为是的包含到 spring-boot-starter-data-jpa
maven 文件中,用于 material 所有依赖项的清单。要使用 spring-boot-starter-data-jpa
pom 的依赖管理中定义的任何一个依赖,您必须在 pom 文件的依赖部分明确声明依赖。
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
要启动 h2 数据库和 运行 您的应用程序,您可以在 src/main/resources/application.properties
的 application.properties 文件中指定属性,使用:
spring.h2.console.enabled=true
spring.h2.console.path=/h2DB
因此,当您 运行 您的应用程序带有 spring 应用程序启动器时,您将能够在 http://localhost:8080/h2DB
登录数据库时访问该应用程序,并且您可以验证数据库是否具有插入与否?
如果没有在其中找到数据,那么您知道在哪里进行更改以将数据保留在那里。
在与@Safwan Hijazi 聊天讨论了一些想法后,得出的结论是 schema.sql 和 data.sql 正在 运行 但是然后根据 spring.jpa.hibernate.ddl-auto 属性.
的值(或缺少)重新创建模式
如果未指定,它们之间的 spring/hibernate 最终会重新创建一个空模式(默认似乎是内存数据库中的 create-drop)。
如果设置 'none' 则不会发生这种情况,由模式和数据 sql 脚本创建的数据库将保留并且应用程序正常运行。
另请参阅:
我开始玩 Spring Boot,作为其中的一部分,我想创建一个内存中的 DB 来处理 bootstrap 应用程序。
鉴于下面的 config/code 我在启动日志中没有发现任何错误并且可以正常访问应用程序,所以它确实启动了(我得到关于对象不存在的模板错误),但我没有得到任何调用 findAll() 时从 DAO 返回数据(或者如果我尝试调用 findById(int) )。
所以虽然看起来一切正常(日志中没有错误,日志显示它发现 sql 创建模式广告尝试 运行 data.sql 语句)当我尝试通过 DAO 访问数据时没有出现异常,但没有返回数据。
对可能存在问题的代码有任何想法或观察吗?
我已经将 Spring 数据/H2 内容添加到我的 pom 中:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
Spring DAO:
public interface PersonDao extends CrudRepository<Person, Integer> {
}
application.properties 中的数据库道具:
server.contextPath=/
server.port=8080
spring.mvc.view.suffix=.ftl
datasource.mine.jdbcUrl=jdbc:h2:tcp://localhost/mem:clubmanagement
datasource.mine.user=sa
datasource.mine.password=
datasource.mine.poolSize=30
logging.level.org.springframework.web=DEBUG
logging.level.org.hibernate=DEBUG
spring.jpa.hibernate.ddl-auto=create
我的服务:
@Service
public class MemberServiceImpl implements MemberService {
@Autowired
PersonDao dao;
@Override
public Optional<ClubMember> getClubMember(int id) {
Person dbPerson = dao.findOne(id);
if(dbPerson == null) {
return Optional.empty();
}
return Optional.of(fromEntity(dbPerson));
}
@Override
public List<ClubMember> allMembers() {
Iterable<Person> people = dao.findAll();
List<ClubMember> members = new ArrayList<>();
people.forEach(person -> {
members.add(fromEntity(person));
});
return members;
}
private ClubMember fromEntity(Person p) {
ClubMember member = new ClubMember();
member.setCurrentGrade(p.getCurrentGrade());
member.setFirstName(p.getFirstName());
member.setLastName(p.getLastName());
member.setAssociationMemberId(p.getAssociationMemberId());
member.setLastGradingDate(p.getLastGradingDate());
return member;
}
}
Schema.sql 在资源/ :
create table CLUB
(id int not null, name varchar(60), association_member_id int);
create table PERSON
(
id int not null, grade_id int, first_name varchar(35), last_name varchar(35),
association_membership varchar(12), last_grading_date date
);
create table GRADE
(id int not null, name varchar(20));
在data.sql中(同样在资源目录中):
insert into club (id, name, association_member_id) values (1, 'some club', '123');
insert into person (id, grade_id, first_name, last_name, association_membership, last_grading_date)
values (1, 1, 'name', 'lastname', 'a1234', '2016-03-23');
实体 class 我正在尝试检索(尝试使用对我来说也是新手的 Lombock 来生成 getters/setters):
@Entity
@Table(name = "person")
public @Data class Person {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "id")
private int id;
@JoinColumn(name = "grade_id")
private GRADE currentGrade;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "association_membership")
private String associationMemberId;
@Column(name = "last_grading_date")
@Temporal(value = TemporalType.DATE)
private Date lastGradingDate;
}
你想添加H2数据库,但是你添加了HSQLDB,请替换
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
<scope>runtime</scope>
</dependency>
和
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
编辑
我注意到您的代码中存在多个问题:
- 默认架构文件名是 schema.sql 而不是 Schema.sql
- schema.sql 中的表名与 data.sql 中的表名不同(人对人)
- 您在 application.properties(默认选项)中使用了此
spring.jpa.hibernate.ddl-auto=create
,在这种情况下,将仅自动创建 JPA 数据库架构(不创建数据) ,所以 data.sql 不会被执行,要解决这个问题,您可以使用validate
或update
选项
我将编写一个简单的示例,说明如何通过 spring 引导和 JPA
使用 H2 数据库这是项目结构:
实体等级
package com.shijazi;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="GRADE")
public class Grade {
@Id
@GeneratedValue
private int id;
private String name;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Grade(int id, String name) {
super();
this.id = id;
this.name = name;
}
public Grade() {
}
}
GradeRepository.java
package com.shijazi;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
@Repository
public interface GradeRepository extends JpaRepository<Grade, Integer> {
}
Application.java
@SpringBootApplication
@RestController
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
@Autowired
private GradeRepository gradeRepo;
@RequestMapping(value="api/test")
public List<Grade> getall()
{
return gradeRepo.findAll();
}
}
application.properties
spring.jpa.hibernate.ddl-auto=validate
schema.sql
create table GRADE (id int not null, name varchar(20));
data.sql
insert into GRADE (id, name) values (2, 'name');
pom.xml
中的依赖项<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.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
现在只需 运行 应用程序并调用此 URL:http://localhost:8080/api/test
尝试更改 spring.jpa.hibernate.ddl-auto
并查看结果
如果你激活 ddl-auto 并有一个 schema.sql,它们都会被执行。但通常先执行 schema.sql 。所以 ddl-auto 丢弃了由 schema.sql 和 data.sql
创建的所有内容<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
只是给你一个 spring 引导自以为是的包含到 spring-boot-starter-data-jpa
maven 文件中,用于 material 所有依赖项的清单。要使用 spring-boot-starter-data-jpa
pom 的依赖管理中定义的任何一个依赖,您必须在 pom 文件的依赖部分明确声明依赖。
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
</dependency>
要启动 h2 数据库和 运行 您的应用程序,您可以在 src/main/resources/application.properties
的 application.properties 文件中指定属性,使用:
spring.h2.console.enabled=true
spring.h2.console.path=/h2DB
因此,当您 运行 您的应用程序带有 spring 应用程序启动器时,您将能够在 http://localhost:8080/h2DB
登录数据库时访问该应用程序,并且您可以验证数据库是否具有插入与否?
如果没有在其中找到数据,那么您知道在哪里进行更改以将数据保留在那里。
在与@Safwan Hijazi 聊天讨论了一些想法后,得出的结论是 schema.sql 和 data.sql 正在 运行 但是然后根据 spring.jpa.hibernate.ddl-auto 属性.
的值(或缺少)重新创建模式如果未指定,它们之间的 spring/hibernate 最终会重新创建一个空模式(默认似乎是内存数据库中的 create-drop)。
如果设置 'none' 则不会发生这种情况,由模式和数据 sql 脚本创建的数据库将保留并且应用程序正常运行。
另请参阅: