SPRING IN ACTION 第4版笔记-第十一章Persisting data with object-relational mapping-004JPA例子的代码

一、结构

二、Repository层

1.

 1 package spittr.db;
 2 
 3 import java.util.List;
 4 
 5 import spittr.domain.Spitter;
 6 
 7 /**
 8  * Repository interface with operations for {@link Spitter} persistence.
 9  * @author habuma
10  */
11 public interface SpitterRepository {
12 
13   long count();
14 
15   Spitter save(Spitter spitter);
16 
17   Spitter findOne(long id);
18 
19   Spitter findByUsername(String username);
20 
21   List<Spitter> findAll();
22 
23 }

 

2.

 1 package spittr.db;
 2 
 3 import java.util.List;
 4 
 5 import spittr.domain.Spittle;
 6 
 7 /**
 8  * Repository interface with operations for {@link Spittle} persistence.
 9  * @author habuma
10  */
11 public interface SpittleRepository {
12 
13   long count();
14 
15   List<Spittle> findRecent();
16 
17   List<Spittle> findRecent(int count);
18 
19   Spittle findOne(long id);
20 
21   Spittle save(Spittle spittle);
22 
23   List<Spittle> findBySpitterId(long spitterId);
24   
25   void delete(long id);
26 
27 }

 

3.

 1 package spittr.db.jpa;
 2 
 3 import java.util.List;
 4 
 5 import javax.persistence.EntityManager;
 6 import javax.persistence.PersistenceContext;
 7 
 8 import org.springframework.stereotype.Repository;
 9 
10 import spittr.db.SpitterRepository;
11 import spittr.domain.Spitter;
12 
13 @Repository
14 public class JpaSpitterRepository implements SpitterRepository {
15 
16     @PersistenceContext
17     private EntityManager entityManager;
18 
19     public long count() {
20         return findAll().size();
21     }
22 
23     public Spitter save(Spitter spitter) {
24         entityManager.persist(spitter);
25         return spitter;
26     }
27 
28     public Spitter findOne(long id) {
29         return entityManager.find(Spitter.class, id);
30     }
31 
32     public Spitter findByUsername(String username) {        
33         return (Spitter) entityManager.createQuery("select s from Spitter s where s.username=?").setParameter(1, username).getSingleResult();
34     }
35 
36     public List<Spitter> findAll() {
37         return (List<Spitter>) entityManager.createQuery("select s from Spitter s").getResultList();
38     }
39     
40 }

 

4.

 1 package spittr.db.jpa;
 2 
 3 import java.util.List;
 4 
 5 import javax.persistence.EntityManager;
 6 import javax.persistence.PersistenceContext;
 7 
 8 import org.springframework.stereotype.Repository;
 9 
10 import spittr.db.SpittleRepository;
11 import spittr.domain.Spittle;
12 
13 @Repository
14 public class JpaSpittleRepository implements SpittleRepository {
15 
16   @PersistenceContext
17   private EntityManager entityManager;
18 
19   public long count() {
20     return findAll().size();
21   }
22 
23   public List<Spittle> findRecent() {
24     return findRecent(10);
25   }
26 
27   public List<Spittle> findRecent(int count) {
28     return (List<Spittle>) entityManager.createQuery("select s from Spittle s order by s.postedTime desc")
29         .setMaxResults(count)
30         .getResultList();
31   }
32 
33   public Spittle findOne(long id) {
34     return entityManager.find(Spittle.class, id);
35   }
36 
37   public Spittle save(Spittle spittle) {
38     entityManager.persist(spittle);
39     return spittle;
40   }
41 
42   public List<Spittle> findBySpitterId(long spitterId) {
43     return (List<Spittle>) entityManager.createQuery("select s from Spittle s, Spitter sp where s.spitter = sp and sp.id=? order by s.postedTime desc")
44         .setParameter(1, spitterId)
45         .getResultList();
46   }
47 
48   public void delete(long id) {
49     entityManager.remove(findOne(id));
50   }
51 
52   public List<Spittle> findAll() {
53     return (List<Spittle>) entityManager.createQuery("select s from Spittle s").getResultList();
54   }
55 
56 }

 

