Spring Data JPA 通过不同的方式实现查询操作,Java大厂面试真题

/**

  • 在CustomerDao接口中添加查询方法

*/

@Query(value = “from Customer where custName = ?”)

public Customer findByName(String custName);

/**

  • 在CustomerFindTest中测试根据name查询

*/

@Test

public void testFindJPQL(){

Customer customer=customerDao.findByName("客户1");

System.out.println(customer);

}




**2\. 根据客户名称与客户id查询客户,使用jpql形式实现**



`配置jpql语句,使用应使用@Query注解, jpql语句 : jpql : from Customer where custName = ? and custId = ?`  

对于多个占位符参数:赋值的时候,默认的情况下,占位符的位置需要和方法参数中的位置保持一致,但是可以指定占位符参数的位置 `? 索引` 的方式,指定次占位的取值来源。



/**

  • 在CustomerDao接口中添加查询方法

*/

@Query(value = “from Customer where custName = ? and custId = ?”)

//@Query(value = “from Customer where custId = ?2 and custName = ?1”)

public Customer findCustNameAndId(String name,Long id);

/**

  • 测试根据客户名称与id查询

*/

@Test

public void testFindCustNameAndId(){

Customer customer=customerDao.findCustNameAndId("客户1",1l);

System.out.println(customer);

}




**3\. 使用jpql语句实现更新操作**



`配置jpql语句,使用应使用@Query注解, jpql语句 : jpql : update Customer set custName = ? where custId = ?`  

于查询语句不同,我们还需要对更新操作进行声明`@Modifying :当前执行的更新操作`,同时springDataJpa中使用jpql完成更新或删除操作需要手动添加事务的支持,因为方法在执行结束后默认会执行回滚事务,我们还需要使用`@Rollback(value =false)` 取消回滚



/**

  • 在CustomerDao接口中添加更新语句的方法

*/

@Query(value = “update Customer set custName = ?2 where custId = ?1”)

@Modifying

public void updateCustomer(long custId,String custName);

/**

  • 测试jpql的更新操作

*/

@Test

@Transactional//添加注解支持

@Rollback(value =false)

public void testUpdateCustomer(){

customerDao.updateCustomer(1l,"黑马程序员");

}




**4\. 使用sql语句形式进行查询**



`使用@Query注解,配置sql查询,添加nativeQuery属性修改查询方式:true:sql查询、 false:jpql查询`  

`sql语句 :sql:select * from cst_customer`



/**

  • 在CustomerDao接口中添加查询全部的客户的方法

*/

@Query(value = “select * from cst_customer”,nativeQuery = true)

public List<Object []> findSql();

//测试sql查询

@Test

public void testFindSql(){

List<Object[]> list = customerDao.findSql();

for (Object []obj:list) {

    System.out.println(Arrays.toString(obj));

}

}




**5\. 使用sql语句实现模糊查询**



/**

  • 在CustomerDao接口中添加查询全部的客户的方法

*/

@Query(value = “select * from cst_customer where cust_name like ?”,nativeQuery = true)

public List<Object []> findLikeSql(String name);

//测试sql模糊查询

@Test

public void testFindLikeSql(){

List<Object[]> list = customerDao.findLikeSql("%程序员");

for (Object []obj:list) {

    System.out.println(Arrays.toString(obj));

}

SimpleJpaRepository s=null;

}




[](

)按照方法命名规则查询

-----------------------------------------------------------------------



我们在Dao层定义方法时,可以根据方法命名规则编写方法。这是我们只需要根据方法的名字,就能执行相应的查询语句。(前提是需要按照Spring Data JPA提供的方法命名规则定义方法的名称)



Spring Data JPA在程序执行的时候会根据方法名称进行解析,并自动生成查询语句进行查询  

按照Spring Data JPA 定义的规则,查询方法以**findBy**开头,涉及条件查询时,条件的属性用条件关键字 **(AND|OR)** 连接,要注意的是:条件属性首字母需大写。框架在进行方法名解析时,会先把方法名多余的前缀截取掉,然后对剩下部分进行解析。



**1\. 测试通过客户名称查询**  

`语法:findBy +属性名称(根据属性名称进行完成匹配的查询)`



//按照命名规则定义方法,不在需要添加注解

public Customer findByCustName(String name);

//测试方法

@Test

public void testNaming(){

Customer customer = customerDao.findByCustName("黑马程序员");

System.out.println(customer);

}




**2\. 测试模糊查询**  

`语法:findBy +属性名称 + 方式(like|isnull)`



//按照命名规则定义方法,实现模糊查询

public List findByCustNameLike(String name);

//测试方法

@Test

public void testFindByCustNameLike(){

List<Customer> byCustNameLike = customerDao.findByCustNameLike("%程序员");

for (Customer customer:byCustNameLike){

    System.out.println(customer);

}

}




**3\. 测试复合查询**  

`语法: findBy +属性名称 + 查询方式 + 多条件连接符(AND|OR)+属性名+ 查询方式`



//使用客户名称模糊匹配,和客户所属行业精准匹配

public List findByCustNameLikeAndCustIndustry(String custName,String custIndustry);

//测试方法

@Test

