数据如何插入 H2 数据库?

Posted

技术标签:

【中文标题】数据如何插入 H2 数据库?【英文标题】:How is data being inserted into H2 database? 【发布时间】:2021-02-17 17:49:16 【问题描述】:

我有一个使用 Spring Boot 的代码库。

根据pom和properties文件,我断定正在使用h2数据库。

当应用程序首次启动时,/orders api 返回一些初始数据。 :我想知道这些数据是如何进入数据库的。没有对 orderrepository 的 save 方法的引用,可以指示保存数据。

数据是指我在下面发布的特定数据。

我将数据源设置为本地路径,并注意到在用于启动应用程序的命令 mvn spring-boot:run 期间它的大小增加了。

数据是如何进入数据库的?我搜索了 orderservice 的保存参考,但找不到任何东西。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
 <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.1.4.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.akveo</groupId>
<artifactId>bundle-java</artifactId>
<version>1.0.0</version>
<name>bundle-java</name>
<description>Backend bundle in Java implementation for ngx admin</description>

<properties>
    <java.version>1.8</java.version>
    <maven.compiler.source>1.8</maven.compiler.source>
    <maven.compiler.target>1.8</maven.compiler.target>
</properties>

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

    <dependency>
        <groupId>commons-configuration</groupId>
        <artifactId>commons-configuration</artifactId>
        <version>1.6</version>
    </dependency>

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

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

    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>

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

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>

    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>

    <dependency>
        <groupId>org.modelmapper</groupId>
        <artifactId>modelmapper</artifactId>
        <version>2.3.3</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger2</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>2.9.2</version>
    </dependency>

    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.19</version>
    </dependency>

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.4.10.Final</version>
    </dependency>

    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <scope>runtime</scope>
        <version>1.4.197</version>
    </dependency>

    <dependency>
        <groupId>com.google.code.findbugs</groupId>
        <artifactId>annotations</artifactId>
        <version>3.0.1</version>
        <scope>provided</scope>
    </dependency>

    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
        <version>2.9.8</version>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-test</artifactId>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>

        <plugin>
            <groupId>org.codehaus.mojo</groupId>
            <artifactId>findbugs-maven-plugin</artifactId>
            <version>3.0.5</version>
            <configuration>
                <effort>Max</effort>
            </configuration>
            <executions>
                <execution>
                    <goals>
                        <goal>check</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-checkstyle-plugin</artifactId>
            <version>3.0.0</version>
            <configuration>
                <configLocation>checkstyle.xml</configLocation>
            </configuration>
            <executions>
                <execution>
                    <phase>validate</phase>
                    <goals>
                        <goal>check</goal>
                    </goals>
                </execution>
            </executions>
        </plugin>
    </plugins>
</build>

application.properties

spring.datasource.url=jdbc:h2:file:C:\\Users\\user\\Documents\\app-data
spring.datasource.driverClassName=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=password
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
# JWT

# 1 hour
jwt.accessTokenValidityInMilliseconds=3600000
# 30 days
jwt.refreshTokenValidityInMilliseconds=2592000000
# Client Info
client.url=http://localhost:3001/api
server.port=3001    
server.servlet.context-path=/api
# Client reset password expiration
client.resetPasswordToken.expiration=60m
# Clear expired tokens every day at midnight
client.resetPasswordToken.clearJob=0 0 0 * * ?

OrderRepository

package com.akveo.bundlejava.ecommerce.repository;

import com.akveo.bundlejava.ecommerce.entity.Order;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;

public interface OrderRepository extends PagingAndSortingRepository<Order, Long>, JpaSpecificationExecutor<Order> 
    @Modifying
    @Query("delete from Order t where t.id = ?1")
    void delete(Long entityId);

订单服务

package com.akveo.bundlejava.ecommerce.service;

