Spring专题

Spring Data JPA 实现简单的CRUD增删改查源码案例

Spring Data JPA旨在简化JPA基础知识库构建和减少需要与数据库进行通信的代码量。第一部分是如何配置Hibernate作为JPA的实现,第二部分是如何使用JPA实现简单的CRUD操作。

项目依赖下面的包:

BoneCP 0.7.1.RELEASE

Hibernate 4.0.1.Final

Spring Framework 3.1.0.RELEASE

Spring Data JPA 1.0.2

Servlet API 3.0

步骤:

你必须配置所需的依赖。

您必须配置在Spring应用程序上下文配置中配置一个Bean,指定:数据源,事务管理器和实体管理器工厂。

你必须配置Spring数据JPA。

使用Maven配置依赖:

xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">

4.0.0

net.petrikainulainen.spring

data-jpa-tutorial-part-one

war

0.1

Spring Data JPA Tutorial Part One

Spring Data JPA Tutorial Part One

Apache License 2.0

http://www.apache.org/licenses/LICENSE-2.0

http://www.petrikainulainen.net

repository.jboss.org-public

JBoss repository

https://repository.jboss.org/nexus/content/groups/public

4.0.1.Final

5.1.18

1.6.1

3.1.0.RELEASE

UTF-8

org.springframework

spring-beans

${spring.version}

org.springframework

spring-core

${spring.version}

org.springframework

spring-context-support

${spring.version}

org.springframework

spring-context

${spring.version}

org.springframework

spring-jdbc

${spring.version}

org.springframework

spring-orm

${spring.version}

org.springframework

spring-tx

${spring.version}

org.springframework

spring-web

${spring.version}

org.springframework

spring-webmvc

${spring.version}

cglib

cglib

2.2.2

org.springframework.data

spring-data-jpa

1.0.2.RELEASE

org.hibernate

hibernate-core

${hibernate.version}

org.hibernate

hibernate-entitymanager

${hibernate.version}

com.h2database

h2

1.3.160

com.jolbox

bonecp

0.7.1.RELEASE

javax.servlet

javax.servlet-api

3.0.1

provided

javax.servlet

jstl

1.2

org.slf4j

slf4j-api

${slf4j.version}

org.slf4j

slf4j-log4j12

${slf4j.version}

log4j

log4j

1.2.16

junit

junit

4.9

test

data-jpa-tutorial-part-one

org.apache.maven.plugins

maven-compiler-plugin

2.3.2

1.6

1.6

org.apache.maven.plugins

maven-war-plugin

2.1.1

false

org.mortbay.jetty

jetty-maven-plugin

8.1.0.RC2

0

src/main/resources/webdefault.xml

org.apache.maven.plugins

maven-site-plugin

3.0

org.codehaus.mojo

cobertura-maven-plugin

2.5.1

配置Spring的上下文:

import com.jolbox.bonecp.BoneCPDataSource;

import org.hibernate.ejb.HibernatePersistence;

import org.springframework.context.MessageSource;

import org.springframework.context.annotation.*;

import org.springframework.context.support.ResourceBundleMessageSource;

import org.springframework.core.env.Environment;

import org.springframework.orm.jpa.JpaTransactionManager;

import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;

import org.springframework.web.servlet.ViewResolver;

import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import org.springframework.web.servlet.view.InternalResourceViewResolver;

import org.springframework.web.servlet.view.JstlView;

import javax.annotation.Resource;

import javax.sql.DataSource;

/**

* An application context Java configuration class. The usage of Java configuration

* requires Spring Framework 3.0 or higher with following exceptions:

*

*

@EnableWebMvc annotation requires Spring Framework 3.1

*

* @author Petri Kainulainen

*/

@Configuration

@ComponentScan(basePackages = {"net.petrikainulainen.spring.datajpa.controller"})

@EnableWebMvc

@ImportResource("classpath:applicationContext.xml")

@PropertySource("classpath:application.properties")

