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/106607.html原文链接:https://javaforall.net

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


相关推荐

  • 电脑使用哪个录制视频软件比较好

    电脑使用哪个录制视频软件比较好如今社会从一个开放的年代发展为开放的信息时代,人们对于自我表达越发的大胆。追求标新立意,而视频正好迎合了人群的需要。视频的表现方式比图纸更加直观具有冲击力,更展现更加生动丰富的内容。想要录制视频其实不难,只需要一款专业的录制视频软件就可以帮搜我们达到我们想要的效果。使用工具:电脑(有网络)迅捷屏幕录像工具操作步骤:1、首先电脑在线进入百度浏览器搜索迅捷屏幕录像,并且安装在电脑上进行运行。…

    2022年6月16日
    27
  • 亲手撸了一个SpringBoot+Vue的企业级项目(附源码)

    简介 SpringBoot和Vue,前后端分离,我们开源一套漂亮的代码和一套整洁的代码规范,让大家在这浮躁的代码世界里感受到一股把代码写好的清流!同时又让开发者节省大量的时间,减少…

    2021年6月23日
    116
  • resnet34 pytorch_pytorch参数初始化

    resnet34 pytorch_pytorch参数初始化pytorch是包含一些常见的神经网络模型的,ResNet34、ResNet18、VGG等等,都在models模块中,调用接口如下:model=models.resnet34(pretrained=True,progress=True)预训练pretrained和进度条progress设为True或False就看你自己需求咯~⚠️与此同时,你可能还会遇到pytorch官网的输出类别数与你所需不同:你想分七类,可resnet34官网是1000类,那就调整一下呗:#修改最后线性层的输出通道数

    2022年9月27日
    2
  • 高手社区论坛_高手手机资料论坛

    高手社区论坛_高手手机资料论坛摘取来自:http://blog.csdn.net/xingyu19871124/article/details/4310614高手的博客阿虚的电子小屋http://hi.baidu.com/aokikyon(从单片机到嵌入式linux都有研究)XY嵌入式Linux  http://blog.chinaunix.net/group/group_1488.html(嵌入式内核研

    2022年10月2日
    5
  • 字典树模板及例题_模板计算公式

    字典树模板及例题_模板计算公式转载:Trie树的常见应用大总结(面试+附代码实现)(一)Trie的简介Trie树,又称字典树,单词查找树或者前缀树,是一种用于快速检索的多叉树结构,如英文字母的字典树是一个26叉树,数字的字典树是一个10叉树。他的核心思想是空间换时间,空间消耗大但是插入和查询有着很优秀的时间复杂度。(二)Trie的定义Trie树的键不是直接保存在节点中,而是由节点在树中的位置决定。一个节点的所有子…

    2025年9月26日
    4
  • Eclipse配置Maven详细教程[通俗易懂]

    Eclipse配置Maven详细教程[通俗易懂]一.使用eclipse自带的maven插件首先,现在下载EclipseMars之后的版本,基本上都自带了maven插件,无需自己再安装maven.有几个注意点:1.默认的本地仓库的目录是在C:\Users\viruser.v-desktop\.m2\repository\如果使用系统默认的maven插件,那么建议还是修改下本地仓库的路径,这样节省C盘空间2.使用的maven版…

    2022年5月25日
    39

发表回复

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

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