import com.akveo.bundlejava.authentication.BundleUserDetailsService;
import com.akveo.bundlejava.authentication.exception.OrderNotFoundHttpException;
import com.akveo.bundlejava.ecommerce.DTO.OrderDTO;
import com.akveo.bundlejava.ecommerce.entity.GridData;
import com.akveo.bundlejava.ecommerce.entity.Country;
import com.akveo.bundlejava.ecommerce.entity.Order;
import com.akveo.bundlejava.ecommerce.entity.builder.PageableBuilder;
import com.akveo.bundlejava.ecommerce.entity.builder.OrderSpecificationBuilder;
import com.akveo.bundlejava.ecommerce.entity.filter.OrderGridFilter;
import com.akveo.bundlejava.ecommerce.repository.CountryRepository;
import com.akveo.bundlejava.ecommerce.repository.OrderRepository;
import com.akveo.bundlejava.user.User;
import com.akveo.bundlejava.user.UserRepository;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.http.HttpStatus;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
public class OrderService 
    private OrderRepository orderRepository;
    private CountryRepository countryRepository;
    private ModelMapper modelMapper;
    private PageableBuilder pageableBuilder;
    private UserRepository userRepository;

    @Autowired
    OrderService(OrderRepository orderRepository,
                 UserRepository userRepository,
                 CountryRepository countryRepository,
                 PageableBuilder pageableBuilder,
                 ModelMapper modelMapper) 
        this.modelMapper = modelMapper;
        this.countryRepository = countryRepository;
        this.userRepository = userRepository;
        this.orderRepository = orderRepository;
        this.pageableBuilder = pageableBuilder;
    

    @Transactional
    public boolean delete(Long id) 
        try 
            orderRepository.delete(id);
            return true;
         catch (EmptyResultDataAccessException e) 
            throw new OrderNotFoundHttpException("Order with id: " + id + " not found", HttpStatus.NOT_FOUND);
        
    

    public OrderDTO getOrderById(Long id) 
        Order existingOrder = orderRepository.findById(id).orElseThrow(
                () -> new OrderNotFoundHttpException("User with id: " + id + " not found", HttpStatus.NOT_FOUND)
        );

        return modelMapper.map(existingOrder, OrderDTO.class);
    

    private List<OrderDTO> mapOrdersToOrderDTO(List<Order> orders) 
        return orders.stream().map(order ->
                modelMapper.map(order, OrderDTO.class)
        ).collect(Collectors.toList());
    

    private GridData<OrderDTO> parsePageToGridData(Page<Order> orderPages) 
        GridData<OrderDTO> gridData = new GridData<>();
        List<Order> orderList = orderPages.getContent();
        long totalCount = orderPages.getTotalElements();
        gridData.setItems(mapOrdersToOrderDTO(orderList));
        gridData.setTotalCount(totalCount);
        return gridData;
    

    public GridData<OrderDTO> getDataForGrid(OrderGridFilter filter) 
        OrderSpecificationBuilder specificationBuilder = new OrderSpecificationBuilder();

        Pageable paginationAndSort = pageableBuilder.build(filter);
        Optional<Specification<Order>> optionalSpec = specificationBuilder.build(filter);
        Page<Order> orderPages = optionalSpec
                .map(orderSpecification -> orderRepository.findAll(orderSpecification, paginationAndSort))
                .orElseGet(() -> orderRepository.findAll(paginationAndSort));
        return parsePageToGridData(orderPages);
    

    @Transactional
    public OrderDTO updateOrderById(Long id, OrderDTO orderDTO, Authentication auth) 
        return update(id, orderDTO, auth);
    

    private OrderDTO update(Long id, OrderDTO orderDTO, Authentication auth) 
        Order orderFromDB = orderRepository.findById(id).orElseThrow(
                () -> new OrderNotFoundHttpException("Order with id: " + id + " not found", HttpStatus.NOT_FOUND)
        );

        User createdUser = orderFromDB.getCreatedByUserId();

        Long userId = ((BundleUserDetailsService.BundleUserDetails) auth.getPrincipal()).getUser().getId();
        Optional<User> optionalUser = userRepository.findById(userId);
        User updatedUser = optionalUser.orElse(null);

        Order order = modelMapper.map(orderDTO, Order.class);

        Long countryId = orderFromDB.getCountry().getId();

        if (countryId == 0) 
            Country country = countryRepository.getOne(countryId);
            orderFromDB.setCountry(country);
        

        order.setUpdatedByUserId(updatedUser);
        order.setCreatedByUserId(createdUser);
        orderRepository.save(order);

        return orderDTO;
    

    @Transactional
    public OrderDTO createOrder(Authentication auth, OrderDTO orderDTO) 
        Long userId = ((BundleUserDetailsService.BundleUserDetails) auth.getPrincipal()).getUser().getId();

        Optional<User> optionalUser = userRepository.findById(userId);
        User user = optionalUser.orElse(null);

        Order order = modelMapper.map(orderDTO, Order.class);

        order.setCreatedByUserId(user);
        order.setUpdatedByUserId(user);
        orderRepository.save(order);

        return orderDTO;
    

订单控制器

package com.akveo.bundlejava.ecommerce.controller;

import com.akveo.bundlejava.authentication.ResponseMessage;
import com.akveo.bundlejava.ecommerce.DTO.OrderDTO;
import com.akveo.bundlejava.ecommerce.entity.GridData;
import com.akveo.bundlejava.ecommerce.entity.filter.OrderGridFilter;
import com.akveo.bundlejava.ecommerce.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;

import javax.validation.Valid;

import static org.springframework.http.ResponseEntity.ok;