public class ApplicationContext {

private static final String VIEW_RESOLVER_PREFIX = "/WEB-INF/jsp/";

private static final String VIEW_RESOLVER_SUFFIX = ".jsp";

private static final String PROPERTY_NAME_DATABASE_DRIVER = "db.driver";

private static final String PROPERTY_NAME_DATABASE_PASSWORD = "db.password";

private static final String PROPERTY_NAME_DATABASE_URL = "db.url";

private static final String PROPERTY_NAME_DATABASE_USERNAME = "db.username";

private static final String PROPERTY_NAME_HIBERNATE_DIALECT = "hibernate.dialect";

private static final String PROPERTY_NAME_HIBERNATE_FORMAT_SQL = "hibernate.format_sql";

private static final String PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY = "hibernate.ejb.naming_strategy";

private static final String PROPERTY_NAME_HIBERNATE_SHOW_SQL = "hibernate.show_sql";

private static final String PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN = "entitymanager.packages.to.scan";

private static final String PROPERTY_NAME_MESSAGESOURCE_BASENAME = "message.source.basename";

private static final String PROPERTY_NAME_MESSAGESOURCE_USE_CODE_AS_DEFAULT_MESSAGE = "message.source.use.code.as.default.message";

@Resource

private Environment environment;

@Bean

public DataSource dataSource() {

BoneCPDataSource dataSource = new BoneCPDataSource();

dataSource.setDriverClass(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_DRIVER));

dataSource.setJdbcUrl(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_URL));

dataSource.setUsername(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_USERNAME));

dataSource.setPassword(environment.getRequiredProperty(PROPERTY_NAME_DATABASE_PASSWORD));

return dataSource;

}

@Bean

public JpaTransactionManager transactionManager() throws ClassNotFoundException {

JpaTransactionManager transactionManager = new JpaTransactionManager();

transactionManager.setEntityManagerFactory(entityManagerFactoryBean().getObject());

return transactionManager;

}

@Bean

public LocalContainerEntityManagerFactoryBean entityManagerFactoryBean() throws ClassNotFoundException {

LocalContainerEntityManagerFactoryBean entityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean();

entityManagerFactoryBean.setDataSource(dataSource());

entityManagerFactoryBean.setPackagesToScan(

environment.getRequiredProperty(PROPERTY_NAME_ENTITYMANAGER_PACKAGES_TO_SCAN));

entityManagerFactoryBean.setPersistenceProviderClass(HibernatePersistence.class);

Properties jpaProterties = new Properties();

jpaProterties.put(PROPERTY_NAME_HIBERNATE_DIALECT, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));

jpaProterties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));

jpaProterties.put(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_NAMING_STRATEGY));

jpaProterties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, environment.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));

entityManagerFactoryBean.setJpaProperties(jpaProterties);

return entityManagerFactoryBean;

}

@Bean

public MessageSource messageSource() {

ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();

messageSource.setBasename(

environment.getRequiredProperty(PROPERTY_NAME_MESSAGESOURCE_BASENAME));

messageSource.setUseCodeAsDefaultMessage(

Boolean.parseBoolean(

environment.getRequiredProperty(PROPERTY_NAME_MESSAGESOURCE_USE_CODE_AS_DEFAULT_MESSAGE)));

return messageSource;

}

@Bean

public ViewResolver viewResolver() {

InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();

viewResolver.setViewClass(JstlView.class);

viewResolver.setPrefix(VIEW_RESOLVER_PREFIX);

viewResolver.setSuffix(VIEW_RESOLVER_SUFFIX);

return viewResolver;

}

}

注意@PropertySource,其中文件配置了数据库参数

# The default database is H2 memory database but I have also

# added configuration needed to use either MySQL and PostgreSQL.

#Database Configuration

db.driver=org.h2.Driver

#db.driver=com.mysql.jdbc.Driver

#db.driver=org.postgresql.Driver

db.url=jdbc:h2:mem:datajpa

#db.url=jdbc:mysql://localhost:3306/datajpa

#db.url=jdbc:postgresql://localhost/datajpa

db.username=sa

db.password=

#Hibernate Configuration

hibernate.dialect=org.hibernate.dialect.H2Dialect

#hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect

#hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

hibernate.format_sql=true

hibernate.ejb.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy

hibernate.show_sql=true

#MessageSource

message.source.basename=i18n/messages

message.source.use.code.as.default.message=true

#EntityManager

#Declares the base package of the entity classes

entitymanager.packages.to.scan=net.petrikainulainen.spring.datajpa.model

配置Spring Data JPA

xmlns:jpa="http://www.springframework.org/schema/data/jpa"

xmlns:mvc="http://www.springframework.org/schema/mvc"

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xsi:schemaLocation="

http://www.springframework.org/schema/beans

http://www.springframework.org/schema/beans/spring-beans-3.1.xsd

http://www.springframework.org/schema/data/jpa

http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd

http://www.springframework.org/schema/mvc

http://www.springframework.org/schema/mvc/spring-mvc-3.1.xsd">

准备工作完成,下面进入开发:

实施Person模型对象

创建一个Person对象库

创建的存储库

Person模型对象:

* A Builder class used to create new Person objects.

*/

public static class Builder {

Person built;

/**

* Creates a new Builder instance.

* @param firstName The first name of the created Person object.

* @param lastName  The last name of the created Person object.

*/

Builder(String firstName, String lastName) {

built = new Person();

built.firstName = firstName;

built.lastName = lastName;

}

/**

* Builds the new Person object.

* @return  The created Person object.

*/

public Person build() {

return built;

}

}

/**

* This setter method should only be used by unit tests.

* @param id

*/

protected void setId(Long id) {

this.id = id;

}

}

创建从界面到后端的DTO:PersonDTO

import org.apache.commons.lang.builder.ToStringBuilder;

import org.hibernate.validator.constraints.NotEmpty;

/**

* A DTO object which is used as a form object

* in create person and edit person forms.

* @author Petri Kainulainen

*/

public class PersonDTO {

private Long id;

@NotEmpty

private String firstName;

@NotEmpty

private String lastName;

public PersonDTO() {

}

public Long getId() {

return id;

}

public void setId(Long id) {

this.id = id;

}

public String getFirstName() {

return firstName;

}

public void setFirstName(String firstName) {

this.firstName = firstName;

}

public String getLastName() {

return lastName;

}

public void setLastName(String lastName) {

this.lastName = lastName;

}

@Override

public String toString() {

return ToStringBuilder.reflectionToString(this);

}

}

服务实现:

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

/**

* This implementation of the PersonService interface communicates with

* the database by using a Spring Data JPA repository.

* @author Petri Kainulainen

*/

@Service

public class RepositoryPersonService implements PersonService {

private static final Logger LOGGER = LoggerFactory.getLogger(RepositoryPersonService.class);

@Resource

private PersonRepository personRepository;

@Transactional

@Override

public Person create(PersonDTO created) {

LOGGER.debug("Creating a new person with information: " + created);

Person person = Person.getBuilder(created.getFirstName(), created.getLastName()).build();

return personRepository.save(person);

}

@Transactional(rollbackFor = PersonNotFoundException.class)

@Override

public Person delete(Long personId) throws PersonNotFoundException {

LOGGER.debug("Deleting person with id: " + personId);

Person deleted = personRepository.findOne(personId);

if (deleted == null) {

LOGGER.debug("No person found with id: " + personId);

throw new PersonNotFoundException();

}

personRepository.delete(deleted);

return deleted;

}

@Transactional(readOnly = true)

@Override

public List findAll() {

LOGGER.debug("Finding all persons");

return personRepository.findAll();

}

@Transactional(readOnly = true)

@Override

public Person findById(Long id) {

LOGGER.debug("Finding person by id: " + id);

return personRepository.findOne(id);

}

@Transactional(rollbackFor = PersonNotFoundException.class)

@Override

public Person update(PersonDTO updated) throws PersonNotFoundException {

LOGGER.debug("Updating person with information: " + updated);

Person person = personRepository.findOne(updated.getId());

if (person == null) {

LOGGER.debug("No person found with id: " + updated.getId());

throw new PersonNotFoundException();

}

person.update(updated.getFirstName(), updated.getLastName());

return person;

}

/**

* This setter method should be used only by unit tests.

* @param personRepository

*/

protected void setPersonRepository(PersonRepository personRepository) {

this.personRepository = personRepository;

}

}

