Spring Data JPA的基础概念及初步上手

一、JPA

1、定义

JPA是Java Persistence API的简称,中文名称为Java持久层API;主要包括以下内容:

(1)一套API标准:在javax.persistence的包下面,用来操作实体对象,执行CRUD操作,让开发者从烦琐的JDBC和SQL代码中解脱出来。
(2)面向对象的查询语言:Java Persistence Query Language(JPQL)。通过面向 对象而非面向数据库的查询语言查询数据,避免程序的SQL语句紧密耦合。
(3)ORM(object/relational metadata)元数据的映射:JPA支持XML和JDK5.0注解两种元数据的形式,元数据描述对象和表之间 的映射关系,框架据此将实体对象持久化到数据库表中。

2、发展

JPA的宗旨是为POJO提供持久化标准规范,经过这几年的实践探索,方便开发和测试的理念已经深入人心了。Hibernate 3.2+、TopLink 10.1.3以及OpenJPA都提供了JPA的实现。目前国外的互联网公司已经大量使用了JPA的开发标准规范。
在这里插入图片描述

二、Spring Data JPA

1、介绍

可以理解为JPA规范的再次封装抽象,底层还是使用了Hibernate的JPA技术实现,引用JPQL(Java Persistence Query Language)查询语言,属于Spring整个生态体系的一部分。随着Spring Boot和Spring Cloud在市场上的流行,Spring Data JPA也逐渐进入大家的视野,它们组成有机的整体,使用起来比较方便,加快了开发的效率,使开发者不需要关心和配置更多的东西,完全可以沉浸在Spring的完整生态标准实现下。JPA上手简单,开发效率高,对对象的支持比较好,又有很大的灵活性,市场的认可度越来越高。

2、Spring Data JPA是Spirng Data的子项目

Spring Data Commons
Spring Data Gemfire
Spring Data JPA
Spring Data KeyValue
Spring Data LDAP
Spring Data MongoDB
Spring Data REST
Spring Data Redis
Spring Data for Apache Cassandra
Spring Data for Apache Solr

3、Spring Data JPA的主要类及结构图

七个Repository接口:

  1. Repository (org.springframework.data.repository)
  2. CrudRepository (org.springframework.data.repository)
  3. PagingAndSortingRepository (org.springframework.data.repository)
  4. QueryByExampleExecutor (org.springframework.data.repository.query)
  5. JpaRepository (org.springframework.data.jpa.repository)
  6. JpaSpecificationExecutor (org.springframework.data.jpa.repository)
  7. QueryDslPredicateExecutor (org.springframework.data.querydsl)

两个实现类:

  • SimpleJpaRepository(org.springframework.data.jpa.repository.support)
  • QueryDslJpaRepository(org.springframework.data.jpa.repository.support)

类结构图:
在这里插入图片描述

三、初步上手:Spring Boot 项目集成Spring Data JPA

1、环境
  • Spring Boot 2.x
  • JDK 1.8
  • Maven 3.0+
  • IntelliJ IDE 2019
  • Mysql5
  • druid1.1
  • log4jdbc1.16
<!--集中管理依赖版本-->
    <properties>
        <!-- JDK版本号 -->
        <java.version>1.8</java.version>
        <!-- druid版本号 -->
        <druid.version>1.1.10</druid.version>
        <!-- log4jdbc版本号 -->
        <log4jdbc.version>1.16</log4jdbc.version>
        <!-- common-pool2版本号 -->
        <commons-pool2.version>2.5.0</commons-pool2.version>
        <!--fastjson版本号-->
        <fastjson.version>1.2.58</fastjson.version>
        <!--mysql版本号-->
        <mysql.version>5.1.47</mysql.version>
        <!--swagger版本号-->
        <swagger.version>2.9.2</swagger.version>
    </properties>

    <!-- 项目继承Spring Boot -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.5.RELEASE</version>
    </parent>
 <!-- 引入外部依赖 -->
    <dependencies>
    	...
        <!--JPA-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        ...
    </dependencies>
