如何使用Spring Boot向数据库添加示例数据?

huangapple go评论67阅读模式
英文:

How to add sample data to database with springboot?

问题

我有一个使用Spring Data JPA的Spring Boot应用程序,并且有两个实体映射到数据库。我的应用程序在每次启动时都会重新创建数据库。现在我想创建一些这些POJO的实例,将它们持久化到数据库中,以便在持续的开发过程中使用一些数据来测试我的应用程序。

最佳的方法是什么呢?

我尝试过以下方法:
我的用于添加示例数据的类:

public class DBSampleAdditor {
    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void addSampleData() {
        // 创建POJO实例并使用em.persist()持久化它们
    }
}

我尝试在应用程序的主类中调用这些函数:

@SpringBootApplication()
public class ApiApplication {
    public static void main(String[] args) {
        SpringApplication.run(ApiApplication.class, args);
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
    }
}

这完全没有起作用,因为EntityManager从未获得过持久化单元的实例。

我还尝试创建一个CommandLineRunner:

@Component
public class PTCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("正在添加示例数据...");
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
    }
}

但是似乎在启动过程中从未调用过这个方法。

英文:

I've a Spring Boot application with the Spring Data JPA and two entities mapped to a database. My application is set to recreate the database on every startup. Now i want to create some instances of these POJOs, persist them in the database so I've some data to test my application with in the ongoing development process.

What is the best way to do that?

What i tried so far:
My class to add the sample data

public class DBSampleAdditor {
    @PersistenceContext
    private EntityManager em;

    @Transactional
    public void addSampleData() {
        // creating POJO instances and persist them with em.perists()
    }
}

I tried to call these functions in the main of my ApplicationClass

@SpringBootApplication()
public class ApiApplication {
	public static void main(String[] args) {
		SpringApplication.run(ApiApplication.class, args);
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
	}
}

That didnt work at all, as the EntityManager never got an Instance from the persistence unit.

I also tried to create a CommandLineRunner:

@Component
public class PTCommandLineRunner implements CommandLineRunner {
    @Override
    public void run(String... args) throws Exception {
        System.out.println("Adding sample data...");
        DBSampleAdditor dbsa = new DBSampleAdditor();
        dbsa.addSampleData();
    }
}

But that one seemed to never been called in the startup process.

答案1

得分: 2

你可以使用带有 @PostConstruct 和 @Component 的方法在启动时插入数据。

在 bean 被创建、依赖项被注入、所有托管属性被设置之后,但在 bean 实际设置到作用域之前,将调用 @PostConstruct。

只需在标记有 @Component 的类中注入数据库存储库,并在标记有 @PostConstruct 的方法内调用已注入的数据库存储库。

示例:

@Component
public class DbInit {
    
    @Autowired
    private DBSampleAdditor dbsa;
    
    @PostConstruct
    private void postConstruct() {
        dbsa.addSampleData();
    }
}
英文:

You can use method with @PostConstruct with @Component to insert data at startup.

@PostConstruct will be invoked after the bean has been created, dependencies have been injected, all managed properties are set, and before the bean is actually set into scope.

Just inject your database repository in the class marked with @Component and call your injected database repository inside the method marked with @PostConstruct

Example:

@Component
public class DbInit {
 
    @Autowired
    private DBSampleAdditor dbsa;
 
    @PostConstruct
    private void postConstruct() {
        dbsa.addSampleData();
    }
}

答案2

得分: 0

为了使用像 EntityManager 这样由 Spring 管理的组件,这些对象需要成为 Spring 的 Beans,这基本上意味着它们在 Spring 上下文中创建,并且可以利用 IoC 容器。

在上面的示例中,从主方法运行 DbSampleAdditor 类位于 Spring 上下文之外,因此诸如 PersistenceContext 之类的 bean 将不会被注入。

一个相当简单的方法是在 Spring 上下文中添加一个 ApplicationListener 来监听 ApplicationReadyEvent 事件:

@Component
class Initialise implements ApplicationListener<ApplicationReadyEvent> {

    @Autowired
    private final DbSampleAdditor db;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        db.addSampleData();
   }
}

当应用程序准备就绪事件触发时,所有必要的 Spring bean 装配都已设置好,因此当运行 addSampleData 方法时,诸如 EM 之类的内容就可以正常运行了。

有关在 Spring Boot 中设置数据库的其他方法在这里有文档记录 1

英文:

In order to use spring managed components like the EntityManager the objects need to spring Beans, which basically means they are created inside the spring context and can utilise the IoC container.

In the example above, running the DbSampleAdditor class from the main method is outside the spring context, so the beans like PersistenceContext wont get injected.

One fairly simple way to do this inside the spring context is to add an ApplicationListener for the ApplicationReadyEvent

@Component
class Initialise implements ApplicationListener&lt;ApplicationReadyEvent&gt; {

    @Autowired
    private final DbSampleAdditor db;

    @Override
    public void onApplicationEvent(ApplicationReadyEvent applicationReadyEvent) {
        db.addSampleData();
   }
}

When the application ready event fires all the necessary spring bean wiring is set up so when it runs the addSampleData method, things like the EM are good to go.

Other approaches for setting up a DB for spring boot are documented here

答案3

得分: 0

Sure, here's the translation:

代替创建一个对象DBSampleAdditor,尝试使用自动装配,以便在应用程序启动时可用。
@Autowired
DBSampleAdditor DBSampleAdditor
然后尝试在run方法内添加示例数据。

英文:

Instead of creating an object DBSampleAdditor, try to autowire it so that it is available on application startup. @Autowired DBSampleAdditor DBSampleAdditor Then you try to add sample data within the run method

huangapple
  • 本文由 发表于 2020年8月26日 06:47:27
  • 转载请务必保留本文链接:https://go.coder-hub.com/63588139.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定