@Controller
@RequestMapping("/orders")
public class OrdersController 
    private OrderService orderService;

    @Autowired
    public OrdersController(OrderService orderService) 
        this.orderService = orderService;
    

    @GetMapping("")
    public ResponseEntity<GridData<OrderDTO>> getDataForGrid(OrderGridFilter orderGridFilter) 
        return ok(orderService.getDataForGrid(orderGridFilter));
    

    @GetMapping("/id")
    public ResponseEntity<OrderDTO> get(@PathVariable Long id) 
        return ok(orderService.getOrderById(id));
    

    @PostMapping("")
    public ResponseEntity<OrderDTO> create(Authentication auth, @Valid @RequestBody OrderDTO orderDTO) 
        return ok(orderService.createOrder(auth, orderDTO));
    

    @PutMapping("/id")
    public ResponseEntity edit(Authentication auth, @PathVariable Long id, @Valid @RequestBody OrderDTO orderDTO) 
        if (!id.equals(orderDTO.getId())) 
            return new ResponseEntity<>(
                    "Id must be equal",
                    HttpStatus.BAD_REQUEST);
        
        return ok(orderService.updateOrderById(id, orderDTO, auth));
    

    @DeleteMapping("/id")
    public ResponseEntity<ResponseMessage> delete(@PathVariable Long id) 
        orderService.delete(id);
        return ok(new ResponseMessage("Ok"));
    

来自订单端点的数据(在应用启动时第一次调用之后):


   "totalCount": 6089,
   "items": [
      
         "id": 6089,
         "name": "Order 13988",
         "date": "2020-11-06T16:49:04.612",
         "sum": 
            "value": 959.55,
            "currency": "USD"
         ,
         "type": "Tables",
         "status": "Payment",
         "country": 
            "id": 22,
            "name": "Suriname"
         
      ,
      
         "id": 6088,
         "name": "Order 16403",
         "date": "2020-09-02T16:49:04.612",
         "sum": 
            "value": 721.46,
            "currency": "USD"
         ,
         "type": "Furniture",
         "status": "Payment",
         "country": 
            "id": 139,
            "name": "Greenland"
         
      ,
      
         "id": 6087,
         "name": "Order 12129",
         "date": "2020-11-15T16:49:04.612",
         "sum": 
            "value": 814.51,
            "currency": "USD"
         ,
         "type": "Textiles",
         "status": "Payment",
         "country": 
            "id": 100,
            "name": "Madagascar"
         
      ,
      
         "id": 6086,
         "name": "Order 910",
         "date": "2020-12-27T16:49:04.612",
         "sum": 
            "value": 585.34,
            "currency": "USD"
         ,
         "type": "Textiles",
         "status": "Payment",
         "country": 
            "id": 148,
            "name": "Japan"
         
      ,
      
         "id": 6085,
         "name": "Order 127",
         "date": "2020-09-16T16:49:04.612",
         "sum": 
            "value": 894.64,
            "currency": "USD"
         ,
         "type": "Tables",
         "status": "Payment",
         "country": 
            "id": 30,
            "name": "Bhutan"
         
      ,
      
         "id": 6084,
         "name": "Order 14774",
         "date": "2020-11-07T16:49:04.612",
         "sum": 
            "value": 865.38,
            "currency": "USD"
         ,
         "type": "Tables",
         "status": "Cancelled",
         "country": 
            "id": 100,
            "name": "Madagascar"
         
      ,
      
         "id": 6083,
         "name": "Order 12590",
         "date": "2021-01-04T16:49:04.612",
         "sum": 
            "value": 708.94,
            "currency": "USD"
         ,
         "type": "Textiles",
         "status": "Cancelled",
         "country": 
            "id": 75,
            "name": "Albania"
         
      ,
      
         "id": 6082,
         "name": "Order 14544",
         "date": "2020-09-26T16:49:04.612",
         "sum": 
            "value": 401.37,
            "currency": "USD"
         ,
         "type": "Textiles",
         "status": "Payment",
         "country": 
            "id": 157,
            "name": "Hungary"
         
      ,
      
         "id": 6081,
         "name": "Order 7908",
         "date": "2020-11-17T16:49:04.612",
         "sum": 
            "value": 222.02,
            "currency": "USD"
         ,
         "type": "Lightning",
         "status": "Cancelled",
         "country": 
            "id": 42,
            "name": "Iraq"
         
      ,
      
         "id": 6080,
         "name": "Order 14165",
         "date": "2020-08-31T16:49:04.612",
         "sum": 
            "value": 879.75,
            "currency": "USD"
         ,
         "type": "Furniture",
         "status": "Cancelled",
         "country": 
            "id": 140,
            "name": "Yemen"
         
      
   ]

【问题讨论】:

如果数据是指表格?它们是从实体自动创建的。你也有 order.setUpdatedByUserId(updatedUser); order.setCreatedByUserId(createdUser); orderRepository.save(order); @SusanMustafa 感谢您的回复,我的错。我现在添加了初始数据。我的问题专门针对这些数据。 【参考方案1】:

我对spring初始化的工作原理做了一些研究,发现了一个这样注释的方法:

@EventListener(ContextStartedEvent.class)

如文章here中所述。

【讨论】:

以上是关于数据如何插入 H2 数据库?的主要内容,如果未能解决你的问题,请参考以下文章

如何使用反射 API 将数据插入 H2 数据库

如何将格式为“3/22/2018 12:24:29 PM”的日期时间字符串格式化为sql时间戳以插入内存数据库中的h2?

无法在 h2 内存数据库中插入数据

内存 H2 数据库,插入脚本不持久

在 h2 数据库中插入视图

使用 ALTER TABLE 添加新列后 H2 数据库插入数据异常