我们都知道Spring是一个非常优秀的JavaEE整合框架它尽可能的减少我们开发的工作量和难度
在持久层的业务逻辑方面Spring开源组织又给我们带来了同样优秀的Spring Data JPA
通常我们写持久层都是先写一个接口再写接口对应的实现类在实现类中进行持久层的业务逻辑处理
而现在Spring Data JPA帮助我们自动完成了持久层的业务逻辑处理我们要做的仅仅是声明一个持久层接口
下载开发所需要的发布包
)springframeworkRELEASEwithdocszip
下载地址framework
)hibernatereleaseFinalzip
下载地址
)Spring Data JPA
Spring Data JPA
下载地址data/jpa
Spring Data Commons
下载地址data/commons
)其他一些依赖包可以从 上查找下载
新建一个Web项目 springdatajpa把相应的jar包放到/WebRoot/WEBINF/lib目录下
我也没有挑选哪些是不需要的最后用到的jar如下
antlrjarsfcglibjaraopalliancejarmonsloggingjaraspectjweaverRELEASEjarcommonslangjardomjjarhibernatecommonsannotationsFinaljarhibernatecoreFinaljarhibernateentitymanagerFinaljarhibernatejpaapiFinaljarjavassistGAjarjbossloggingGAjarjbosstransactionapi__specFinaljarlogjjarmysqlconnectorjavabinjarorgspringframeworkaopRELEASEjarorgspringframeworkasmRELEASEjarorgspringframeworkaspectsRELEASEjarorgspringframeworkbeansRELEASEjarorgntextRELEASEjarorgntextsupportRELEASEjarorgreRELEASEjarorgspringframeworkexpressionRELEASEjarorgspringframeworkinstrumentRELEASEjarorgspringframeworkinstrumenttomcatRELEASEjarorgspringframeworkjdbcRELEASEjarorgspringframeworkjmsRELEASEjarorgspringframeworkjsresourcesRELEASEjarorgspringframeworkormRELEASEjarorgspringframeworkoxmRELEASEjarorgspringframeworktestRELEASEjarorgspringframeworktransactionRELEASEjarorgspringframeworkwebRELEASEjarorgspringframeworkwebportletRELEASEjarorgspringframeworkwebservletRELEASEjarslfjapijarslfjlogjjarspringdatacommonscoreMjarspringdatajpaRELEASEjar
在MySql数据库中建立一个叫spring_data_jpa的数据库
create database spring_data_jpa default character set utf;
JPA配置文件persistencexml
)在src目录下建立一个叫METAINF的文件夹
)在METAINF文件夹下建立persistencexml文件
persistencexml内容如下
xml version= encoding=UTF?><persistence version= xmlns=
xmlns:xsi=instance
xsi:schemaLocation=
__xsd>
<persistenceunit name=myJPA transactiontype=RESOURCE_LOCAL>
<provider>orghibernateejbHibernatePersistenceprovider>
<properties>
<property name=hibernatedialect value=orghibernatedialectMySQLDialect />
<property name=nnectiondriver_class value=commysqljdbcDriver />
<property name=nnectionusername value=root />
<property name=nnectionpassword value=root />
<property name=nnectionurl value=jdbc:mysql://localhost:/spring_data_jpa?useUnicode=true&characterEncoding=UTF />
<property name=hibernatemax_fetch_depth value= />
<property name=hibernatehbmddlauto value=update />
<property name=hibernateshow_sql value=true />
<property name=hibernateformat_sql value=true />
<property name=javaxpersistencevalidationmode value=none/>
properties>
persistenceunit>
persistence>
Spring配置文件applicationContextxml
在src目录下建立applicationContextxml
applicationContextxml内容如下
xml version= encoding=UTF?> <beans xmlns=
xmlns:xsi=instance
xmlns:context=
xmlns:aop=
xmlns:tx=
xmlns:p=
xmlns:cache=
xmlns:jpa=
xsi:schemaLocation=
beansxsd
contextxsd
aopxsd
txxsd
cachexsd
jpaxsd>
<context:annotationconfig />
<context:componentscan basepackage=cnluxhapp/>
<bean id=entityManagerFactory class=orgspringframeworkormjpaLocalContainerEntityManagerFactoryBean>
<property name=persistenceUnitName value=myJPA/>
bean>
<bean id=transactionManager class=orgspringframeworkormjpaJpaTransactionManager>
<property name=entityManagerFactory ref=entityManagerFactory />
bean>
<tx:annotationdriven transactionmanager=transactionManager/>
<jpa:repositories basepackage=cnluxhapprepository/>
beans>
webxml
webxml内容如下
xml version= encoding=UTF?><webapp version=
xmlns=
xmlns:xsi=instance
xsi:schemaLocation=
app__xsd> <displayname>displayname>
<contextparam>
<paramname>webAppRootKeyparamname>
<paramvalue>springdatajparootparamvalue> contextparam> <contextparam>
<paramname>logjConfigLocationparamname>
<paramvalue>classpath:logjpropertiesparamvalue> contextparam> <listener>
<listenerclass>orgspringframeworkwebutilLogjConfigListenerlistenerclass> listener>
<filter>
<filtername>characterEncodingFilterfiltername>
<filterclass>orgspringframeworkwebfilterCharacterEncodingFilterfilterclass>
<initparam>
<paramname>encodingparamname>
<paramvalue>UTFparamvalue>
initparam>
filter> <filtermapping>
<filtername>characterEncodingFilterfiltername>
<urlpattern>/*urlpattern> filtermapping>
<contextparam>
<paramname>contextConfigLocationparamname>
<paramvalue>classpath:applicationContextxmlparamvalue> contextparam> <listener>
<listenerclass>orgsprntextContextLoaderListenerlistenerclass> listener>
<listener>
<listenerclass>orgspringframeworkwebutilIntrospectorCleanupListenerlistenerclass>
listener>
<welcomefilelist>
<welcomefile>indexjspwelcomefile> welcomefilelist>webapp>
日志配置
在src目录下建立logjproperties文件
logjproperties内容如下
logjrootLogger=INFOCONSOLEFIapache=true # 应用于控制台 logjappenderCONSOLE=orgapachelogjConsoleAppender logjappenderThreshold=INFO logjappenderCONSOLETarget=Systemout logjappenderCONSOLElayout=orgapachelogjPatternLayout logjappenderCONSOLElayoutConversionPattern=[framework] %d %c %r [%t] %p %c %x %m%n #logjappenderCONSOLElayoutConversionPattern=[start]%d{DATE}[DATE]%n%p[PRIORITY]%n%x[NDC]%n%t[THREAD] n%c[CATEGORY]%n%m[MESSAGE]%n%n #应用于文件 logjappenderFILE=orgapachelogjDailyRollingFileAppenderlogjappenderFILEFile=${springdatajparoot}/springdatajpalog logjappenderFILEAppend=true logjappenderFILElayout=orgapachelogjPatternLayout logjappenderFILElayoutConversionPattern=[framework] %d %c %r [%t] %p %c %x %m%n
所有环境配完毕开始写一个Spring Data JPA 的增删改查
)建立相应的包
)领域模型实体类User
package cnluxhappdomain;import javaxpersistenceEntity;import javaxpersistenceGeneratedValue;import javaxpersistenceId;import javaxpersistenceTable;/** * 用户信息 * @author Luxh * */@Entity@Table(name=t_user)public class User {
@Id
@GeneratedValue
private Integer id;
//账号
private String account;
//姓名
private String name;
//密码
private String password;
//省略 getter和setter方法}
)声明持久层接口UserRepository
让UserRepository接口继承CrudRepositoryT是领域实体ID是领域实体的主键类型CrudRepository实现了相应的增删改查方法
package cnluxhapprepository;import orgspringframeworkdatarepositoryCrudRepository;import cnluxhappdomainUser;/** * 用户持久层接口 * @author Luxh * */public interface UserRepository extends CrudRepository{
}
不再需要持久层接口实现类
)业务层
一般多层架构是控制层调用业务层业务层再调用持久层所以这里写个业务层
a业务层接口
package cnluxhappservice;import cnluxhappdomainUser;/** * 用户业务接口 * @author Luxh * */public interface UserService {
/**
* 保存用户
* @param user
*/
void saveUser(User user)
/**
* 根据id查找用户
* @param id
* @return
*/
User findUserById(Integer id)
/**
* 更新用户
* @param user
*/
void updateUser(User user)
/**
* 根据ID删除用户
* @param id
*/
void deleteUserById(Integer id)
}
b业务层接口实现类
package cnluxhappservice;import orgspringframeworkbeansfactoryannotationAutowired;import orgspringframeworkstereotypeService;import orgspringframeworktransactionannotationTransactional;import cnluxhappdomainUser;import cnluxhapprepositoryUserRepository;/** * 用户业务服务实现类 * @author Luxh * */@Service(userService)public class UserServiceImpl implements UserService{
@Autowired
private UserRepository userRepository;//注入UserRepository
@Override
@Transactional
public void saveUser(User user) {
userRepositorysave(user)
}
@Override
@Transactional(readOnly=true)
public User findUserById(Integer id) {
return userRepositoryfindOne(id)
}
@Override
@Transactional
public void updateUser(User user) {
userRepositorysave(user)
}
@Override
@Transactional
public void deleteUserById(Integer id) {
userRepositorydelete(id)
}}
)编写测试用例
在执行测试的时候发现如下错误
Caused by: javalangNoSuchMethodError: javaxpersistencespiPersistenceUnitInfogetValidationMode()Ljavax/persistence/ValidationMode;
at orghibernateejbEnfigure(EjbConfigurationjava:)
at orghibernateejbHibernatePersistencecreateContainerEntityManagerFactory(HibernatePersistencejava:)
at orgspringframeworkormjpaLocalContainerEntityManagerFactoryBeancreateNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBeanjava:)
at orgspringframeworkormjpaAbstractEntityManagerFactoryBeanafterPropertiesSet(AbstractEntityManagerFactoryBeanjava:)
at orgspringframeworkbeansfactorysupportAbstractAutowireCapableBeanFactoryinvokeInitMethods(AbstractAutowireCapableBeanFactoryjava:)
at orgspringframeworkbeansfactorysupportAbstractAutowireCapableBeanFactoryinitializeBean(AbstractAutowireCapableBeanFactoryjava:)
… more
网上说是新版本的Hibernate跟javaeejar里面的JPA接口沖突了
解决方法移除MyEclipse自带的Java EE Libraries自己新建一个user libraries加入Java EE中的jsfapijarjsfimpljar和jstljar再加入Tomcat中自带的
servletapijar
用servletapijar替换掉javaeejar就没问题了
测试代码
package cnluxhapptest;import orgjunitAssert;import orgjunitTest;import orgjunitrunnerRunWith;import orgspringframeworkbeansfactoryannotationAutowired;import orgsprintextContextConfiguration;import orgsprintextjunitSpringJUnitClassRunner;import cnluxhappdomainUser;import cnluxhappserviceUserService;@RunWith(SpringJUnitClassRunnerclass)@ContextConfiguration({/applicationContextxml}) public class UserTest {
@Autowired
private UserService userService;
//保存用户
@Test
public void testSaveUser() {
User user = new User()
usersetAccount(LiHuai)
usersetName(李坏)
usersetPassword()
userServicesaveUser(user)
}
//根据id查找用户
@Test
public void testFindUserById() {
Integer id = ;
User user = userServicefindUserById(id)
AssertassertEquals(李坏usergetName())
}
//更新用户
@Test
public void testUpdateUser() {
Integer id = ;
User user = userServicefindUserById(id)
usersetName(李寻欢)
userServiceupdateUser(user)
}
//根据id删除用户
@Test
public void testDeleteUserById() {
Integer id = ;
userServicedeleteUserById(id)
}}
使用Spring Data JPA相当的简单我们只需要定义持久层的接口不需要编写实现代码
步骤和注意点
)在spring配置文件中添加仓库接口的扫描路径
)编写领域实体需要按照JPA规范
)编写仓库Repository接口依靠Spring Data规范定义接口方法
比如按照规范定义一个数据访问接口方法 List findByName(String name)
Spring Data JPA 就会自动转化为 select u from User u where uname = ?
可以使用的仓库接口有
Repository:
是 Spring Data的一个核心接口它不提供任何方法开发者需要在自己定义的接口中声明需要的方法
CrudRepository:
继承Repository提供增删改查方法可以直接调用
PagingAndSortingRepository:
继承CrudRepository具有分页查询和排序功能
JpaRepository:
继承PagingAndSortingRepository针对JPA技术提供的接口
JpaSpecificationExecutor:
可以执行原生SQL查询