一、结构
二、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.以前是用HibernateTemplate,但现在的最佳实践是用Hibernate contextual sessions and not use HibernateTemplate at all. This can be done by wiring a Hibernate SessionFactory directly into your repository and using it to obtain a session
@Repository有两作用:
(1)scanned by Spring component-scanning
(2)catch platformspecific exceptions and rethrow them as one of Spring’s unified unchecked exceptions
But if you’re using Hibernate contextual sessions and not a Hibernate template,how can the exception translation take place?要实现第2个作用还要配在配置文件配置PersistenceExceptionTranslationPostProcessor,如:
1 @Bean 2 public BeanPostProcessor persistenceTranslation() { 3 return new PersistenceExceptionTranslationPostProcessor(); 4 }
1 package spittr.db.hibernate4; 2 3 import java.io.Serializable; 4 import java.util.List; 5 6 import javax.inject.Inject; 7 8 import org.hibernate.Session; 9 import org.hibernate.SessionFactory; 10 import org.hibernate.criterion.Restrictions; 11 import org.springframework.stereotype.Repository; 12 13 import spittr.db.SpitterRepository; 14 import spittr.domain.Spitter; 15 16 @Repository 17 public class HibernateSpitterRepository implements SpitterRepository { 18 19 private SessionFactory sessionFactory; 20 21 @Inject 22 public HibernateSpitterRepository(SessionFactory sessionFactory) { 23 this.sessionFactory = sessionFactory; //<co id="co_InjectSessionFactory"/> 24 } 25 26 private Session currentSession() { 27 return sessionFactory.getCurrentSession();//<co id="co_RetrieveCurrentSession"/> 28 } 29 30 public long count() { 31 return findAll().size(); 32 } 33 34 public Spitter save(Spitter spitter) { 35 Serializable id = currentSession().save(spitter); //<co id="co_UseCurrentSession"/> 36 return new Spitter((Long) id, 37 spitter.getUsername(), 38 spitter.getPassword(), 39 spitter.getFullName(), 40 spitter.getEmail(), 41 spitter.isUpdateByEmail()); 42 } 43 44 public Spitter findOne(long id) { 45 return (Spitter) currentSession().get(Spitter.class, id); 46 } 47 48 public Spitter findByUsername(String username) { 49 return (Spitter) currentSession() 50 .createCriteria(Spitter.class) 51 .add(Restrictions.eq("username", username)) 52 .list().get(0); 53 } 54 55 public List<Spitter> findAll() { 56 return (List<Spitter>) currentSession() 57 .createCriteria(Spitter.class).list(); 58 } 59 60 }
4.
1 package spittr.db.hibernate4; 2 3 import java.io.Serializable; 4 import java.util.List; 5 6 import javax.inject.Inject; 7 8 import org.hibernate.Criteria; 9 import org.hibernate.Session; 10 import org.hibernate.SessionFactory; 11 import org.hibernate.criterion.Order; 12 import org.hibernate.criterion.Restrictions; 13 import org.springframework.stereotype.Repository; 14 15 import spittr.db.SpittleRepository; 16 import spittr.domain.Spittle; 17 18 @Repository 19 public class HibernateSpittleRepository implements SpittleRepository { 20 21 private SessionFactory sessionFactory; 22 23 @Inject 24 public HibernateSpittleRepository(SessionFactory sessionFactory) { 25 this.sessionFactory = sessionFactory; 26 } 27 28 private Session currentSession() { 29 return sessionFactory.getCurrentSession();//<co id="co_RetrieveCurrentSession"/> 30 } 31 32 public long count() { 33 return findAll().size(); 34 } 35 36 public List<Spittle> findRecent() { 37 return findRecent(10); 38 } 39 40 public List<Spittle> findRecent(int count) { 41 return (List<Spittle>) spittleCriteria() 42 .setMaxResults(count) 43 .list(); 44 } 45 46 public Spittle findOne(long id) { 47 return (Spittle) currentSession().get(Spittle.class, id); 48 } 49 50 public Spittle save(Spittle spittle) { 51 Serializable id = currentSession().save(spittle); 52 return new Spittle( 53 (Long) id, 54 spittle.getSpitter(), 55 spittle.getMessage(), 56 spittle.getPostedTime()); 57 } 58 59 public List<Spittle> findBySpitterId(long spitterId) { 60 return spittleCriteria() 61 .add(Restrictions.eq("spitter.id", spitterId)) 62 .list(); 63 } 64 65 public void delete(long id) { 66 currentSession().delete(findOne(id)); 67 } 68 69 public List<Spittle> findAll() { 70 return (List<Spittle>) spittleCriteria().list(); 71 } 72 73 private Criteria spittleCriteria() { 74 return currentSession() 75 .createCriteria(Spittle.class) 76 .addOrder(Order.desc("postedTime")); 77 } 78 79 }
三、Domainn层
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, 35 String email, boolean updateByEmail) { 36 this.id = id; 37 this.username = username; 38 this.password = password; 39 this.fullName = fullName; 40 this.email = email; 41 this.updateByEmail = updateByEmail; 42 } 43 44 public Long getId() { 45 return id; 46 } 47 48 public String getUsername() { 49 return username; 50 } 51 52 public String getPassword() { 53 return password; 54 } 55 56 public String getFullName() { 57 return fullName; 58 } 59 60 public String getEmail() { 61 return email; 62 } 63 64 public boolean isUpdateByEmail() { 65 return updateByEmail; 66 } 67 68 }
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 }
四、配置文件及数据库文件
0.
1 package spittr.db.hibernate4; 2 3 import java.io.IOException; 4 import java.util.Properties; 5 6 import javax.inject.Inject; 7 import javax.sql.DataSource; 8 9 import org.hibernate.SessionFactory; 10 import org.springframework.context.annotation.Bean; 11 import org.springframework.context.annotation.ComponentScan; 12 import org.springframework.context.annotation.Configuration; 13 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabase; 14 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder; 15 import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType; 16 //import org.springframework.orm.hibernate4.HibernateTransactionManager; 17 //import org.springframework.orm.hibernate4.LocalSessionFactoryBean; 18 import org.springframework.orm.hibernate5.HibernateTransactionManager; 19 import org.springframework.orm.hibernate5.LocalSessionFactoryBean; 20 import org.springframework.transaction.PlatformTransactionManager; 21 import org.springframework.transaction.annotation.EnableTransactionManagement; 22 import org.springframework.transaction.annotation.TransactionManagementConfigurer; 23 24 @Configuration 25 @EnableTransactionManagement 26 @ComponentScan 27 public class RepositoryTestConfig implements TransactionManagementConfigurer { 28 29 @Inject 30 private SessionFactory sessionFactory; 31 32 @Bean 33 public DataSource dataSource() { 34 EmbeddedDatabaseBuilder edb = new EmbeddedDatabaseBuilder(); 35 edb.setType(EmbeddedDatabaseType.H2); 36 edb.addScript("spittr/db/hibernate4/schema.sql"); 37 edb.addScript("spittr/db/hibernate4/test-data.sql"); 38 EmbeddedDatabase embeddedDatabase = edb.build(); 39 return embeddedDatabase; 40 } 41 42 //@Bean 43 public PlatformTransactionManager annotationDrivenTransactionManager() { 44 System.out.println(sessionFactory); 45 HibernateTransactionManager transactionManager = new HibernateTransactionManager(); 46 transactionManager.setSessionFactory(sessionFactory); 47 return transactionManager; 48 } 49 50 @Bean 51 public SessionFactory sessionFactoryBean() { 52 try { 53 LocalSessionFactoryBean lsfb = new LocalSessionFactoryBean(); 54 lsfb.setDataSource(dataSource()); 55 lsfb.setPackagesToScan("spittr.domain"); 56 Properties props = new Properties(); 57 props.setProperty("dialect", "org.hibernate.dialect.H2Dialect"); 58 lsfb.setHibernateProperties(props); 59 lsfb.afterPropertiesSet(); 60 SessionFactory object = lsfb.getObject(); 61 return object; 62 } catch (IOException e) { 63 return null; 64 } 65 } 66 }
1.
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
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 xsi:schemaLocation="http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.1.xsd 6 http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 7 http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd"> 8 9 10 <context:component-scan base-package="spittr.db.hibernate4" /> 11 12 <bean id="transactionManager" 13 class="org.springframework.orm.hibernate4.HibernateTransactionManager" 14 c:_-ref="sessionFactory" /> 15 16 <jdbc:embedded-database id="dataSource" type="H2"> 17 <jdbc:script location="spittr/db/hibernate4/schema.sql" /> 18 <jdbc:script location="spittr/db/hibernate4/test-data.sql" /> 19 </jdbc:embedded-database> 20 21 <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 22 <property name="dataSource" ref="dataSource"/> 23 <property name="packagesToScan" value="com.habuma.spitter.domain" /> 24 <property name="hibernateProperties"> 25 <props> 26 <prop key="dialect">org.hibernate.dialect.H2Dialect</prop> 27 </props> 28 </property> 29 </bean> 30 31 <bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/> 32 33 </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');
五、测试文件
1.
1 package spittr.db.hibernate4; 2 3 import static org.junit.Assert.*; 4 5 import java.util.List; 6 7 import org.junit.BeforeClass; 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.SpitterRepository; 16 import spittr.domain.Spitter; 17 18 @RunWith(SpringJUnit4ClassRunner.class) 19 @ContextConfiguration(classes = RepositoryTestConfig.class) 20 public class SpitterRepositoryTest { 21 22 @Autowired 23 SpitterRepository spitterRepository; 24 25 @Test 26 @Transactional 27 public void count() { 28 assertEquals(4, spitterRepository.count()); 29 } 30 31 @Test 32 @Transactional 33 public void findAll() { 34 List<Spitter> spitters = spitterRepository.findAll(); 35 assertEquals(4, spitters.size()); 36 assertSpitter(0, spitters.get(0)); 37 assertSpitter(1, spitters.get(1)); 38 assertSpitter(2, spitters.get(2)); 39 assertSpitter(3, spitters.get(3)); 40 } 41 42 @Test 43 @Transactional 44 public void findByUsername() { 45 assertSpitter(0, spitterRepository.findByUsername("habuma")); 46 assertSpitter(1, spitterRepository.findByUsername("mwalls")); 47 assertSpitter(2, spitterRepository.findByUsername("chuck")); 48 assertSpitter(3, spitterRepository.findByUsername("artnames")); 49 } 50 51 @Test 52 @Transactional 53 public void findOne() { 54 assertSpitter(0, spitterRepository.findOne(1L)); 55 assertSpitter(1, spitterRepository.findOne(2L)); 56 assertSpitter(2, spitterRepository.findOne(3L)); 57 assertSpitter(3, spitterRepository.findOne(4L)); 58 } 59 60 @Test 61 @Transactional 62 public void save_newSpitter() { 63 assertEquals(4, spitterRepository.count()); 64 Spitter spitter = new Spitter(null, "newbee", "letmein", "New Bee", 65 "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 private static void assertSpitter(int expectedSpitterIndex, Spitter actual) { 73 assertSpitter(expectedSpitterIndex, actual, "Newbie"); 74 } 75 76 private static void assertSpitter(int expectedSpitterIndex, Spitter actual, 77 String expectedStatus) { 78 Spitter expected = SPITTERS[expectedSpitterIndex]; 79 assertEquals(expected.getId(), actual.getId()); 80 assertEquals(expected.getUsername(), actual.getUsername()); 81 assertEquals(expected.getPassword(), actual.getPassword()); 82 assertEquals(expected.getFullName(), actual.getFullName()); 83 assertEquals(expected.getEmail(), actual.getEmail()); 84 assertEquals(expected.isUpdateByEmail(), actual.isUpdateByEmail()); 85 } 86 87 private static Spitter[] SPITTERS = new Spitter[6]; 88 89 @BeforeClass 90 public static void before() { 91 SPITTERS[0] = new Spitter(1L, "habuma", "password", "Craig Walls", 92 "craig@habuma.com", false); 93 SPITTERS[1] = new Spitter(2L, "mwalls", "password", "Michael Walls", 94 "mwalls@habuma.com", true); 95 SPITTERS[2] = new Spitter(3L, "chuck", "password", "Chuck Wagon", 96 "chuck@habuma.com", false); 97 SPITTERS[3] = new Spitter(4L, "artnames", "password", "Art Names", 98 "art@habuma.com", true); 99 SPITTERS[4] = new Spitter(5L, "newbee", "letmein", "New Bee", 100 "newbee@habuma.com", true); 101 SPITTERS[5] = new Spitter(4L, "arthur", "letmein", "Arthur Names", 102 "arthur@habuma.com", false); 103 } 104 105 }
2.
1 package spittr.db.hibernate4; 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(classes=RepositoryTestConfig.class) 21 public class SpittleRepositoryTest { 22 23 @Autowired 24 SpittleRepository spittleRepository; 25 26 @Test 27 @Transactional 28 public void count() { 29 assertEquals(15, spittleRepository.count()); 30 } 31 32 @Test 33 @Transactional 34 public void findRecent() { 35 // default case 36 { 37 List<Spittle> recent = spittleRepository.findRecent(); 38 assertRecent(recent, 10); 39 } 40 41 // specific count case 42 { 43 List<Spittle> recent = spittleRepository.findRecent(5); 44 assertRecent(recent, 5); 45 } 46 } 47 48 @Test 49 @Transactional 50 public void findOne() { 51 Spittle thirteen = spittleRepository.findOne(13); 52 assertEquals(13, thirteen.getId().longValue()); 53 assertEquals("Bonjour from Art!", thirteen.getMessage()); 54 assertEquals(1332682500000L, thirteen.getPostedTime().getTime()); 55 assertEquals(4, thirteen.getSpitter().getId().longValue()); 56 assertEquals("artnames", thirteen.getSpitter().getUsername()); 57 assertEquals("password", thirteen.getSpitter().getPassword()); 58 assertEquals("Art Names", thirteen.getSpitter().getFullName()); 59 assertEquals("art@habuma.com", thirteen.getSpitter().getEmail()); 60 assertTrue(thirteen.getSpitter().isUpdateByEmail()); 61 } 62 63 @Test 64 @Transactional 65 public void findBySpitter() { 66 List<Spittle> spittles = spittleRepository.findBySpitterId(4L); 67 assertEquals(11, spittles.size()); 68 for (int i = 0; i < 11; i++) { 69 assertEquals(15-i, spittles.get(i).getId().longValue()); 70 } 71 } 72 73 @Test 74 @Transactional 75 public void save() { 76 assertEquals(15, spittleRepository.count()); 77 Spitter spitter = spittleRepository.findOne(13).getSpitter(); 78 Spittle spittle = new Spittle(null, spitter, "Un Nuevo Spittle from Art", new Date()); 79 Spittle saved = spittleRepository.save(spittle); 80 assertEquals(16, spittleRepository.count()); 81 assertNewSpittle(saved); 82 assertNewSpittle(spittleRepository.findOne(16L)); 83 } 84 85 @Test 86 @Transactional 87 public void delete() { 88 assertEquals(15, spittleRepository.count()); 89 assertNotNull(spittleRepository.findOne(13)); 90 spittleRepository.delete(13L); 91 assertEquals(14, spittleRepository.count()); 92 assertNull(spittleRepository.findOne(13)); 93 } 94 95 private void assertRecent(List<Spittle> recent, int count) { 96 long[] recentIds = new long[] {3,2,1,15,14,13,12,11,10,9}; 97 assertEquals(count, recent.size()); 98 for (int i = 0; i < count; i++) { 99 assertEquals(recentIds[i], recent.get(i).getId().longValue()); 100 } 101 } 102 103 private void assertNewSpittle(Spittle spittle) { 104 assertEquals(16, spittle.getId().longValue()); 105 } 106 107 }