SpringDataJPA是Spring基于ORM框架、JPA规范的基础上封装的一套JPA应用框架,底层使用了Hibernate的JPA技术实现。提供了基本CRUD操作。能够满足日常开发过程中对数据库访问的日常需求。特殊的查询还可以自定义查询语句。极简的配置就可以使用起来,极大的减少了开发者的负担。
下面通过一个简单的案例讲述如何使用。
- 引入jar.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
- Spring Boot 入口类上添加@EnableJpaAuditing注解,用于自动创建表。
- application.yml文件中做下配置。
spring:
application:
name: tourist
jpa:
# print sql or not
show-sql: false
open-in-view: false
hibernate:
# 开启自动建表功能,一般选update,每次启动会对比实体和数据表结构是否相同,不相同会更新
ddl-auto: update
naming-strategy: org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy
# 设置创表引擎为Innodb,不然默认为MyiSam
database-platform: org.hibernate.dialect.MySQL5InnoDBDialect
datasource:
url: jdbc:mysql://localhost:3306/tourist?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC
name:
username: root
password:
driver-class-name: com.mysql.cj.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
hikari:
data-source-properties:
cachePrepStmts: true
prepStmtCacheSize: 250
prepStmtCacheSqlLimit: 2048
useServerPrepStmts: true
- 新建一个Entity.
@SuppressWarnings("serial")
@MappedSuperclass
@Data
public abstract class AbstractEntity implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "created_date", columnDefinition = "datetime")
@CreatedDate
private Date createdDate;
@Column(name = "update_date", columnDefinition = "datetime")
@LastModifiedDate
private Date updateDate;
}
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EntityListeners;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.NoArgsConstructor;
@SuppressWarnings("serial")
@Entity
@Data
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "user")
@EntityListeners(AuditingEntityListener.class)
public class User extends AbstractEntity {
@NotNull
@Column(name = "name", columnDefinition = "varchar(10) not null comment '用户名'")
private String name;
@Column(name = "age", columnDefinition = "tinyint(1) not null comment '年龄'")
private Integer age;
@Column(name = "password", columnDefinition = "varchar(60) not null comment '密码'")
private String password;
@NotNull
@Column(name = "phone_number", columnDefinition = "varchar(11) not null comment '手机号'", unique = true)
private String phoneNumber;
}
- 定义持久层.根目录下新建一个package:repository
/**
* Spring Data JPA repository for the User entity.
*/
public interface UserRepository extends JpaRepository<User, Long> {
User findByPhoneNumber(String phoneNumber);
}
- 定义Service层。
@Service
@Slf4j
public class UserService {
@Inject
private UserMapper userMapper;
@Inject
private UserRepository userRepository;
public UserDto findOne(Long id) {
log.debug("get entity by id [{}]", id);
return userMapper.entityToDto(userRepository.findById(id).get(), null);
}
public UserDto create(UserDto dto) {
log.debug("create user [{}]", dto);
User userDb = userRepository.findByPhoneNumber(dto.getPhoneNumber());
if (userDb == null) {
return userMapper.entityToDto(userRepository.save(userMapper.dtoToEntity(dto, null)), null);
}
return userMapper.entityToDto(userDb, null);
}
public void delete(Long id) {
log.debug("delete user by id [{}]", id);
userRepository.deleteById(id);
}
public UserDto update(UserDto dto) {
log.debug("update user [{}]", dto);
return userMapper.entityToDto(userRepository.save(userMapper.dtoToEntity(dto, null)), null);
}
}
附:mapper 类:
public abstract class DeepflowAbstractMapper<E extends AbstractEntity, D extends DeepflowAbstractDto> {
protected final Class<E> entityClazz;
protected final Class<D> dtoClazz;
@SuppressWarnings("unchecked")
public DeepflowAbstractMapper() {
Class<?>[] genericTypes = GenericTypeResolver.resolveTypeArguments(getClass(), DeepflowAbstractMapper.class);
this.entityClazz = (Class<E>) genericTypes[0];
this.dtoClazz = (Class<D>) genericTypes[1];
}
public E dtoToEntity(D dto, String... ignoreProperties) {
if (dto == null)
return null;
E entity = BeanUtils.instantiateClass(this.entityClazz);
copyPropertiesFromDto(dto, entity, ignoreProperties);
return entity;
}
public D entityToDto(E entity, String... ignoreProperties) {
if (entity == null)
return null;
D dto = BeanUtils.instantiateClass(this.dtoClazz);
copyPropertiesFromEntity(entity, dto, ignoreProperties);
return dto;
}
// override if necessary
protected void copyPropertiesFromEntity(E source, D target, String... ignoreProperties) {
BeanUtils.copyProperties(source, target, ignoreProperties);
}
// override if necessary
public void copyPropertiesFromDto(D source, E target, String... ignoreProperties) {
BeanUtils.copyProperties(source, target, ignoreProperties);
}
}
@Component
public class UserMapper extends DeepflowAbstractMapper<User, UserDto> {
}
- 定义controller层方法。
@RestController
@RequestMapping("/users")
public class UserController {
@Inject
private UserService userService;
@GetMapping("/{id}")
public UserDto getUser(@PathVariable Long id) {
return userService.findOne(id);
}
@PostMapping()
public UserDto create(@RequestBody UserDto userDto) {
return userService.create(userDto);
}
@PutMapping()
public UserDto update(@RequestBody UserDto userDto) {
return userService.update(userDto);
}
}
八.测试
在启动项目前,先在数据库里新建一个库:tourist。然后启动项目后,到数据库会发现,数据库里应自动生成里相应的表和字段。可以使用postman去调用户接口。