public void testFindByCustNameLikeAndCustIndustry(){

List<Customer> byCustNameLike = customerDao.findByCustNameLikeAndCustIndustry("%程序员","程序员");

for (Customer customer:byCustNameLike){

    System.out.println(customer);

}

}




**具体的关键字,使用方法和生产成SQL如下表所示:**



| Keyword | Sample | JPQL |

| --- | --- | --- |

| **And** | `findByLastnameAndFirstname` | … where x.lastname = ?1 and x.firstname = ?2 |

| **Or** | `findByLastnameOrFirstname` | … where x.lastname = ?1 or x.firstname = ?2 |

| **Is,Equals** | `findByFirstnameIs,findByFirstnameEquals` | … where x.firstname = ?1 |

| **Between** | `findByStartDateBetween` | … where x.startDate between ?1 and ?2 |

| **LessThan** | `findByAgeLessThan` | … where x.age < ?1 |

| **LessThanEqual** | `findByAgeLessThanEqual` | … where x.age ⇐ ?1 |

| **GreaterThan** | `findByAgeGreaterThan` | … where x.age > ?1 |

| **GreaterThanEqual** | `findByAgeGreaterThanEqual` | … where x.age >= ?1 |

| **After** | `findByStartDateAfter` | … where x.startDate > ?1 |

| **Before** | `findByStartDateBefore` | … where x.startDate < ?1 |

| **IsNull** | `findByAgeIsNull` | … where x.age is null |

| **IsNotNull,NotNull** | `findByAge(Is)NotNull` | … where x.age not null |

| **Like** | `findByFirstnameLike` | … where x.firstname like ?1 |

| **NotLike** | `findByFirstnameNotLike` | … where x.firstname not like ?1 |

| **StartingWith** | `findByFirstnameStartingWith` | … where x.firstname like ?1 (parameter bound with appended %) |

| **EndingWith** | `findByFirstnameEndingWith` | … where x.firstname like ?1 (parameter bound with prepended %) |

| **Containing** | `findByFirstnameContaining` | … where x.firstname like ?1 (parameter bound wrapped in %) |

| **OrderBy** | `findByAgeOrderByLastnameDesc` | … where x.age = ?1 order by x.lastname desc |

| **Not** | `findByLastnameNot` | … where x.lastname <> ?1 |

| **In** | `findByAgeIn(Collection ages)` | … where x.age in ?1 |

| **NotIn** | `findByAgeNotIn(Collection age)` | … where x.age not in ?1 |

| **TRUE** | `findByActiveTrue()` | … where x.active = true |

| **FALSE** | `findByActiveFalse()` | … where x.active = false |

| **IgnoreCase** | `findByFirstnameIgnoreCase` | … where UPPER(x.firstame) = UPPER(?1) |



[](

)Specifications动态查询

-------------------------------------------------------------------------------



有时我们在查询某个实体的时候,给定的条件是不固定的,这时就需要动态构建相应的查询语句,在Spring Data JPA中可以通过JpaSpecificationExecutor接口查询。相比JPQL,其优势是类型安全,更加的面向对象。



/**

  • JpaSpecificationExecutor中定义的方法

**/

public interface JpaSpecificationExecutor {

//根据条件查询一个对象

T findOne(Specification<T> spec);	

//根据条件查询集合

List<T> findAll(Specification<T> spec);

//根据条件分页查询

Page<T> findAll(Specification<T> spec, Pageable pageable);

//排序查询查询

List<T> findAll(Specification<T> spec, Sort sort);

//统计查询

long count(Specification<T> spec);

}




对于JpaSpecificationExecutor,这个接口基本是围绕着Specification接口来定义的。我们可以简单的理解为,Specification构造的就是查询条件。



/**Specification接口

Java高频面试专题合集解析:

Spring Data JPA 通过不同的方式实现查询操作,Java大厂面试真题

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](

)**Spring Data JPA 通过不同的方式实现查询操作,Java大厂面试真题

更多Java架构进阶资料展示

Spring Data JPA 通过不同的方式实现查询操作,Java大厂面试真题

Spring Data JPA 通过不同的方式实现查询操作,Java大厂面试真题

简单的理解为,Specification构造的就是查询条件。


/**Specification接口 



# **Java高频面试专题合集解析:**

[外链图片转存中...(img-JNKRNpCV-1631181273470)]

当然在这还有更多整理总结的Java进阶学习笔记和面试题未展示,其中囊括了**Dubbo、Redis、Netty、zookeeper、Spring cloud、分布式、高并发等架构资料和完整的Java架构学习进阶导图!**

**[CodeChina开源项目:【一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频】](

)**[外链图片转存中...(img-wzzhIKmc-1631181273472)]

**更多Java架构进阶资料展示**

[外链图片转存中...(img-tDonkYXr-1631181273475)]

[外链图片转存中...(img-n8BV9KtV-1631181273476)]

![阿里Java岗面试百题:Spring 缓存 JVM 微服务 数据库 RabbitMQ等](https://www.icode9.com/i/ll/?i=img_convert/19acd31c6a08f52c746af8e16641d2de.png)
上一篇:MyBatic与Spring的整合,Mapper接口方式的开发


下一篇:django和数据库交互,在微信小程序端删除数据库中的数据