代码之家  ›  专栏  ›  技术社区  ›  DaFoot

如何使用SpringBoot创建H2?

  •  1
  • DaFoot  · 技术社区  · 9 年前

    我开始玩SpringBoot,作为其中的一部分,我想创建一个内存中的DB来使用和引导应用程序。

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

    因此,当我尝试通过DAO访问数据时,虽然看起来一切正常(日志中没有错误,但日志显示它会找到用于创建模式的sql,并尝试运行data.sql语句),但我没有收到异常,但没有返回数据。

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

    我已将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>
    

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

    应用程序属性中的数据库属性:

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

    架构。资源/中的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));
    

    在数据中。sql(同样在resources目录中):

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

    @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 回复  |  直到 9 年前
        1
  •  8
  •   Safwan Hijazi    9 年前

    您想添加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. 模式中表的名称。sql与数据中的名称不同。sql(个人vs个人)
    3. 你用过这个 spring.jpa.hibernate.ddl-auto=create 在应用程序中。属性(默认选项),在这种情况下,将仅自动创建JPA数据库模式( 不创建数据 ),所以数据。不会执行sql,要解决此问题,可以使用 validate update 选项

    我将编写一个简单的示例,说明如何将H2数据库与spring boot和JPA结合使用

    这是项目结构:

    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() {
        }
    
    
    
    }
    

    等级库.java

    package com.shijazi;
    
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.stereotype.Repository;
    
    
    @Repository
    public interface GradeRepository extends JpaRepository<Grade, Integer> {
    
    }
    

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

    应用程序.属性

    spring.jpa.hibernate.ddl-auto=validate
    

    模式.sql

    create table GRADE (id int not null, name varchar(20));
    

    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 并查看结果

        2
  •  3
  •   Community Mohan Dere    9 年前

    在与@Safwan Hijazi聊天时,花了一些时间研究了一些想法后,得出结论,所发生的事情就是这个模式。sql和数据。sql正在运行,然后根据spring.jpa.hibernate的值(或缺少)重新创建模式。ddl-auto属性。

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

    如果设置为“none”,则不会发生这种情况,由模式和数据sql脚本创建的数据库将保持不变,应用程序将正常运行。

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

        3
  •  0
  •   Naresh Kumar    9 年前
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    

    spring-boot-starter-data-jpa maven文件,用于所有依赖项的物料清单。使用的依赖项管理中定义的任何依赖项 spring boot starter数据jpa pom您必须在pom文件的依赖项部分显式声明依赖项。

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

    要启动h2数据库并与应用程序一起运行,可以在应用程序中指定属性。属性文件位于 src/main/resources/application.properties 使用:

    spring.h2.console.enabled=true
    spring.h2.console.path=/h2DB
    

    因此,当您使用springapplicationstarter运行应用程序时,您将能够访问位于 http://localhost:8080/h2DB

    如果在那里找不到数据,那么您就知道在哪里进行更改以将数据保存在那里。