相关文章推荐
跑龙套的土豆  ·  Lombok ...·  1 周前    · 
慈祥的黄豆  ·  How to remove illegal ...·  1 年前    · 
很酷的生菜  ·  Jquery.Datatables ...·  1 年前    · 
小眼睛的灭火器  ·  com.google.ar.core.exc ...·  1 年前    · 

环境配置后,开始增删改查,查是用的最多的,放在最后.

增加可以使用JpaRepository接口里面的save方法.查看源码可以发现实际上是使用了 em.persist(entity) 来使对象进入持久化状态,最后提交事务的时候再一起更新到数据库.

        User user = new User();
        user.setId(99);
        user.setAddress("上海");
        user.setName("张三");
        user.setPhone("110");
        //保存单个
        userRepository.save(user);
        //保存或更新
        userRepository.saveAndFlush(user);
        List<User> users = new ArrayList<>();
        users.add(user);
        //保存多个
        userRepository.save(users);
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

这里还可以批量插入,对于mysql支持 INSERT user VALUES (20,'王二','111','111'),(21,'王二','111','111'); 类似这样的sql语句,具体实现就需要自己去写实现了,这样可以一次插入多条记录,效率很高.至于一次插入多少条就可以根据你的业务量来自己制定.

删除都是根据主键来删除的,区别就是多条sql和单条sql

        User user = new User();
        user.setId(21);
        user.setName("王二");
         * 删除都是根据主键删除
        //删除单条,根据主键值
        userRepository.delete(20);
        //删除全部,先findALL查找出来,再一条一条删除,最后提交事务
        userRepository.deleteAll();
        //删除全部,一条sql
        userRepository.deleteAllInBatch();
        List<User> users = new ArrayList<>();
        users.add(user);
        //删除集合,一条一条删除
        userRepository.delete(users);
        //删除集合,一条sql,拼接or语句  如 id=1 or id=2
        userRepository.deleteInBatch(users);
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

修改也是根据主键来更新的

        User user = new User();
        user.setId(1);
        user.setName("张三");
         * 更新也是根据主键来更新  update XX  xx where id=1
        userRepository.saveAndFlush(user);
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

批量更新的话,就调用entityManager的merge函数来更新.

首先在service层获取持久化管理器:

    @PersistenceContext
    private EntityManager em;

