SpringBoot 使用JPA操作数据库

       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去调用户接口。

猜你喜欢

转载自blog.csdn.net/zjhcxdj/article/details/96430790