三、domain层

1.

 1 package spittr.domain;
 2 
 3 import javax.persistence.Column;
 4 import javax.persistence.Entity;
 5 import javax.persistence.GeneratedValue;
 6 import javax.persistence.GenerationType;
 7 import javax.persistence.Id;
 8 
 9 
10 @Entity
11 public class Spitter {
12     
13     private Spitter() {}
14 
15     @Id
16     @GeneratedValue(strategy=GenerationType.IDENTITY)
17     private Long id;
18 
19     @Column(name="username")
20     private String username;
21 
22     @Column(name="password")
23     private String password;
24 
25     @Column(name="fullname")
26     private String fullName;
27 
28     @Column(name="email")
29     private String email;
30 
31     @Column(name="updateByEmail")
32     private boolean updateByEmail;
33 
34     public Spitter(Long id, String username, String password, String fullName, String email, boolean updateByEmail) {
35         this.id = id;
36         this.username = username;
37         this.password = password;
38         this.fullName = fullName;
39         this.email = email;
40         this.updateByEmail = updateByEmail;
41     }
42 
43     public Long getId() {
44         return id;
45     }
46 
47     public String getUsername() {
48         return username;
49     }
50 
51     public String getPassword() {
52         return password;
53     }
54 
55     public String getFullName() {
56         return fullName;
57     }
58 
59     public String getEmail() {
60         return email;
61     }
62 
63     public boolean isUpdateByEmail() {
64         return updateByEmail;
65     }
66 
67 }

 

2.

 1 package spittr.domain;
 2 
 3 import java.util.Date;
 4 
 5 import javax.persistence.Column;
 6 import javax.persistence.Entity;
 7 import javax.persistence.GeneratedValue;
 8 import javax.persistence.GenerationType;
 9 import javax.persistence.Id;
10 import javax.persistence.JoinColumn;
11 import javax.persistence.ManyToOne;
12 
13 @Entity
14 public class Spittle {
15   
16   private Spittle() {}
17   
18   @Id
19   @GeneratedValue(strategy=GenerationType.IDENTITY)
20   private Long id;
21   
22   @ManyToOne
23   @JoinColumn(name="spitter")
24   private Spitter spitter;
25   
26   @Column
27   private String message;
28 
29   @Column
30   private Date postedTime;
31 
32   public Spittle(Long id, Spitter spitter, String message, Date postedTime) {
33     this.id = id;
34     this.spitter = spitter;
35     this.message = message;
36     this.postedTime = postedTime;
37   }
38   
39   public Long getId() {
40     return this.id;
41   }
42   
43   public String getMessage() {
44     return this.message;
45   }
46   
47   public Date getPostedTime() {
48     return this.postedTime;
49   }
50 
51   public Spitter getSpitter() {
52     return this.spitter;
53   }
54 
55 }

 

四、配置文件及数据库文件

1.

 1 package spittr.db.jpa;
 2 
 3 import javax.inject.Inject;
 4 import javax.persistence.EntityManagerFactory;
 5 import javax.sql.DataSource;
 6 
 7 import org.springframework.context.annotation.Bean;
 8 import org.springframework.context.annotation.ComponentScan;
 9 import org.springframework.context.annotation.Configuration;
