JPA存储库的初始数据

时间:2014-06-07 13:08:50

标签: spring jpa spring-data

我正在寻找一种方便的方法来为我的应用程序提供初始数据。目前我已经实现了一个基于Spring Data JPA的项目,这是我所有数据库相关操作的基础。

示例:

我有一个实体Role,可以将其分配给实体User。在干净的应用程序启动时,我想直接提供一些默认角色(例如管理员,经理等)。

最佳

3 个答案:

答案 0 :(得分:1)

查看内存中的H2数据库。

http://www.h2database.com/html/main.html

Maven依赖

<!-- H2 Database -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.178</version>
</dependency>

Spring Java Config Entry

@Bean
public DataSource dataSource() {
    System.out.println("**** USING H2 DATABASE ****");
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    return builder.setType(EmbeddedDatabaseType.H2).addScript("/schema.sql").build();
}

您可以使用 .addscript()在上述代码中创建/加载带有SQL脚本的H2数据库。

答案 1 :(得分:1)

我建立了一个随机数据工厂:

public class RandomDataFactory {

    private static final String UNGENERATED_VALUE_MARKER = "UNGENERATED_VALUE_MARKER";

    private static void randomlyPopulateFields(Object object) {
        new RandomValueFieldPopulator().populate(object);
    }

    /**
     * Instantiates a single object with random data
     */
    public static <T> T getSingle(Class<T> clazz) throws IllegalAccessException, InstantiationException {
        T object = clazz.newInstance();
        randomlyPopulateFields(object);
        return object;
    }

    /**
     * Returns an unmodifiable list of specified type objects with random data
     *
     * @param clazz     the myPojo.class to be instantiated with random data
     * @param maxLength the length of list to be returned
     */
    public static <T> List<T> getList(Class<T> clazz, int maxLength) throws IllegalAccessException, InstantiationException {
        List<T> list = new ArrayList<T>(maxLength);
        for (int i = 0; i < maxLength; i++) {
            T object = clazz.newInstance();
            randomlyPopulateFields(object);
            list.add(i, object);
        }
        return Collections.unmodifiableList(list);
    }

    /**
     * Returns a unmodifiable list of specified type T objects with random data
     * <p>List length will be 3</p>
     *
     * @param clazz the myPojo.class to be instantiated with random data
     */
    public static <T> List<T> getList(Class<T> clazz) throws InstantiationException, IllegalAccessException {
        return getList(clazz, 3);
    }

    public static <T> T getPrimitive(Class<T> clazz) {
        return (T) RandomValueFieldPopulator.generateRandomValue(clazz);
    }

    public static <T> List<T> getPrimitiveList(Class<T> clazz) {
        return getPrimitiveList(clazz, 3);
    }

    public static <T> List<T> getPrimitiveList(Class<T> clazz, int length) {
        List<T> randoms = new ArrayList<T>(length);
        for (int i = 0; i < length; i++) {
            randoms.add(getPrimitive(clazz));
        }
        return randoms;
    }

    private static class RandomValueFieldPopulator {
        public static Object generateRandomValue(Class<?> fieldType) {
            Random random = new Random();
              if (fieldType.equals(String.class)) {
                return UUID.randomUUID().toString();
            } else if (Date.class.isAssignableFrom(fieldType)) {
                return new Date(System.currentTimeMillis() - random.nextInt());
            } else if (LocalDate.class.isAssignableFrom(fieldType)) {
                Date date = new Date(System.currentTimeMillis() - random.nextInt());
                return new LocalDate(date);
            } else if (fieldType.equals(Character.class) || fieldType.equals(Character.TYPE)) {
                return (char) (random.nextInt(26) + 'a');
            } else if (fieldType.equals(Integer.TYPE) || fieldType.equals(Integer.class)) {
                return random.nextInt();
            } else if (fieldType.equals(Short.TYPE) || fieldType.equals(Short.class)) {
                return (short) random.nextInt();
            } else if (fieldType.equals(Long.TYPE) || fieldType.equals(Long.class)) {
                return random.nextLong();
            } else if (fieldType.equals(Float.TYPE) || fieldType.equals(Float.class)) {
                return random.nextFloat();
            } else if (fieldType.equals(Double.TYPE)) {
                return random.nextInt(); //if double is used, jsonPath uses bigdecimal to convert back
            } else if (fieldType.equals(Double.class)) {
                return random.nextDouble(); //if double is used, jsonPath uses bigdecimal to convert back
            } else if (fieldType.equals(Boolean.TYPE) || fieldType.equals(Boolean.class)) {
                return random.nextBoolean();
            } else if (fieldType.equals(BigDecimal.class)) {
                return new BigDecimal(random.nextFloat());
            } else if (Enum.class.isAssignableFrom(fieldType)) {
                Object[] enumValues = fieldType.getEnumConstants();
                return enumValues[random.nextInt(enumValues.length)];
            } else if (Number.class.isAssignableFrom(fieldType)) {
                return random.nextInt(Byte.MAX_VALUE) + 1;
            } else {
                return UNGENERATED_VALUE_MARKER;
            }

        public void populate(Object object) {
            ReflectionUtils.doWithFields(object.getClass(), new RandomValueFieldSetterCallback(object));
        }

        private static class RandomValueFieldSetterCallback implements ReflectionUtils.FieldCallback {
            private final Object targetObject;

            public RandomValueFieldSetterCallback(Object targetObject) {
                this.targetObject = targetObject;
            }

            @Override
            public void doWith(Field field) throws IllegalAccessException {
                Class<?> fieldType = field.getType();
                if (!Modifier.isFinal(field.getModifiers())) {
                    Object value = generateRandomValue(fieldType);
                    if (!value.equals(UNGENERATED_VALUE_MARKER)) {
                        ReflectionUtils.makeAccessible(field);
                        field.set(targetObject, value);
                    }
                }
            }
        }
    }
}

答案 2 :(得分:0)

如果您将其用于单元测试,并且需要不同的状态进行不同的测试,那么

  1. http://dbunit.sourceforge.net/

  2. 特别针对Spring,有http://springtestdbunit.github.io/spring-test-dbunit/

  3. 如果您只需要初始化一次并使用EmbeddedDatabaseBuilder进行测试,那么正如Brandon所说,您可以使用EmbeddedDatabaseBuilder。

    @Bean
    public DataSource dataSource() {
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        return builder.setType(EmbeddedDatabaseType.H2).addScript("/schema.sql").build();
    }
    

    如果要在应用程序启动时初始化它,可以将@PostConstruct函数添加到Configuration bean,并在创建配置bean后初始化它。

    @PostConstruct
    public void initializeDB() {
    }