• Spring Data Jpa


    Spring Data Jpa 简介

      JPA(Java Persistence API)意即Java持久化API,是Sun官方在JDK5.0后提出的Java持久化规范(JSR 338,这些接口所在包为javax.persistence,详细内容可参考https://github.com/javaee/jpa-spec

      JPA的出现主要是为了简化持久层开发以及整合ORM技术,结束Hibernate、TopLink、JDO等ORM框架各自为营的局面。JPA是在吸收现有ORM框架的基础上发展而来,易于使用,伸缩性强。总的来说,JPA包括以下3方面的技术:

    • ORM映射元数据: 支持XML和注解两种元数据的形式,元数据描述对象和表之间的映射关系
    • API: 操作实体对象来执行CRUD操作
    • 查询语言: 通过面向对象而非面向数据库的查询语言(JPQL)查询数据,避免程序的SQL语句紧密耦合
     

    Spring Data Jpa官方解释

      连接:https://spring.io/projects/spring-data-jpa#overview

      
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
     
      
     
     
      
      
      Spring Data JPA是Spring Data家族的一部分,可以轻松实现基于JPA的存储库。 此模块处理对基于JPA的数据访问层的增强支持。 它使构建使用数据访问技术的Spring驱动应用程序变得更加容易。
      在相当长的一段时间内,实现应用程序的数据访问层一直很麻烦。 必须编写太多样板代码来执行简单查询以及执行分页和审计。 Spring Data JPA旨在通过减少实际需要的工作量来显著改善数据访问层的实现。 作为开发人员,您编写repository接口,包括自定义查找器方法,Spring将自动提供实现。

     

     

     

     

     

     

     

     

     

     

    Hibernate、Jpa、Spring Data Jpa三者之间的关系

     Hibernate

      Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,它将POJO与数据库表建立映射关系,是一个全自动的orm框架,hibernate可以自动生成SQL语句,自动执行,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。

     JPA

      JPA全称是Java Persistence API,即java持久化API,是sun公司推出的一套基于ORM的规范,内部由一系列的接口和抽象类构成

     

     

     

     

     

     

     

     

     

     

     

     

    JPA与Hibetnate的关系

      JPA和Hibernate的关系就像JDBC和JDBC驱动的关系,JPA是规范,Hibernate除了作为ORM框架之外,它也是一种JPA实现。JPA怎么取代Hibernate呢?JDBC规范可以驱动底层数据库吗?答案是否定的,也就是说,如果使用JPA规范进行数据库操作,底层需要hibernate作为其实现类完成数据持久化工作。

    Spring Data jpa

      Spring Data JPA 让我们解脱了DAO层的操作,基本上所有CRUD都可以依赖于它来实现,在实际的工作工程中,推荐使用Spring Data JPA + ORM(如:hibernate)完成操作,这样在切换不同的ORM框架时提供了极大的方便,同时也使数据库层操作更加简单,方便解耦

     总结:

      JPA是一种规范,Hibernate实现了JPA规范,即Hibernate为JPA的一种实现;而Spring Data JPA是对JPA进行更高级的封装,让其dao编码变得更简单。
     

    Spring Boot整合Spring Data Jpa

      导入依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

    相关配置

    server:
      port: 9001
    spring:
      application:
        name: service-product
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/practice?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8
        username: root
        password: 123456
      jpa:
        database: mysql
        show-sql: true
        open-in-view: true
        hibernate:
          ddl-auto: update

       ddl-auto

    • create:每次运行程序时,都会重新创建表,故而数据会丢失
    • create-drop:每次运行程序时会先创建表结构,然后待程序结束时清空表
    • upadte:每次运行程序,没有表时会创建表,如果对象发生改变会更新表结构,原有数据不会清空,只会更新(推荐使用)
    • validate:运行程序会校验数据与数据库的字段类型是否相同,字段不同会报错
    • none: 禁用DDL处理

    Spring Data Jpa的使用

      Spring Data Jpa UML类图

     

    简单的REST CRUD示例

      实体类
    package com.jpa.product.entity;
    
            import lombok.Data;
    
            import javax.persistence.*;
            import java.math.BigDecimal;
    
    /**
     * @author: MR.LIU
     * @description:
     * @date: 2020/5/29
     * @time: 22:17
     */
    @Data
    @Entity
    @Table(name = "product")
    public class Product {
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        @Column(name = "id")
        private Long id;
    
        @Column(name = "product_name")
        private String productName;
    
        @Column(name = "price")
        private BigDecimal price;
    
        @Column(name = "description")
        private String description;
    
        @Column(name = "status")
        private Integer status;
    
        @Column(name = "caption")
        private String caption;
    
        @Column(name = "stock")
        private Integer stock;
    }

      一般简单的Demo示例中只会使用@GeneratedValue(strategy = GenerationType.IDENTITY)这种主键自增的策略,而实际数据库中表字段主键类型很少是int型的

    JPA自带的几种主键生成策略

    • TABLE: 使用一个特定的数据库表格来保存主键
    • SEQUENCE: 根据底层数据库的序列来生成主键,条件是数据库支持序列。这个值要与generator一起使用,generator 指定生成主键使用的生成器(可能是orcale中自己编写的序列)
    • IDENTITY: 主键由数据库自动生成(主要是支持自动增长的数据库,如mysql)
    • AUTO: 主键由程序控制,也是GenerationType的默认值

      dao层
    package com.jpa.product.dao;
    
    import com.jpa.product.entity.Product;
    import org.springframework.data.jpa.repository.JpaRepository;
    import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
    
    /**
     * @author: MR.LIU
     * @description: 数据层
     * @date: 2020/5/29
     * @time: 22:34
     */
    public interface ProductDao extends JpaRepository<Product,Long>, JpaSpecificationExecutor<Product> {
    }

     

      service层

    package com.jpa.product.service;
    
    import com.jpa.product.entity.Product;
    
    /**
     * @author: MR.LIU
     * @description: 接口层
     * @date: 2020/5/29
     * @time: 22:37
     */
    public interface ProductService {
        /**
         * 根据id查询
         * @param id
         * @return
         */
        Product findById(Long id);
    
        /**
         * 保存
         * @param product
         * @return
         */
        void save(Product product);
    
        /***
         * 修改
         * @param product
         * @return
         */
        void update(Product product);
    
        /**
         * 删除
         * @param id
         * @return
         */
        void delete(Long id);
    }

      

      impl层

    package com.jpa.product.service.impl;
    
    import com.jpa.product.dao.ProductDao;
    import com.jpa.product.entity.Product;
    import com.jpa.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Service;
    
    /**
     * @author: MR.LIU
     * @description:
     * @date: 2020/5/29
     * @time: 22:41
     */
    @Service
    public class ProductServiceImpl implements ProductService {
        @Autowired
        private ProductDao productDao;
    
        @Override
        public Product findById(Long id) {
            return productDao.findById(id).get();
        }
    
        @Override
        public void save(Product product) {
             productDao.save(product);
        }
    
        @Override
        public void update(Product product) {
            productDao.save(product);
        }
    
        @Override
        public void delete(Long id) {
            productDao.deleteById(id);
        }
    }
      controller层
     
    package com.jpa.product.controller;
    
    import com.jpa.product.entity.Product;
    import com.jpa.product.service.ProductService;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.*;
    
    /**
     * @author: MR.LIU
     * @description:
     * @date: 2020/5/29
     * @time: 22:47
     */
    @RestController
    @RequestMapping(value = "/product")
    public class ProductController {
        @Autowired
        private ProductService productService;
    
        @GetMapping(value = "/{id}")
        public Product getProduct(@PathVariable Long id) {
            return productService.findById(id);
        }
    
        @PostMapping(value = "/save")
        public String saveProduct(@RequestBody Product product){
            productService.save(product);
            return "保存成功";
        }
    
    }
      测试
    http://localhost:9001/product/1

      成功查询

    模糊查询

      自定义DAO接口

    @Query(value = "select * from product where product_name like concat('%',:name,'%')",nativeQuery = true)
        List<Product> findByNameMatch(@Param("name") String name);

      上的SQL语句一定要按照Query的格式来。以上都是写在DAO层(respository层里面)

      @Query注解的用法(Spring Data JPA)  这里参考:http://www.cnblogs.com/zj0208/p/6008627.html

  • 相关阅读:
    爬取B站up主相册原图
    爬MEIZITU网站上的图片
    mpvue
    修改Tomcat控制台标题
    iserver频繁崩溃、内存溢出事故解决小记
    Java反射机制详解 及 Method.invoke解释
    window下maven的环境搭建
    window下mongodb的安装和环境搭建
    centos7 安装 redis4.0.8
    centos7 安装mysql5.7.20(yum方式)
  • 原文地址:https://www.cnblogs.com/topshark/p/12989623.html
Copyright © 2020-2023  润新知