10 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase;
11 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
12 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
13 import org.springframework.orm.jpa.JpaTransactionManager;
14 import org.springframework.orm.jpa.JpaVendorAdapter;
15 import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
16 import org.springframework.orm.jpa.vendor.Database;
17 import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
18 import org.springframework.transaction.PlatformTransactionManager;
19 import org.springframework.transaction.annotation.EnableTransactionManagement;
20 import org.springframework.transaction.annotation.TransactionManagementConfigurer;
21 
22 @Configuration
23 @ComponentScan
24 public class JpaConfig {
25 
26   @Bean
27   public DataSource dataSource() {
28     EmbeddedDatabaseBuilder edb = new EmbeddedDatabaseBuilder();
29     edb.setType(EmbeddedDatabaseType.H2);
30     edb.addScript("spittr/db/jpa/schema.sql");
31     edb.addScript("spittr/db/jpa/test-data.sql");
32     EmbeddedDatabase embeddedDatabase = edb.build();
33     return embeddedDatabase;
34   }
35 
36   @Bean
37   public LocalContainerEntityManagerFactoryBean emf(DataSource dataSource, JpaVendorAdapter jpaVendorAdapter) {
38     LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
39     emf.setDataSource(dataSource);
40     emf.setPersistenceUnitName("spittr");
41     emf.setJpaVendorAdapter(jpaVendorAdapter);
42     emf.setPackagesToScan("spittr.domain");
43     return emf;
44   }
45   
46   @Bean
47   public JpaVendorAdapter jpaVendorAdapter() {
48     HibernateJpaVendorAdapter adapter = new HibernateJpaVendorAdapter();
49     adapter.setDatabase(Database.H2);
50     adapter.setShowSql(true);
51     adapter.setGenerateDdl(false);
52     adapter.setDatabasePlatform("org.hibernate.dialect.H2Dialect");
53     return adapter;
54   }
55   
56 
57   @Configuration
58   @EnableTransactionManagement
59   public static class TransactionConfig implements TransactionManagementConfigurer {
60     @Inject
61     private EntityManagerFactory emf;
62 
63     public PlatformTransactionManager annotationDrivenTransactionManager() {
64       JpaTransactionManager transactionManager = new JpaTransactionManager();
65       transactionManager.setEntityManagerFactory(emf);
66       return transactionManager;
67     }    
68   }
69 }

 

2.RepositoryTest-context.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jdbc="http://www.springframework.org/schema/jdbc"
 4     xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:p="http://www.springframework.org/schema/p"
 6     xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd
 7         http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
 8         http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd">
 9 
10 
11     <context:component-scan base-package="spittr.db.jpa" />
12 
13     <bean id="emf" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"
14         p:dataSource-ref="dataSource" 
15     p:persistenceUnitName="spittr"
16         p:jpaVendorAdapter-ref="jpaVendorAdapter"
17     p:packagesToScan="spittr.domain" />
18 
19     <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
20         <property name="database" value="H2" />
21         <property name="showSql" value="true" />
22         <property name="generateDdl" value="false" />
23         <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect" />
24     </bean>
25 
26      <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"
27         p:entityManagerFactory-ref="emf" />
28         
29     <jdbc:embedded-database id="dataSource" type="H2">
30         <jdbc:script location="spittr/db/jpa/schema.sql" />
31         <jdbc:script location="spittr/db/jpa/test-data.sql" />
32     </jdbc:embedded-database>
33 
34 </beans>

 

3.schema.sql

 1 drop table if exists spittle;
 2 drop table if exists spitter;
 3 
 4 create table spitter (
 5   id identity,
 6   username varchar(25) not null,
 7   password varchar(25) not null,
 8   fullName varchar(100) not null,
 9   email varchar(50) not null,
10   updateByEmail boolean not null
11 );
12 
13 create table spittle (
14   id integer identity primary key,
15   spitter integer not null,
16   message varchar(2000) not null,
17   postedTime datetime not null,
18   foreign key (spitter) references spitter(id)
19 );

 

