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)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 使用CocoaPods出现 The `master` repo requires CocoaPods 0.32.1 – 问题解决

    使用CocoaPods出现 The `master` repo requires CocoaPods 0.32.1 – 问题解决

    2021年12月9日
    40
  • Error: A JNI error has occurred, please check your installation and try again解决[通俗易懂]

    Error: A JNI error has occurred, please check your installation and try again解决[通俗易懂]为什么会出现这个问题?因为你的java-verion和javac-version版本不一致为什么两个版本不一致?因为你重复多次安装JDK,导致你的电脑上存在多个JDK版本,这样你运行java命令的时候就会出现这个错。怎么解决两个版本不一致问题?让你的java-verion和javac-version版本不致就可以了怎样保持一致?你要卸载掉旧的JDK,这样剩余的j…

    2022年5月28日
    35
  • python Debug 单步调试[通俗易懂]

    python Debug 单步调试

    2022年1月29日
    43
  • dpkg详解_historian授权

    dpkg详解_historian授权1.dpkg描述    dpkg是一个安装、创建、移除和管理debian包的工具。更多使用界面友好的dpkg的前端”dselect”,。dpkg完全受控于命令行参数,和零个或更多参数正确的组成一个操作方式。参数告诉dpkg要做什么和多种选项控制不同的行为。dpkg不仅提供了大量的参数选项,同时也提供了许多子命令比如:dpkg-debdpkg-divertdpkg-query

    2022年10月6日
    0
  • cubieboard开发板简介

    cubieboard开发板简介Cubieboard,简称Cb,是由珠海的Cubietech团队推出,跟业内有名的pcduino一样,Cubieboard是i基于珠海全志科技的A10/A20等系列处理器的开发板。Cubieboard初次生产是在2012年的8月8日,目前有三代产品,第一代是采用A10的基础版,其中有分8月8日生产的版本和9月9日生产的版本,第二代更换了双核处理器A20,并且经过测试可以稳定地运行在1.2Ghz上,

    2022年7月22日
    9
  • GPS数据格式转换[通俗易懂]

    GPS数据格式转换[通俗易懂]经纬度格式分为三种:度、 度-分、  度-分-秒 1.)ddd.ddddd °【度.度 格式】的十进制小数部分(5位) 2.)ddd°mm.mmm’ 【度分.分 格式】的十进制小数部分(3位) NMEA数据格式为$GPGGA时,得到gps数据为(度分.分)格式 3.) ddd°mm’ss’’ 【度.分.秒 格式】 Goog

    2022年6月16日
    111

发表回复

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

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