批量更新方法,同理插入,删除也都可以如此做.

    @Transactional
    public void batchUpateCustom(List<User> users) {
        // TODO Auto-generated method stub
        for(int i = 0; i < users.size(); i++) {  
            em.merge(users.get(i));  
            if(i % 30== 0) {  
                em.flush();  
                em.clear();  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

单表查询,大部分都可以使用下面三种方法解决,多表联合查询的话,下面方法就不是很实用,下一节分析多表查询.

1.使用JpaRepository方法

        //查找全部
        userRepository.findAll();
        //分页查询全部,返回封装了分页信息
        Page<User> pageInfo = userRepository.findAll(new PageRequest(1, 3, Sort.Direction.ASC,"id"));
        //查找全部,并排序
        userRepository.findAll(new Sort(new Sort.Order(Sort.Direction.ASC,"id")));
        User user = new User();
        user.setName("小红");
        //条件查询,可以联合分页,排序
        userRepository.findAll(Example.of(user));
        //查询单个
        userRepository.findOne(1);
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.解析方法名创建查询

规则: 
find+全局修饰+By+实体的属性名称+限定词+连接词+ …(其它实体属性)+OrderBy+排序属性+排序方向

    //分页查询出符合姓名的记录,同理Sort也可以直接加上
    public List<User> findByName(String name, Pageable pageable);
 

全局修饰: Distinct, Top, First 
关键词: IsNull, IsNotNull, Like, NotLike, Containing, In, NotIn, 
IgnoreCase, Between, Equals, LessThan, GreaterThan, After, Before… 
排序方向: Asc, Desc 
连接词: And, Or

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 类型,也可以是数组或者不定长参数;

嵌套实体:

主实体中子实体的名称+ _ +子实体的属性名称 
List findByAddress_ZipCode(ZipCode zipCode) 
表示查询所有 Address(地址)的zipCode(邮编)为指定值的所有Person(人员)

3.JPQL查询

一个类似HQL的语法,在接口上使用@Query标识

 @Query("select a from user a where a.id = ?1") 
 public User findById(Long id); 

使用@Modifying标识修改

 @Modifying 
 @Query("update User a set a.name = ?1 where a.id < ?2") 
 public int updateName(String name, Long id);
 
  • 1
  • 2
  • 3

携带分页信息:

    @Query("select u from User u where u.name=?1")
    public List<User> findByName(String name, Pageable pageable);

除此之外也可以使用原生sql,只需要@Query(nativeQuery=true)标识即可.

创建查询顺序:

创建查询的顺序 
Spring Data JPA 在为接口创建代理对象时,如果发现同时存在多种上述情况可用,它该优先采用哪种策略呢?为此, 提供了 query-lookup-strategy 属性,用以指定查找的顺序。它有如下三个取值: 
create — 通过解析方法名字来创建查询。即使有符合的命名查询,或者方法通过 @Query 指定的查询语句,都将会被忽略。 
create-if-not-found — 如果方法通过 @Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则通过解析方法名字来创建查询。这是 query-lookup-strategy 属性的默认值。 
use-declared-query — 如果方法通过 @Query 指定了查询语句,则使用该语句实现查询;如果没有,则查找是否定义了符合条件的命名查询,如果找到,则使用该命名查询;如果两者都没有找到,则抛出异常。

计数就直接使用JpaRepository的count方法

        //查找总数量
        userRepository.count();
        User user = new User();
        user.setName("小红");
        //条件计数
        userRepository.count(Example.of(user));
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

6.判断是否存在

计数就直接使用JpaRepository的exists方法

        //根据主键判断是否存在
        userRepository.exists(1);
        User user = new User();
        user.setName("小红");
        //根据条件判断是否存在
        userRepository.exists(Example.of(user));
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

7.自定义查询

首先自定义一个接口,用于定义自定义方法,如UserRepositoryCustom

然后让UserRepository实现该接口,这样的话就可以使用其中的方法.

然后写UserRepositoryImpl实现UserRepositoryCustom接口

最后设置jpa:repositoriesrepository-impl-postfix="Impl",这样的话JPA会查找自定义实现类命名规则,这样的话JPA在相应UserRepository包下面查找实现类,找到则会使用其中的实现方法,而不去自己实现.

具体可以看项目demo,或者下一节的复杂查询

1.尽量避免getSingleResult

下面是该方法的部分源码,可以看出,如果查询出来的个数为0或者大于1都抛出异常,一般来说我们希望查找不到就返回null,而抛异常则是不想看到的,如果要使用,则需要try一下该代码块,在catch里面返回null.

        try {
            List he = this.query.list();
            if(he.size() == 0) {
                NoResultException uniqueResult1 = new NoResultException("No entity found for query");
                this.getEntityManager().handlePersistenceException(uniqueResult1);
                throw uniqueResult1;
            } else if(he.size() > 1) {
                HashSet uniqueResult = new HashSet(he);
                if(uniqueResult.size() > 1) {
                    NonUniqueResultException nure = new NonUniqueResultException("result returns more than one elements");
                    this.getEntityManager().handlePersistenceException(nure);
                    throw nure;
                } else {
                    return uniqueResult.iterator().next();
            } else {
                return he.get(0);
        } catch (QueryExecutionRequestException var4) {
            throw new IllegalStateException(var4);
        } catch (TypeMismatchException var5) {
            throw new IllegalArgumentException(var5);
        } catch (HibernateException var6) {
            throw this.getEntityManager().convert(var6);
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

基本增删改查就是以上这些,都很容易上手,个人感觉比mybatis方便多了.初学该框架,借鉴了很多博客,更多使用技巧还要在实战中发现,如果问题,请留言交流.

代码地址:

更新时候不能直接保存页面的数据dto,应该通过查询或者级联获取到数据库中的持久化状态数据才可以更新。 可以使用org.springframework.beans.BeanUtils.copyProperties(dto,实体,"id","en... @Repository public interface PersonDao extends JpaRepository<PersonPO,String>, JpaSpecificationExecutor<PersonPO>{ 在controller层注入该类,并调用即可 默认的删除方法有: delete(实体),只能传入一个可以对应到数据库的实体,即数据库中存在一样的数据 根据源码我们可以看出来,save是先通过判断这个对象是不是新的,新的便会新增,否则就是执行的修改。整个是有分两步进行的,先查询再新增saveAll()方法是一种更新多条的一种方式,里面传的存对象的集合。分析源码我们可以看出saveAll()底层还是调用的save()方法,也就是每次需要先查询再做修改。在使用上方便,但是因每次涉及到查询、新增,事务的关系,导致修改或者新增耗时得非常的久。那么下面我们将结合EntityManager对批量新增,修改做出优化。 上一篇文章介绍了如何快速的搭建一个JPA的项目环境,并给出了一个简单的演示demo,接下来我们开始业务教程,也就是我们常说的CURD,接下来进入第一篇,如何添加数据通过本篇文章,你可以get到以下技能点POJO对象如何与表关联如何向DB中添加单条记录如何批量向DB中添加记录save 与 saveAndFlush的区别I. 环境准备实际开始之前,需要先走一些必要的操作,如安装测试使用mysql,创建... package com.example.example1; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; @Entity public class Us. Spring Data JPA学习 Spring Boot可以访问关系型数据库和非关系型数据库,Spring DataSpring访问数据库的一揽子解决方案,一个伞形项目,包含大量关系型数据库和非关系型数据库的数据访问解决方案。 Spring Data JPASpring Data的一个子项目,在讲解Spring Data JPA之前,先了解一下Hibernate,因为Spring Data JPA是由Hibernate默认实现的。 Hibernate是一个开源的关系映射框架,它对JDBC进行了非常轻量 springboot整合jpa,对两表查询,接口JpaRepository的使用进行实例演示,并拓展出如何在接口中定义自定义的方法和使用jpa注解使用SQL语句等内容。 实习期间一个任务对接webservice接口,将返回来的数据同步到自己的数据库中,同步的思路简单粗暴,直接删除自己表中的全部数据,再将接口返回的数据全部插进去。 一开始用spring data jpa中的deleteAll()和saveAll()这两个方法,能实现需求,但是性能太差,原因在于 deleteAll()要先进行一次全表查询,然后再根据主键一条条删除 saveAll()每次插入前都进行一遍查询,查询是否存在,存在则更新,否则插入 使用deleteAllInBatch()替换 StudentServiceImpl.java @Service("studentServiceImpl") public class StudentServiceImpl implements StudentService { @Autowired private StudentRepository student Spring Boot 建立在 Spring 之上,包含了 Spring 的所有特性。并且由于其快速的生产就绪环境使开发人员能够直接专注于逻辑而不是为配置和设置而苦苦挣扎,如今它正成为开发人员的最爱。Spring Boot 是一个基于微服务的框架,在其中制作可用于生产的应用程序只需要很少的时间。以下是 Spring Boot 的一些特性: 它允许避免在 spring 中存在的 XML 的繁重配置 它提供易于维护和创建 REST 端点 它包括嵌入式 Tomcat 服务器 部署非常简单,war和jar. 1、本文将详细阐述如何使用JPA框架对数据库实现增删改查操作,业务中比较常见的应用场景几乎在这里都能看到,并且有详尽的代码可供直观演示,其中遇到的坑也进行了实时标注。 2、JPA的环境配置在前面的章节已有总结,不再赘述,直接上干货。 步骤1:创建实体类对象 @Entity //该注解必须加,表明这是一个与数据库映射的实体类 @Data @NoArgsConstructor @AllArgsConstructor @Table(name = "merchant_info") //项目启动后 SpringDataJpa基本增删改查自定义查询与更新jpa实现分页批量操作批量保存跟删除批量更新以上部分的完整代码 基本增删改查 每个Repository都需要实现JpaRepository<T, ID>,然后可根据标准化的操作方式以及实体字段来定义接口方法,优势在查询方面,支持多字段,多类型(大于、小于、等于、in、like、between and。。。) @Repository 一、基本介绍 JPA诞生的缘由是为了整合第三方ORM框架,建立一种标准的方式,百度百科说是JDK为了实现ORM的天下归一,目前也是在按照这个方向发展,但是还没能完全实现。在ORM框架中,Hibernate是一支很大的部队,使用很广泛,也很方便,能力也很强,同时Hibernate也是和JPA整合的比较良好,我们可以认为JPA是标准,事实上也是,JPA几乎都是接口,实现都是Hiber... 1.spring data jpa 官网地址:https://projects.spring.io/spring-data-jpa/ 2.JpaRepository接口地址:https://docs.spring.io/spring-data/jpa/docs/2.1.0.RELEASE/api/ 父接口:CrudRepository&lt;T,ID&gt;, PagingAnd...