Spring使用内存数据库

有时候为了做些测试需要创建数据库及相关表,安装MySQL等轻量数据库虽然简单但还是有点麻烦?而且用于自己临时测试的数据库对象一般不会被多次使用,还是浪费?内存数据库结合ORM可以很好解决这个问题。


H2,Derby,HSQLDB 都是很好的内存数据库,大家可以根据自己的需要选择:


H2 Derby HSQLDB MySQL PostgreSQL
Pure Java Yes Yes Yes No No
Memory Mode Yes Yes Yes No No
Encrypted Database Yes Yes Yes No No
ODBC Driver Yes No No Yes Yes
Fulltext Search Yes No No Yes Yes
Multi Version Concurrency Yes No Yes Yes Yes
Footprint (jar/dll size) ~1 MB ~2 MB ~1 MB ~4 MB ~6 MB

Spring已经对使用内存数据库提供很完美的支持:

配置类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
@Configuration
public class HibernateConfiguration {
    @Autowired
    private DataSource dataSource;
    @Bean
    public AnnotationSessionFactoryBean sessionFactoryBean() {
        Properties props = new Properties();
        //配置H2方言
        props.put("hibernate.dialect", H2Dialect.class.getName());
        props.put("hibernate.format_sql""true");
        AnnotationSessionFactoryBean bean = new AnnotationSessionFactoryBean();
        bean.setAnnotatedClasses(new Class[]{Item.class, Order.class});
        bean.setHibernateProperties(props);
        bean.setDataSource(this.dataSource);
        bean.setSchemaUpdate(true);
        return bean;
    }
    @Bean
    public HibernateTransactionManager transactionManager() {
        return new HibernateTransactionManager( sessionFactoryBean().getObject() );
    }
                                                    
    /**
     * 设置内存数据库类型,可以更改为Derby,HSQL
     * @return
     */
    @Bean
    public DataSource dataSource(){
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
        builder.setType(EmbeddedDatabaseType.H2);
        return builder.build();
    }
}

然后我们可以写entity类及相关测试用例:

Order Entity类:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
@Entity
@Table(name="T_ORDER")
public class Order {
                                                  
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;
                                                  
    private String customer;
                                                  
    @OneToMany(cascade=CascadeType.ALL)
    @JoinColumn(name="ORDER_ID")
    private Collection<Item> items = new LinkedHashSet<Item>();
    /**
     * @return the customer
     */
    public String getCustomer() {
        return customer;
    }
    /**
     * @param customer the customer to set
     */
    public void setCustomer(String customer) {
        this.customer = customer;
    }
    /**
     * @return the items
     */
    public Collection<Item> getItems() {
        return items;
    }
    /**
     * @param items the items to set
     */
    public void setItems(Collection<Item> items) {
        this.items = items;
    }
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
                                                  
}

Item Entity类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
@Entity
public class Item {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ManyToOne
    private Order order;
    private String product;
    private double price;
    private int quantity;
    /**
     * @return the order
     */
    public Order getOrder() {
        return order;
    }
    /**
     * @return the product
     */
    public String getProduct() {
        return product;
    }
    /**
     * @param product
     *            the product to set
     */
    public void setProduct(String product) {
        this.product = product;
    }
    /**
     * @return the price
     */
    public double getPrice() {
        return price;
    }
    /**
     * @param price
     *            the price to set
     */
    public void setPrice(double price) {
        this.price = price;
    }
    /**
     * @return the quantity
     */
    public int getQuantity() {
        return quantity;
    }
    /**
     * @param quantity
     *            the quantity to set
     */
    public void setQuantity(int quantity) {
        this.quantity = quantity;
    }
    /**
     * @return the id
     */
    public Long getId() {
        return id;
    }
}

Junit测试类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
@ContextConfiguration
@RunWith(SpringJUnit4ClassRunner.class)
public class OrderPersistenceTests {
    @Autowired
    private SessionFactory sessionFactory;
    @Test
    @Transactional
    public void testSaveOrderWithItems() throws Exception {
        Session session = sessionFactory.getCurrentSession();
        Order order = new Order();
        order.getItems().add(new Item());
        session.save(order);
        session.flush();
        assertNotNull(order.getId());
    }
    @Test
    @Transactional
    public void testSaveAndGet() throws Exception {
        Session session = sessionFactory.getCurrentSession();
        Order order = new Order();
        order.getItems().add(new Item());
        session.save(order);
        session.flush();
        // Otherwise the query returns the existing order (and we didn't set the
        // parent in the item)...
        session.clear();
        Order other = (Order) session.get(Order.class, order.getId());
        assertEquals(1, other.getItems().size());
        assertEquals(other, other.getItems().iterator().next().getOrder());
    }
    @Test
    @Transactional
    public void testSaveAndFind() throws Exception {
        Session session = sessionFactory.getCurrentSession();
        Order order = new Order();
        Item item = new Item();
        item.setProduct("foo");
        order.getItems().add(item);
        session.save(order);
        session.flush();
        // Otherwise the query returns the existing order (and we didn't set the
        // parent in the item)...
        session.clear();
        Order other = (Order) session
                .createQuery( "select o from Order o join o.items i where i.product=:product")
                .setString("product""foo").uniqueResult();
        assertEquals(1, other.getItems().size());
        assertEquals(other, other.getItems().iterator().next().getOrder());
    }
}

整个项目已经打包,大家可以详阅,也可以直接参考Spring的示例项目,基本一样。




附件:http://down.51cto.com/data/2363898




     本文转自sarchitect 51CTO博客,原文链接:http://blog.51cto.com/stevex/1343060,如需转载请自行联系原作者



上一篇:内存数据库应用之NBA篮球图文直播室存储设计(Redis版)


下一篇:在组件之间实现事务和异步提交事务(NET2.0)