编写服务的单元测试:

import org.junit.Before;

import org.junit.Test;

import org.mockito.ArgumentCaptor;

import static junit.framework.Assert.assertEquals;

import static org.mockito.Mockito.*;

public class RepositoryPersonServiceTest {

private static final Long PERSON_ID = Long.valueOf(5);

private static final String FIRST_NAME = "Foo";

private static final String FIRST_NAME_UPDATED = "FooUpdated";

private static final String LAST_NAME = "Bar";

private static final String LAST_NAME_UPDATED = "BarUpdated";

private RepositoryPersonService personService;

private PersonRepository personRepositoryMock;

@Before

public void setUp() {

personService = new RepositoryPersonService();

personRepositoryMock = mock(PersonRepository.class);

personService.setPersonRepository(personRepositoryMock);

}

@Test

public void create() {

PersonDTO created = PersonTestUtil.createDTO(null, FIRST_NAME, LAST_NAME);

Person persisted = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);

when(personRepositoryMock.save(any(Person.class))).thenReturn(persisted);

Person returned = personService.create(created);

ArgumentCaptor personArgument = ArgumentCaptor.forClass(Person.class);

verify(personRepositoryMock, times(1)).save(personArgument.capture());

verifyNoMoreInteractions(personRepositoryMock);

assertPerson(created, personArgument.getValue());

assertEquals(persisted, returned);

}

@Test

public void delete() throws PersonNotFoundException {

Person deleted = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);

when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(deleted);

Person returned = personService.delete(PERSON_ID);

verify(personRepositoryMock, times(1)).findOne(PERSON_ID);

verify(personRepositoryMock, times(1)).delete(deleted);

verifyNoMoreInteractions(personRepositoryMock);

assertEquals(deleted, returned);

}

@Test(expected = PersonNotFoundException.class)

public void deleteWhenPersonIsNotFound() throws PersonNotFoundException {

when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(null);

personService.delete(PERSON_ID);

verify(personRepositoryMock, times(1)).findOne(PERSON_ID);

verifyNoMoreInteractions(personRepositoryMock);

}

@Test

public void findAll() {

List persons = new ArrayList();

when(personRepositoryMock.findAll()).thenReturn(persons);

List returned = personService.findAll();

verify(personRepositoryMock, times(1)).findAll();

verifyNoMoreInteractions(personRepositoryMock);

assertEquals(persons, returned);

}

@Test

public void findById() {

Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);

when(personRepositoryMock.findOne(PERSON_ID)).thenReturn(person);

Person returned = personService.findById(PERSON_ID);

verify(personRepositoryMock, times(1)).findOne(PERSON_ID);

verifyNoMoreInteractions(personRepositoryMock);

assertEquals(person, returned);

}

@Test

public void update() throws PersonNotFoundException {

PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);

Person person = PersonTestUtil.createModelObject(PERSON_ID, FIRST_NAME, LAST_NAME);

when(personRepositoryMock.findOne(updated.getId())).thenReturn(person);

Person returned = personService.update(updated);

verify(personRepositoryMock, times(1)).findOne(updated.getId());

verifyNoMoreInteractions(personRepositoryMock);

assertPerson(updated, returned);

}

@Test(expected = PersonNotFoundException.class)

public void updateWhenPersonIsNotFound() throws PersonNotFoundException {

PersonDTO updated = PersonTestUtil.createDTO(PERSON_ID, FIRST_NAME_UPDATED, LAST_NAME_UPDATED);

when(personRepositoryMock.findOne(updated.getId())).thenReturn(null);

personService.update(updated);

verify(personRepositoryMock, times(1)).findOne(updated.getId());

verifyNoMoreInteractions(personRepositoryMock);

}

