java增删改查实例源码_Spring Data JPA 实现简单的CRUD增删改查源码案例
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增删改查源码案例相关推荐
- spring data jpa从入门到精通_Spring Data JPA的简单入门
前言 spring data JPA是spring团队打造的sping生态全家桶的一部分,本身内核使用的是hibernate核心源码,用来作为了解java持久层框架基本构成的样本是再好不过的选择.最近 ...
- mysql jpa 正则_Spring Data JPA 实例查询
数量:1 刘芳 三.认识"实例查询" 1.概念定义: 上面例子中,是这样创建"实例"的:Example ex = Example.of(customer, ma ...
- jpa 动态查询条件 数组_Spring data jpa 复杂动态查询方式总结
一.Spring data jpa 简介 首先JPA是Java持久层API,由Sun公司开发, 希望整合ORM技术,实现天下归一. 诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,目前也是 ...
- jpa 定义中间表实体_Spring Data JPA实体详解
1. Spring Data JPA实体概述 JPA提供了一种简单高效的方式来管理Java对象(POJO)到关系数据库的映射,此类Java对象称为JPA实体或简称实体.实体通常与底层数据库中的单个关系 ...
- 在每个运行中运行多个查询_Spring Data JPA的运行原理及几种查询方式
Spring Data JPA的运行原理: @PersistenceContext(name="entityManagerFactory") private EntityManag ...
- jpa多表联查动态_Spring Data JPA实现动态多表关联查询
在面向关系型数据库(例如:MySQL)的查询中,动态的.多表关联的查询属于比较复杂的情况.所以,我们只要掌握了这种复杂的查询,当面对其他查询情况时,就能做到胸有成竹. 在java工程中,目前我所了解到 ...
- vue结合php增删改查实例,从vue基础开始创建一个简单的增删改查的实例
1.安装vue-clicnpm install vue-cli -g --执行全局安装 2.创建一个webpack的基础项目:命令:vue init webpack myproject; 以下是项目 ...
- java多表查询返回数据_spring data jpa如何在多张数据库表中查询返回某些字段值?...
对于多表联查需要使用springdata jpa的@Query标注实现,例如最代码的我的私信列表的查询:public static final String POSTREPOSITORY_FINDAL ...
- jpa mysql存储过程_spring data jpa 如何调用mysql存储过程?
A:首先定义存储过程依赖的jpa表: @Entity @Table(name="evenmngt_childthingtree_tmp")//数据库中的表名 @NamedStore ...
最新文章
- wordpress安装
- OPNFV董事邓辉:网络功能虚拟化开源平台OPNFV介绍
- AngularJs创建自己的Grid–分页组件
- Django REST framework快速入门
- JS实现App扫码网页端登录
- setjump, longjump学习
- 关于SQlserver数据库的加密应用
- Lesson Plan 教学计划 翻译
- 编译期会出现错误提示有哪些_Webpack 5有哪些值得期待
- 【转载】在.NET环境中实现每日构建--NAnt篇
- ORACLE锁的管理
- Linux下用客户端连接校园网
- 中控考勤机忘记密码处理
- html网页怎么分页打印,web如何实现页面分页打印
- 苹果uwb_苹果发布会前瞻:iPhone12还得再等等 UWB或成最大惊喜
- 服务器远程桌面连接不上(远程桌面连接服务器之超级VPS管理器)
- Zabbix发送带附件的邮件
- OC / Swift / Xcode - 怎么私有化init 方法(禁止调用init方法生成对象)
- some untracked working tree files问题解决
- 2021-2027全球与中国汽车电动四分之一回转执行器市场现状及未来发展趋势
热门文章
- java win8 mac地址_Windows8系统下MAC地址修改方法图文教程
- python爬取百度文库付费文档_亲测免费转换百度文库付费文件
- java c static块_java静态块
- java 解压缩 工具类_Java实现的zip压缩及解压缩工具类示例
- YYDS 的 IDEA插件,没装上的安排起来!
- 皮一皮:论一件艺术品的诞生...
- 让 Linux 防火墙新秀 nftables 为你的 VPS 保驾护航
- 《90后程序员职场报告》:平均月薪近20K,每6个程序员就有1个是女性
- 超实用的 Mybatis 3.5 新特性
- Spring Cloud中Hystrix 线程隔离导致ThreadLocal数据丢失(续)