4.test-data.sql

 1 insert into Spitter (username, password, fullname, email, updateByEmail) values ('habuma', 'password', 'Craig Walls', 'craig@habuma.com', false);
 2 insert into Spitter (username, password, fullname, email, updateByEmail) values ('mwalls', 'password', 'Michael Walls', 'mwalls@habuma.com', true);
 3 insert into Spitter (username, password, fullname, email, updateByEmail) values ('chuck', 'password', 'Chuck Wagon', 'chuck@habuma.com', false);
 4 insert into Spitter (username, password, fullname, email, updateByEmail) values ('artnames', 'password', 'Art Names', 'art@habuma.com', true);
 5 
 6 insert into Spittle (spitter, message, postedTime) values (1, 'This is a test spittle message', '2012-06-09 22:00:00Z');
 7 insert into Spittle (spitter, message, postedTime) values (1, 'This is another test spittle message', '2012-06-09 22:10:00Z');
 8 insert into Spittle (spitter, message, postedTime) values (1, 'This is a third test spittle message', '2012-07-04 23:30:00Z');
 9 insert into Spittle (spitter, message, postedTime) values (2, 'Hello from Chuck!', '2012-03-25 12:15:00Z');
10 insert into Spittle (spitter, message, postedTime) values (4, 'Hello from Art!', '2012-03-25 12:15:00Z');
11 insert into Spittle (spitter, message, postedTime) values (4, 'Hello again from Art!', '2012-03-25 12:25:00Z');
12 insert into Spittle (spitter, message, postedTime) values (4, 'Hola from Arthur!', '2012-03-25 12:35:00Z');
13 insert into Spittle (spitter, message, postedTime) values (4, 'Buenos Dias from Art!', '2012-03-25 12:45:00Z');
14 insert into Spittle (spitter, message, postedTime) values (4, 'Ni Hao from Art!', '2012-03-25 12:55:00Z');
15 insert into Spittle (spitter, message, postedTime) values (4, 'Guten Tag from Art!', '2012-03-25 13:05:00Z');
16 insert into Spittle (spitter, message, postedTime) values (4, 'Konnichi wa from Art!', '2012-03-25 13:15:00Z');
17 insert into Spittle (spitter, message, postedTime) values (4, 'Buon giorno from Art!', '2012-03-25 13:25:00Z');
18 insert into Spittle (spitter, message, postedTime) values (4, 'Bonjour from Art!', '2012-03-25 13:35:00Z');
19 insert into Spittle (spitter, message, postedTime) values (4, 'Aloha from Art!', '2012-03-25 13:45:00Z');
20 insert into Spittle (spitter, message, postedTime) values (4, 'God dag from Art!', '2012-03-25 13:55:00Z');

 

5.log4j.properties

1 log4j.rootCategory=INFO, stdout
2 
3 log4j.appender.stdout=org.apache.log4j.ConsoleAppender
4 log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
5 log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %40.40c:%4L - %m%n

 

五、测试文件

