我应该如何使用SpringBoot创建H2?

时间:2016-07-11 12:37:30

标签: spring hibernate spring-boot spring-data h2

我开始玩Spring Boot,作为其中的一部分,我想创建一个内存数据库来与应用程序一起使用和引导程序。

鉴于下面的配置/代码,我在启动日志中没有错误,并且可以访问应用程序,所以它确实启动(我得到关于不存在的对象的模板错误),但我没有从中获取任何数据调用findAll()时的DAO(或者如果我尝试调用findById(int))。

因此,虽然事情似乎没事(日志中没有错误,日志显示它找到sql来创建架构广告尝试运行data.sql语句)当我尝试通过DAO访问数据时我没有得到异常,但是没有数据返回。

对代码可能有问题的任何想法或观察?

我已将Spring Data / 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>

春天DAO:

public interface PersonDao extends CrudRepository<Person, Integer> {
}

application.properties中的DB道具:

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');

我正在尝试检索的实体类(尝试使用Lombock,对我来说也是新手,以生成getter / setter):

@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;
}

3 个答案:

答案 0 :(得分:6)

你想添加H2数据库,但你添加了HSQLDB,请替换

<dependency>
        <groupId>org.hsqldb</groupId>
        <artifactId>hsqldb</artifactId>
        <scope>runtime</scope>
    </dependency>

<dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
        </dependency>

修改

我注意到您的代码中存在多个问题:

  1. 默认架构文件名是schema.sql而不是Schema.sql
  2. schema.sql中表的名称与data.sql中的名称不同(PERSON vs person)
  3. 您在application.properties(默认选项)中使用了此spring.jpa.hibernate.ddl-auto=create,在这种情况下,将仅自动创建JPA数据库架构(无数据创建),因此data.sql不会执行,要解决此问题,您可以使用validateupdate选项
  4. 我将写一个简单的例子,说明如何使用带有spring boot和JPA的H2数据库

    这是项目结构:

    enter image description here

    成绩实体

    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>
    

    现在只需运行应用程序并调用此网址:http://localhost:8080/api/test

    尝试更改spring.jpa.hibernate.ddl-auto并查看结果

    如果你激活ddl-auto并且有一个schema.sql,那么它们就会被执行。但通常先执行schema.sql。所以ddl-auto抛出一切,这是由schema.sql和data.sql

    创建的

答案 1 :(得分:1)

花了一些时间与@Safwan Hijazi在聊天中讨论一些想法后,得出的结论是,正在运行schema.sql和data.sql,然后根据值重新创建模式(或者缺少spring.jpa.hibernate.ddl-auto属性。

如果没有指定,它们之间的spring / hibernate最终会重新创建一个空模式(在内存DB中默认似乎是create-drop)。

如果设置&#39;无&#39;然后就不会发生这种情况,由架构和数据sql脚本创建的DB将保留,并且应用程序正常运行。

另请参阅:CrudRepository not reading data from schema.sql

答案 2 :(得分:0)

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

为了spring-boot-starter-data-jpa maven文件,为了所有依赖项的物料清单,给你一个春季启示意见。要使用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登录到数据库时访问应用程序,并且您可以验证数据库是否包含插入数据?

在那里找不到数据,然后你知道在哪里进行更改以保存数据。