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的参考文档。

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

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/106607.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • LAN8720 100M 掉线问题解决

    LAN8720 100M 掉线问题解决最近在做一块板子的时候,使用的phy芯片为LAN8720,在使用的发现老是ping一段时间后自动掉线,从软件问题一直查找,最后发现是LAN8720掉线了,且wang网口绿灯一直常亮,拔线网线也是一样,黄灯不闪烁,且phy发热严重。问题出在本来网口电源是下面这样,但是在焊接时没有找到磁珠,就用0欧电阻代替,结果电源干扰大不稳定,换上磁珠后ping未出现网口掉线现象,发热现象明显减少。…

    2022年10月27日
  • java如何输入字符串_JAVA中怎样输入字符串「建议收藏」

    java如何输入字符串_JAVA中怎样输入字符串「建议收藏」https://zhidao.baidu.com/question/344967589.htmljava.lang.String.charAt()方法返回指定索引处的char值。http://www.yiibai.com/javalang/string_charat.html(toLowerCase)toUpperCase的意思是将所有的英文字符转换为大写字母,如:Stringcc=“a…

  • 永磁直流无刷电机驱动器_永磁直流无刷电机的优缺点

    永磁直流无刷电机驱动器_永磁直流无刷电机的优缺点现实生活中我们接触的电机包括很多种类,除部分特殊种类外,永磁电机均是利用定子与转子磁场相互作用的原理制成。其中,使用直流电源驱动的电机称为直流电机,直流电机又可细分为直流有刷电机和直流无刷电机(BLDC)。电刷,是区分“有刷”与“无刷”电机的关键,它是与换向器组合使用的电机组件,常见材质为金属和碳。带有换向器和电刷的电机称为有刷电机,使用电子电路实现换向功能的电机称为无刷电机。直流有刷电…

    2022年10月21日
  • 入手南洋这么多天,终于等到涨停了,呜哈哈哈,有时候看好的事情要学会等待,守候,意志力要坚定,坚持10天半个月的,一定能有所收获…

    入手南洋这么多天,终于等到涨停了,呜哈哈哈,有时候看好的事情要学会等待,守候,意志力要坚定,坚持10天半个月的,一定能有所收获…

  • 光盘装系统和U盘装系统有什么区别?哪个好?

    光盘装系统和U盘装系统有什么区别?哪个好?光盘装系统和U盘装系统的区别:U盘:U盘安装就是利用U盘启动盘制作工具,制作U盘启动盘,之后从U盘启动WINPE系统,再加载下载好的系统镜像进行安装的方法。  光盘:光盘安装法就是利用购买好的系统盘,或者自己制作的系统盘,利用电脑的光驱,直接加载进行安装的方法。此安装法不用进入任何系统,不是xp、win7,也不是WINPE。  优点比较  U盘:如果当前系统崩溃,无法启动的

  • python进阶(3)json文件与python字典的转化

    python进阶(3)json文件与python字典的转化序列化与反序列化按照某种规则,把内存中的数据保存到文件中,文件是一个字节序列,所以必须要把内存数据转换成为字节序列,输出到文件,这就是序列化;反之,从文件的字节恢复到内存,就是反序列化;pytho

发表回复

您的电子邮箱地址不会被公开。

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