private void assertPerson(PersonDTO expected, Person actual) {

assertEquals(expected.getId(), actual.getId());

assertEquals(expected.getFirstName(), actual.getFirstName());

assertEquals(expected.getLastName(), expected.getLastName());

}

}

java增删改查实例源码_Spring Data JPA 实现简单的CRUD增删改查源码案例相关推荐

  1. spring data jpa从入门到精通_Spring Data JPA的简单入门

    前言 spring data JPA是spring团队打造的sping生态全家桶的一部分,本身内核使用的是hibernate核心源码,用来作为了解java持久层框架基本构成的样本是再好不过的选择.最近 ...

  2. mysql jpa 正则_Spring Data JPA 实例查询

    数量:1 刘芳 三.认识"实例查询" 1.概念定义: 上面例子中,是这样创建"实例"的:Example ex = Example.of(customer, ma ...

  3. jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结

    一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一.  诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...

  4. jpa 定义中间表实体_Spring Data JPA实体详解

    1. Spring Data JPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系数据库的映射,此类Java对象称为JPA实体或简称实体.实体通常与底层数据库中的单个关系 ...

  5. 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式

    Spring Data JPA的运行原理: @PersistenceContext(name="entityManagerFactory") private EntityManag ...

  6. jpa多表联查动态_Spring Data JPA实现动态多表关联查询

    在面向关系型数据库(例如:MySQL)的查询中,动态的.多表关联的查询属于比较复杂的情况.所以,我们只要掌握了这种复杂的查询,当面对其他查询情况时,就能做到胸有成竹. 在java工程中,目前我所了解到 ...

  7. vue结合php增删改查实例,从vue基础开始创建一个简单的增删改查的实例

    1.安装vue-clicnpm install vue-cli -g  --执行全局安装 2.创建一个webpack的基础项目:命令:vue init webpack myproject; 以下是项目 ...

  8. java多表查询返回数据_spring data jpa如何在多张数据库表中查询返回某些字段值?...

    对于多表联查需要使用springdata jpa的@Query标注实现,例如最代码的我的私信列表的查询:public static final String POSTREPOSITORY_FINDAL ...

  9. jpa mysql存储过程_spring data jpa 如何调用mysql存储过程?

    A:首先定义存储过程依赖的jpa表: @Entity @Table(name="evenmngt_childthingtree_tmp")//数据库中的表名 @NamedStore ...

最新文章

  1. wordpress安装
  2. OPNFV董事邓辉:网络功能虚拟化开源平台OPNFV介绍
  3. AngularJs创建自己的Grid–分页组件
  4. Django REST framework快速入门
  5. JS实现App扫码网页端登录
  6. setjump, longjump学习
  7. 关于SQlserver数据库的加密应用
  8. Lesson Plan 教学计划 翻译
  9. 编译期会出现错误提示有哪些_Webpack 5有哪些值得期待
  10. 【转载】在.NET环境中实现每日构建--NAnt篇
  11. ORACLE锁的管理
  12. Linux下用客户端连接校园网
  13. 中控考勤机忘记密码处理
  14. html网页怎么分页打印,web如何实现页面分页打印
  15. 苹果uwb_苹果发布会前瞻:iPhone12还得再等等 UWB或成最大惊喜
  16. 服务器远程桌面连接不上(远程桌面连接服务器之超级VPS管理器)
  17. Zabbix发送带附件的邮件
  18. OC / Swift / Xcode - 怎么私有化init 方法(禁止调用init方法生成对象)
  19. some untracked working tree files问题解决
  20. 2021-2027全球与中国汽车电动四分之一回转执行器市场现状及未来发展趋势

热门文章

  1. java win8 mac地址_Windows8系统下MAC地址修改方法图文教程
  2. python爬取百度文库付费文档_亲测免费转换百度文库付费文件
  3. java c static块_java静态块
  4. java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例
  5. YYDS 的 IDEA插件,没装上的安排起来!
  6. 皮一皮:论一件艺术品的诞生...
  7. 让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航
  8. 《90后程序员职场报告》:平均月薪近20K,每6个程序员就有1个是女性
  9. 超实用的 Mybatis 3.5 新特性
  10. Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失(续)