有时候为了做些测试需要创建数据库及相关表,安装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的示例项目,基本一样。