1.

  1 package spittr.db.jpa;
  2 
  3 import static org.junit.Assert.*;
  4 
  5 import java.util.List;
  6 
  7 import org.junit.BeforeClass;
  8 import org.junit.Ignore;
  9 import org.junit.Test;
 10 import org.junit.runner.RunWith;
 11 import org.springframework.beans.factory.annotation.Autowired;
 12 import org.springframework.test.context.ContextConfiguration;
 13 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 14 import org.springframework.transaction.annotation.Transactional;
 15 
 16 import spittr.db.SpitterRepository;
 17 import spittr.domain.Spitter;
 18 
 19 @RunWith(SpringJUnit4ClassRunner.class)
 20 @ContextConfiguration(classes=JpaConfig.class)
 21 public class SpitterRepositoryTest {
 22 
 23     @Autowired
 24     SpitterRepository spitterRepository;
 25     
 26     @Test
 27     @Transactional
 28     public void count() {
 29         assertEquals(4, spitterRepository.count());
 30     }
 31     
 32     @Test
 33     @Transactional
 34     public void findAll() {
 35         List<Spitter> spitters = spitterRepository.findAll();
 36         assertEquals(4, spitters.size());
 37         assertSpitter(0, spitters.get(0));
 38         assertSpitter(1, spitters.get(1));
 39         assertSpitter(2, spitters.get(2));
 40         assertSpitter(3, spitters.get(3));
 41     }
 42     
 43     @Test
 44     @Transactional
 45     public void findByUsername() {
 46         assertSpitter(0, spitterRepository.findByUsername("habuma"));
 47         assertSpitter(1, spitterRepository.findByUsername("mwalls"));
 48         assertSpitter(2, spitterRepository.findByUsername("chuck"));
 49         assertSpitter(3, spitterRepository.findByUsername("artnames"));
 50     }
 51     
 52     @Test
 53     @Transactional
 54     public void findOne() {
 55         assertSpitter(0, spitterRepository.findOne(1L));
 56         assertSpitter(1, spitterRepository.findOne(2L));
 57         assertSpitter(2, spitterRepository.findOne(3L));
 58         assertSpitter(3, spitterRepository.findOne(4L));
 59     }
 60     
 61     @Test
 62     @Transactional
 63     public void save_newSpitter() {
 64         assertEquals(4, spitterRepository.count());
 65         Spitter spitter = new Spitter(null, "newbee", "letmein", "New Bee", "newbee@habuma.com", true);
 66         Spitter saved = spitterRepository.save(spitter);
 67         assertEquals(5, spitterRepository.count());
 68         assertSpitter(4, saved);
 69         assertSpitter(4, spitterRepository.findOne(5L));
 70     }
 71 
 72     @Test
 73     @Transactional
 74     @Ignore
 75     public void save_existingSpitter() {
 76         assertEquals(4, spitterRepository.count());
 77         Spitter spitter = new Spitter(4L, "arthur", "letmein", "Arthur Names", "arthur@habuma.com", false);
 78         Spitter saved = spitterRepository.save(spitter);
 79         assertSpitter(5, saved);
 80         assertEquals(4, spitterRepository.count());
 81         Spitter updated = spitterRepository.findOne(4L);
 82         assertSpitter(5, updated);
 83     }
 84 
 85     private static void assertSpitter(int expectedSpitterIndex, Spitter actual) {
 86         assertSpitter(expectedSpitterIndex, actual, "Newbie");
 87     }
 88     
 89     private static void assertSpitter(int expectedSpitterIndex, Spitter actual, String expectedStatus) {
 90         Spitter expected = SPITTERS[expectedSpitterIndex];
 91         assertEquals(expected.getId(), actual.getId());
 92         assertEquals(expected.getUsername(), actual.getUsername());
 93         assertEquals(expected.getPassword(), actual.getPassword());
 94         assertEquals(expected.getFullName(), actual.getFullName());
 95         assertEquals(expected.getEmail(), actual.getEmail());
 96         assertEquals(expected.isUpdateByEmail(), actual.isUpdateByEmail());
 97     }
 98     
 99     private static Spitter[] SPITTERS = new Spitter[6];
100     
101     @BeforeClass
102     public static void before() {
103         SPITTERS[0] = new Spitter(1L, "habuma", "password", "Craig Walls", "craig@habuma.com", false);
104         SPITTERS[1] = new Spitter(2L, "mwalls", "password", "Michael Walls", "mwalls@habuma.com", true);
105         SPITTERS[2] = new Spitter(3L, "chuck", "password", "Chuck Wagon", "chuck@habuma.com", false);
106         SPITTERS[3] = new Spitter(4L, "artnames", "password", "Art Names", "art@habuma.com", true);
107         SPITTERS[4] = new Spitter(5L, "newbee", "letmein", "New Bee", "newbee@habuma.com", true);        
108         SPITTERS[5] = new Spitter(4L, "arthur", "letmein", "Arthur Names", "arthur@habuma.com", false);        
109     }
110     
111 }

 