2、数据库建表
CREATE TABLE `user`  (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `open_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `nick_name` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `gender` int(11) NULL DEFAULT NULL COMMENT '0-未知 1-male 2-female',
  `avatar_url` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `union_id` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `country` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `province` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `city` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `language` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `email` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `remarks` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `enabled` int(11) NULL DEFAULT 1 COMMENT '1-激活 0-禁用',
  `last_password_reset_time` datetime(0) NULL DEFAULT NULL,
  `create_time` datetime(0) NULL DEFAULT NULL,
  `update_time` datetime(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE,
  UNIQUE INDEX `open_id`(`open_id`) USING BTREE,
  UNIQUE INDEX `user_name`(`user_name`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 8 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;
3、Spring配置文件
#配置数据源
spring:
  datasource:
    druid:
      db-type: com.alibaba.druid.pool.DruidDataSource
      driverClassName: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
      url: jdbc:log4jdbc:mysql://localhost:3306/startup?serverTimezone=Asia/Shanghai&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
      username: root
      password: root

      # 初始化配置
      initial-size: 3
      # 最小连接数
      min-idle: 3
      # 最大连接数
      max-active: 15
      # 获取连接超时时间
      max-wait: 5000
      # 连接有效性检测时间
      time-between-eviction-runs-millis: 90000
      # 最大空闲时间
      min-evictable-idle-time-millis: 1800000
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false

      validation-query: select 1
      # 配置监控统计拦截的filters
      filters: stat
      stat-view-servlet:
        url-pattern: /druid/*
        reset-enable: false

      web-stat-filter:
        url-pattern: /*
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"

#配置 Jpa
  jpa:
    hibernate:
      # 生产环境设置成 none,避免程序运行时自动更新数据库结构
      ddl-auto: none
4、创建实体类
/**
 * 用户表
 *
 * @author zhuhuix
 * @date 2020-04-03
 */
@ApiModel(value = "用户信息")
@Entity
@Getter
@Setter
@Table(name = "user")
public class User implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @NotNull(groups = Update.class)
    private Long id;


    @Column(name = "user_name", unique = true)
    private String userName;

    @JsonIgnore
    private String password;

    /**
     * 微信openId
     */
    @Column(unique = true, name = "open_id")
    private String openId;

    /**
     * 用户昵称
     */
    @Column(name="nick_name")
    private String nickName;

    /**
     * 性别 0-未知 1-male,2-female
     */
    private Integer gender;

    /**
     * 头像地址
     */
    @Column(name = "avatar_url")
    private String avatarUrl;

    @Column(name = "union_id")
    private String unionId;

    private String country;

    private String province;

    private String city;

    private String language;

    @Email
    private String email;

    private String phone;

    private String remarks;

    private Boolean enabled;

    @JsonIgnore
    @Column(name = "last_password_reset_time")
    private Timestamp lastPasswordResetTime;

    @JsonIgnore
    @Column(name = "create_time")
    @CreationTimestamp
    private Timestamp createTime;

    @JsonIgnore
    @Column(name = "update_time")
    @UpdateTimestamp
    private Timestamp updateTime;

}
4、创建Spring Data JPA仓库类(DAO接口)
/**
 * 用户DAO接口层
 * @author zhuhuix
 * @date 2020-04-03
 */
public interface UserRepository extends JpaRepository<User,Long>, JpaSpecificationExecutor<User> {
	//该接口继承JpaRepository及JpaSpecificationExecutor接口,
	//该接口中已包含默认基本的CRUD成员方法,比如:
	//findById,create,delete,update等
}
5、创建服务接口及服务接口实现类调用DAO接口
/**
 * 用户接口实现类
 *
 * @author zhuhuix
 * @date 2020-04-03
 */
@Slf4j
@Service
@Transactional(propagation = Propagation.SUPPORTS, readOnly = true, rollbackFor = Exception.class)
public class UserServiceImpl implements UserService {

    private final UserRepository userRepository;

    public UserServiceImpl(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<User> create(User user) {
        return new Result<User>().ok(userRepository.save(user));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(User user) {
        userRepository.delete(user);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result<User> update(User user) {
        return new Result<User>().ok(userRepository.save(user));
    }

    @Override
    public Result<User> findById(Long id) {
        Optional<User> optional = userRepository.findById(id);
        return optional.map(user -> new Result<User>().ok(user)).orElse(null);
    }

    @Override
    public Result<User> findByOpenId(String openId) {
        return new Result<User>().ok(userRepository.findByOpenId(openId));
    }
}
6、编写测试类进行测试
@SpringBootTest
@Slf4j
public class UserJPATest {
    @Test
    void test() {
        UserService userService = SpringContextHolder.getBean(UserService.class);
        userService.findById(1L);
    }
}

测试图片

四、总结

Spring Data JPA非常强大,且容易上手:在DAO层只需继承默认接口,无需手写SQL语句。测试类进行测试时,Spring Data JPA会根据DAO调用方法,自动生成SQL语句,进行表数据的增删改查。

原创文章 56 获赞 8 访问量 4744

猜你喜欢

转载自blog.csdn.net/jpgzhu/article/details/105434698