SpringDataJpa

SpringDataJpaSpringDataJpa

大家好,又见面了,我是你们的朋友全栈君。

入门介绍

SpringData JPA只是SpringData中的一个子模块
JPA是一套标准接口,而Hibernate是JPA的实现
SpringData JPA 底层默认实现是使用Hibernate
SpringDataJPA 的首个接口就是Repository,它是一个标记接口。只要我们的接口实现这个接口,那么我们就相当于在使用SpringDataJPA了。
只要我们实现了这个接口,我们就可以使用”按照方法命名规则”来进行查询。

SpringDataJpa(理解)

  • 1、JPA是Java Persistence API,Java持久化API,是SUN公司推出的一套接口,一套标准
    Hibernate是一个具体的ORM的持久层框架,实现了JPA接口
  • 2、Spring Data是Spring开发团队提供的一套标准API和不同持久层整合技术实现
    Spring Data的出现就是为了简化、统一持久层的各种实现技术API
    Spring Data在项目里以spring-data-commons这个jar存在
  • 3、Spring Data JPA既实现了Spring Data接口,又实现了JPA接口,也是为了简化持久层的开发
    Spring Data JPA在项目里以spring-data-jpa这个jar存在
  • 4、SpringDataJpa原理,参考文档:“SpringDataJpa原理.docx”
    核心:Spring AOP的思想
    a.拿到SimpleJpaRepository的所有方法 具体执行操作的类SimpleJpaRepository
    b.拿到自定义的接口的所有方法
private final Map<Method, RepositoryQuery> queries = new ConcurrentHashMap<Method, RepositoryQuery>();

公用方法(SimpleJpaRepository)+自定义方法(findBy… @Query)

使用简述

  • 两种等价的继承接口方式示例
public interface UserDao extends Repository<AccountInfo, Long> { …… } 
@RepositoryDefinition(domainClass = AccountInfo.class, idClass = Long.class) 
public interface UserDao { …… }

Repository :
CrudRepository :
JpaRepository:

  • 查询关键字概述:
    And — 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
    Or — 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
    Between — 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
    LessThan — 等价于 SQL 中的 “<”,比如 findBySalaryLessThan(int max);
    GreaterThan — 等价于 SQL 中的”>”,比如 findBySalaryGreaterThan(int min);
    IsNull — 等价于 SQL 中的 “is null”,比如 findByUsernameIsNull();
    IsNotNull — 等价于 SQL 中的 “is not null”,比如 findByUsernameIsNotNull();
    NotNull — 与 IsNotNull 等价;
    Like — 等价于 SQL 中的 “like”,比如 findByUsernameLike(String user);
    NotLike — 等价于 SQL 中的 “not like”,比如 findByUsernameNotLike(String user);
    OrderBy — 等价于 SQL 中的 “order by”,比如 findByUsernameOrderBySalaryAsc(String user);
    Not — 等价于 SQL 中的 “! =”,比如 findByUsernameNot(String user);
    In — 等价于 SQL 中的 “in”,比如 findByUsernameIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
    NotIn — 等价于 SQL 中的 “not in”,比如 findByUsernameNotIn(Collection userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;

SpringDataJpa查询Query的使用(重要)

第一种:根据方法命名规则自动生成 findBy
1)基于一列等值查询 findBy列名 例如:findByName(String name)

// 根据收派标准名称查询 
public List<Standard> findByName(String name);

2)基于一列模糊查询findBy列名Like 例如:findByNameLike(String name)
3)基于两列等值查询findBy列名And列名 例如:findByUsernameAndPassword(String username,String password)
第二种:不按命名规则写的查询方法,可以配置@Query绑定JPQL语句或者SQL语句

@Query(value="from Standard where name = ?" ,nativeQuery=false)
// nativeQuery 为 false 配置JPQL,为true 配置SQL 
public List<Standard> queryName(String name);

第三种:不按命名规则写的查询方法,配置@Query,没写语句,实体类@NamedQuery定义(不常用)

@Query
public List<Standard> queryName2(String name);
@NamedQueries({
@NamedQuery(name="Standard.queryName2",query="from Standard where name=?")
})

@Query+@Modifying注解完成修改、删除操作(重要)

  • 1、修改
    @Query(value="update Standard set minLength=?2 where id =?1")
    @Modifying
    public void updateMinLength(Integer id , Integer minLength);
  • 2、测试
    Junit单元测试,要添加事务,设置事务不回滚
    @Test
    @Transactional
    @Rollback(false)
    public void testUpdate(){
    standardRepository.updateMinLength(1, 3);
    } 

例子:

比如:定义下面这么一个方法,就可以在外界使用了。

Employee findByName(String name);

也就是说,上面的方法会被解析成SQL语句:select * from Employee where name = ?
是不是觉得很方便!!!!
如果是简单的操作的话,直接定义这么一个方法,就能够使用了。确确实实很好。
简直比Mytais不知道好到哪里去了。Mybatis还要去写映射文件,专门写一个sql语句。
同时,创建了实体就能够自动帮我们创建数据库表了,修改了实体字段也能够将数据表一起修改。顿时就觉得很好用了。

/**
 * 雇员:  先开发实体类===>自动生成数据表
 */
@Entity
public class Employee {

    private Integer id;

    private String name;

    private Integer age;

    @GeneratedValue
    @Id
    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    @Column(length = 20)
    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

当然了,上面根据方法名来使用是有弊端的:

1)方法名会比较长: 约定大于配置
2)对于一些复杂的查询,是很难实现