2.

  1 package spittr.db.jpa;
  2 
  3 import static org.junit.Assert.*;
  4 
  5 import java.util.Date;
  6 import java.util.List;
  7 
  8 import org.junit.Test;
  9 import org.junit.runner.RunWith;
 10 import org.springframework.beans.factory.annotation.Autowired;
 11 import org.springframework.test.context.ContextConfiguration;
 12 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
 13 import org.springframework.transaction.annotation.Transactional;
 14 
 15 import spittr.db.SpittleRepository;
 16 import spittr.domain.Spitter;
 17 import spittr.domain.Spittle;
 18 
 19 @RunWith(SpringJUnit4ClassRunner.class)
 20 //@ContextConfiguration("classpath:spittr/db/jpa/RepositoryTest-context.xml")
 21 @ContextConfiguration(classes=JpaConfig.class)
 22 public class SpittleRepositoryTest {
 23     
 24     @Autowired
 25     SpittleRepository spittleRepository;
 26 
 27     @Test
 28     @Transactional
 29     public void count() {
 30         assertEquals(15, spittleRepository.count());
 31     }
 32 
 33     @Test
 34     @Transactional
 35     public void findRecent() {
 36         // default case
 37         {
 38             List<Spittle> recent = spittleRepository.findRecent();
 39             assertRecent(recent, 10);
 40         }
 41         
 42         // specific count case
 43         {
 44             List<Spittle> recent = spittleRepository.findRecent(5);
 45             assertRecent(recent, 5);
 46         }
 47     }
 48 
 49     @Test
 50     @Transactional
 51     public void findOne() {
 52         Spittle thirteen = spittleRepository.findOne(13);
 53         assertEquals(13, thirteen.getId().longValue());
 54         assertEquals("Bonjour from Art!", thirteen.getMessage());
 55         assertEquals(1332682500000L, thirteen.getPostedTime().getTime());
 56         assertEquals(4, thirteen.getSpitter().getId().longValue());
 57         assertEquals("artnames", thirteen.getSpitter().getUsername());
 58         assertEquals("password", thirteen.getSpitter().getPassword());
 59         assertEquals("Art Names", thirteen.getSpitter().getFullName());
 60         assertEquals("art@habuma.com", thirteen.getSpitter().getEmail());
 61         assertTrue(thirteen.getSpitter().isUpdateByEmail());
 62     }
 63 
 64     @Test
 65     @Transactional
 66     public void findBySpitter() {
 67         List<Spittle> spittles = spittleRepository.findBySpitterId(4L);
 68         assertEquals(11, spittles.size());
 69         for (int i = 0; i < 11; i++) {
 70             assertEquals(15-i, spittles.get(i).getId().longValue());
 71         }
 72     }
 73     
 74     @Test
 75     @Transactional
 76     public void save() {
 77         assertEquals(15, spittleRepository.count());
 78         Spitter spitter = spittleRepository.findOne(13).getSpitter();
 79         Spittle spittle = new Spittle(null, spitter, "Un Nuevo Spittle from Art", new Date());
 80         Spittle saved = spittleRepository.save(spittle);
 81         assertEquals(16, spittleRepository.count());
 82         assertNewSpittle(saved);
 83         assertNewSpittle(spittleRepository.findOne(16L));
 84     }
 85 
 86     @Test
 87     @Transactional
 88     public void delete() {
 89         assertEquals(15, spittleRepository.count());
 90         assertNotNull(spittleRepository.findOne(13));
 91         spittleRepository.delete(13L);
 92         assertEquals(14, spittleRepository.count());
 93         assertNull(spittleRepository.findOne(13));
 94     }
 95     
 96     private void assertRecent(List<Spittle> recent, int count) {
 97         long[] recentIds = new long[] {3,2,1,15,14,13,12,11,10,9};
 98         assertEquals(count, recent.size());
 99         for (int i = 0; i < count; i++) {
100             assertEquals(recentIds[i], recent.get(i).getId().longValue());
101         }
102     }
103     
104     private void assertNewSpittle(Spittle spittle) {
105         assertEquals(16, spittle.getId().longValue());
106     }
107     
108 }

 

posted @ 2016-04-01 16:39  shamgod  阅读(194)  评论(0编辑  收藏  举报
haha