Spring与JPA

    这里我主要用Spring Data实现自动化的JPA Repository。

package com.zzf.finals.repository;

import com.zzf.finals.entity.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface demoRepository extends JpaRepository<demo,Long> {
}

需要导入jar包:

       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

    Spring Data JPA Repository的关键在于要从一组接口中挑选一个进行扩展。这里,SpitterRepository扩展了Spring Data JPA的JpaRepository。通过这种方式,JpaRepository进行了参数化,所以它就能知道这是一个用来持久化demo对象的Repository,并且Spitter的ID类型为Long。另外,它还会继承18个执行持久化操作的通用方法,如保存demo、删除demo以及根据ID查询demo。

    为了要求Spring Data创建demoRepository的实现,我们需要在Spring配置中添加一个元素。如下的程序清单展现了在XML配置中启用Spring Data JPA所需要添加的内容:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://www.springframework.org/schema/data/jpa
       http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

    <jpa:repositories base-package="com.zzf.finals.repository "/>
</beans>
    就像<context:component-scan>元素一样,<jpa:repositories>元素需要指定一个要进行扫描的base-package。不过,<context:component-scan>会扫描包(及其子包)来查找带有@Component注解的类,而<jpa:repositories>会扫描它的基础包来查找扩展自SpringData JPA Repository接口的所有接口。如果发现了扩展自Repository的接口,它会自动生成(在应用启动的时候)这个接口的实现。

    使用java配置方式:

@Configuration
@EnableJpaRepositories(basePackages = "com.zzf.finals.repository")
public class JpaConfiguration{
    
}

    Repository的实现类是在应用启动的时候生成的,也就是Spring的应用上下文创建的时候。它并不是在构建时通过代码生成技术产生的,也不是接口方法调用时才创建的。

 自定义查询方法:

此时我有一个demo.java的实体类

package com.zzf.finals.entity;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import javax.persistence.*;
import java.util.Date;

@Data
@Entity
@Table(name = "seckill")
public class demo {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long seckillId;

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

    @Column(name = "number")
    private int number;


    @Column(name = "start_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date startTime;

    @Column(name = "end_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date endTime;

    @Column(name = "create_time")
    @DateTimeFormat(pattern = "yyyy-MM-dd hh:mm:ss")
    private Date createTime;

    public Long getSeckillId() {
        return seckillId;
    }

    public void setSeckillId(Long seckillId) {
        this.seckillId = seckillId;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getNumber() {
        return number;
    }

    public void setNumber(int number) {
        this.number = number;
    }

    public Date getStartTime() {
        return startTime;
    }

    public void setStartTime(Date startTime) {
        this.startTime = startTime;
    }

    public Date getEndTime() {
        return endTime;
    }

    public void setEndTime(Date endTime) {
        this.endTime = endTime;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public void setCreateTime(Date createTime) {
        this.createTime = createTime;
    }

它对应的数据库为

使用springboot集成jpa需要在application.properties做配置:

spring.datasource.url=jdbc:mysql://localhost:3306/seckill?useUnicode=true&characterEncoding=utf-8&useSSL=true
spring.datasource.username=root
spring.datasource.password=12345678
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
然后就是自定义的接口了,如:
package com.zzf.finals.repository;

import com.zzf.finals.entity.demo;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

@Repository
public interface demoRepository extends JpaRepository<demo,Long> {

    demo findByNumber(int num);

    demo findBySeckillId(Long id);
}
然后在控制器里调用这个接口
    @GetMapping("/jpa")
    public Map<String,Object> Jpagetall(){
        List<demo> a=demoRepository.findAll();
        Map<String,Object> map1 = new HashMap<String,Object>();
        map1.put("data",a);
        return map1;
    }

    @GetMapping("/jpa/id")
    public Map<String,Object> jpayId(int num,long seckillId){
        demo a=demoRepository.findByNumber(num);
        demo b=demoRepository.findBySeckillId(seckillId);
        Map<String,Object> map1 = new HashMap<String,Object>();
        map1.put("findByNumber",a);
        map1.put("findBySeckillId",b);
        return map1;
    }

第一个返回的所有数据:http://localhost:8080/a/jpa/

下面测试的是自定义的接口:http://localhost:8080/a/jpa/id?num=98&seckillId=1001

OK~

    当创建Repository实现的时候,Spring Data会检查Repository接口的所有方法,解析方法的名称,并基于被持久化的对象来试图推测方法的目的。本质上,Spring Data定义了一组小型的领域特定语言(domain-specific language ,DSL),在这里,持久化的细节都是通过Repository方法的签名来描述的。
    方法名findByNumber确定该方法需要根据number属性相匹配来查找demo,而number是作为参数传递到方法中来的。另外,因为在方法签名中定义了该方法要返回一个demo对象,而不是一个集合,因此它只会查找一个number属性匹配的demo。
    Repository方法是由一个动词、一个可选的主题(Subject)、关键词By以及一个断言所组成。在findByNumber()这个样例中,动词是find,断言是Number,主题并没有指定,暗含的主题是demo。

    假设现在有这么一个方法:readSpitterByFirstnameOrLastname()

    这里的动词是read,与之前样例中的find有所差别。Spring Data允许在方法名中使用四种动词:get、read、find和count。其中,动词get、read和find是同义的,这三个动词对应的Repository方法都会查询数据并返回对象。而动词count则会返回匹配对象的数量,而不是对象本身。

readSpittersByFirstnameOrLastname()==readByFirstnameOrLastname()

    在省略主题的时候,有一种例外情况。如果主题的名称以Distinct开头的话,那么在生成查询的时候会确保所返回结果集中不包含重复记录。
    断言是方法名称中最为有意思的部分,它指定了限制结果集的属性。在readByFirstnameOrLastname()这个样例中,会通过firstname属性或lastname属性的值来限制结果。在断言中,会有一个或多个限制结果的条件。每个条件必须引用一个属性,并且还可以指定一种比较操作。如果省略比较操作符的话,那么这暗指是一种相等比较操作。不过,我们也可以选择其他的比较操作,包括如下的种类:

    IsAfter、After、IsGreaterThan、GreaterThan
    IsGreaterThanEqual、GreaterThanEqual
    IsBefore、Before、IsLessThan、LessThan
    IsLessThanEqual、LessThanEqual
    IsBetween、BetweenIsNull、Null
    IsNotNull、NotNull
    IsIn、In
    IsNotIn、NotIn
    IsStartingWith、StartingWith、StartsWith
    IsEndingWith、EndingWith、EndsWith
    IsContaining、Containing、Contains
    IsLike、Like
    IsNotLike、NotLike
    IsTrue、True
    IsFalse、False
    Is、Equals
    IsNot、Not

完整的方法签名如:

参数的名称是无关紧要的,但是它们的顺序必须要与方法名称中的操作符相匹配。
我们还可以在方法名称的结尾处添加OrderBy,实现结果集排序。例如,我们可以按照lastname属性升序排列结果集:

条件部分是通过And或者Or进行分割的。
如果所需的数据无法通过方法名称进行恰当地描述,那么我们可以使用@Query注解,为Spring Data提供要执行的查询。对于findAllGmailSpitters()方法,我们可以按照如下的方式来使用@Query注解:


如果按照命名约定,方法的名称特别长的时候,也可以使用这个注解。

    大致就写这么点吧……个人感觉jpa适合简单查询,增删改之类的额。当你的sql很复杂的话还是用sql语句比较方便,毕竟这方法名那么长不研究一下还真拼不出来……


  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值