比如:

    // where name like ?% and age <?
    public List<Employee> findByNameStartingWithAndAgeLessThan(String name, Integer age);

    // where name like %? and age <?
    public List<Employee> findByNameEndingWithAndAgeLessThan(String name, Integer age);

    // where name in (?,?....) or age <?
    public List<Employee> findByNameInOrAgeLessThan(List<String> names, Integer age);

    // where name in (?,?....) and age <?
    public List<Employee> findByNameInAndAgeLessThan(List<String> names, Integer age);

因此,对于这种情况下还是要写SQL语句简单得多。

    @Query("select o from Employee o where id=(select max(id) from Employee t1)")
    public Employee getEmployeeByMaxId();

    @Query("select o from Employee o where o.name=?1 and o.age=?2")
    public List<Employee> queryParams1(String name, Integer age);

    @Query("select o from Employee o where o.name=:name and o.age=:age")
    public List<Employee> queryParams2(@Param("name")String name, @Param("age")Integer age);

    @Query("select o from Employee o where o.name like %?1%")
    public List<Employee> queryLike1(String name);

    @Query("select o from Employee o where o.name like %:name%")
    public List<Employee> queryLike2(@Param("name")String name);

    @Query(nativeQuery = true, value = "select count(1) from employee")
    public long getCount();

学过Hibernate的都知道上面的不是原生的SQL语句,是HQL/JPQL语句。不过他用起来还是比Mybatis简洁很多。
对于修改数据,需要增加Modify注解、并且一定要在事务的管理下才能修改数据

 @Modifying
    @Query("update Employee o set o.age = :age where o.id = :id")
    public void update(@Param("id")Integer id, @Param("age")Integer age);
  • 排序、分页接口:
    PagingAndSortingRespository接口:包含分页和排序功能,排序查询findAll(Sort sort),带排序的分页查询:findAll(Pageable pageable)
    在这里插入图片描述
    Ps:数据库的级联很麻烦,待学习

Spring Data JPA 对事务的支持

默认情况下,Spring Data JPA 实现的方法都是使用事务的。针对查询类型的方法,其等价于 @Transactional(readOnly=true);增删改类型的方法,等价于 @Transactional。可以看出,除了将查询的方法设为只读事务外,其他事务属性均采用默认值。

如果用户觉得有必要,可以在接口方法上使用 @Transactional 显式指定事务属性,该值覆盖 Spring Data JPA 提供的默认值。同时,开发者也可以在业务层方法上使用 @Transactional 指定事务属性,这主要针对一个业务层方法多次调用持久层方法的情况。持久层的事务会根据设置的事务传播行为来决定是挂起业务层事务还是加入业务层的事务。具体 @Transactional 的使用,请参考 Spring的参考文档。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/106606.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 花了一个周末折腾蜗牛星际的黑群晖,多图预警!

    花了一个周末折腾蜗牛星际的黑群晖,多图预警!简介不知道什么是蜗牛星际的,可以自行百度下,顺便在引用一下矿难的前因后果:最近大量蜗牛星际二手主机在咸鱼售卖,是什么原因?总之我花了349块买了台D款的蜗牛星际J1900(有ABCD款,D款最新,也贵),买来是老板没有帮我装好黑群晖,只能自己来了。强烈建议不爱折腾或者动手能力差的,买装好系统的。不过吧,折腾起来也挺好玩的,以后系统出问题了也能自己修复。接下来我要介绍一下我安装黑群晖的过…

    2022年5月16日
    459
  • 深度图可视化

    深度图可视化之前一直以为深度图应该是黑灰色的,不清楚为什么还有彩色的深度图,直到今天才知道原来这是深度图可视化。专门写篇博客纪念一下!灰黑色的图片人眼很难识别出其中的物体,感知深度的变化。所以才需要可视化,下面是几种颜色空间:…

    2022年4月25日
    47
  • 深入理解JVM的垃圾回收机制

    深入理解JVM的垃圾回收机制上一篇博客介绍了Java运行时内存的各个区域。对于程序计数器、虚拟机栈、本地方法栈这三个部分而言,其生命周期与相关线程有关,随线程而生,随线程而灭。并且这三个区域的内存分配与回收具有确定性,因为当方法结束或者线程结束时,内存就自然跟着线程回收了。因此本篇文章所讲的有关内存分配和回收关注的是Java堆与方法区这两个区域。1、如何判断对象已“死”Java堆中存放着几乎所有的对象实例,垃圾回收器…

    2022年4月29日
    38
  • 5g的控制信道编码方式_5gnr上行支持的信道编码

    5g的控制信道编码方式_5gnr上行支持的信道编码第1章物理层架构1.1物理层内部功能协议栈1.2物理层编码与处理过程(1)信道编码(2)调制解调(3)层映射(4)扩频预编码(仅仅用于上行,可选)(5)多天线技术的预编码(6)资源映射(7)OFDM变换本文主要探讨NR的信道编码技术第2章NR的物理层信道编码技术概述物理层信道编码不是单一的编码,而是有一组编码组成。以发送为例,阐述物理层信道编码的过程以及其中涉及到的主要,接收过程与之相反。(1)TrBloc……

    2025年7月3日
    2
  • 对象

    对象

    2022年3月13日
    37
  • CSS设置超链接样式常用

    CSS设置超链接样式常用伪类名称 含义 示例 a:link 未单击访问时超链接样式 a:link{color:#9ef5f9;} a:visited 单击访问后超链接样式 a:visited{color:#333;} a:hover 鼠标悬浮其上的超链接样式 a:hover{color:#…

    2022年7月19日
    13

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号