第三节:自定义查询@Query
有时候复杂sql使用hql方式无法查询,这时候使用本地查询,使用原生sql的方式;
 
第四节:动态查询Specification 使用
什么时候用呢?比如搜索有很多条件,有时候用户只填了一个,有时候填很多,不确定条件的数目,这时候动态判断,拼接sql,使用Specification
 
下面是例子讲解:
com.cy.dao.BookDao.java:
package com.cy.dao;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Query; import com.cy.entity.Book; public interface BookDao extends JpaRepository<Book, Integer>, JpaSpecificationExecutor<Book>{ // ?1代表第一个参数
// 这种是hql形式
@Query("select b from Book b where b.name like %?1%")
public List<Book> findByName(String name); /**
* 随机查询n条图书
* nativeQuery默认是hql查询,这里true表示使用本地查询,就是原生的sql方式
* @param n
* @return
*/
@Query(value="select * from t_book order by RAND() limit ?1", nativeQuery=true)
public List<Book> randomList(Integer n); }

注意:

上面BookDao继承了JpaSpecificationExecutor,这个接口里面才可以动态条件查询;继承这个是为了动态查询Specification 使用

BookController:

package com.cy.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root; import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView; import com.cy.dao.BookDao;
import com.cy.entity.Book; @Controller
@RequestMapping("/book")
public class BookController { @Resource
private BookDao bookDao;
/**
* 根据条件动态查询
*/
@RequestMapping("/list2")
public ModelAndView list2(Book book){
ModelAndView mav = new ModelAndView();
List<Book> bookList = bookDao.findAll(new Specification<Book>(){
@Override
public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Predicate predicate = cb.conjunction();
if(book!=null){
if(book.getName()!=null && !"".equals(book.getName())){
predicate.getExpressions().add(cb.like(root.get("name"), "%"+book.getName()+"%"));
}
if(book.getAuthor()!=null && !"".equals(book.getAuthor())){
predicate.getExpressions().add(cb.like(root.get("author"), "%"+book.getAuthor()+"%"));
}
}
return predicate;
}
});
mav.addObject("book", book);
mav.addObject("bookList", bookList);
mav.setViewName("bookList");
return mav;
} /**
* 根据名字查找图书
* @return
*/
@ResponseBody
@GetMapping("/queryByName")
public List<Book> queryByName(){
return bookDao.findByName("编程");
} //随机查询一条图书
@ResponseBody
@GetMapping("/randomList")
public List<Book> randomList(){
return bookDao.randomList(1);
}
}

src/main/resouces/templates/bookList.ftl里面增加两个搜索框:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>图书管理</title>
</head>
<body>
<a href="/bookAdd.html">添加</a>
<!-- 这个book返回来是为了搜素框回显使用的 -->
<form method="post" action="/book/list2">
图书名称:<input type="text" name="name" value="${book.name}"/>&nbsp;
图书作者:<input type="text" name="author" value="${book.author}" />&nbsp;
<input type="submit" value="搜索"/>
</form>
<table>
<tr>
<th>编号</th>
<th>图书名称</th>
<th>图书作者</th>
<th>操作</th>
</tr>
<#list bookList as book>
<tr>
<td>${book.id}</td>
<td>${book.name}</td>
<td>${book.author}</td>
<td>
<a href="/book/preUpdate/${book.id}">修改</a>
<a href="/book/delete?id=${book.id}">删除</a>
</td>
</tr>
</#list>
</table>
</body>
</html>

测试:

数据表情况:

mysql> select * from t_book;
+----+--------+--------------+
| id | author | name |
+----+--------+--------------+
| 2 | 作者1 | 图书五 |
| 7 | 外国佬 | java编程思想 |
| 8 | 王五 | 大刀王五 |
| 9 | 有人 | php编程 |
+----+--------+--------------+

1.http://localhost/book/queryByName显示:  [{"id":7,"name":"java编程思想","author":"外国佬"},{"id":9,"name":"php编程","author":"有人"}]

2.http://localhost/book/randomList,  随机查询一条图书;

3.http://localhost/book/list2,搜索图书名称:五:

 

spring boot学习(5) SpringBoot 之Spring Data Jpa 支持(2)的更多相关文章

  1. spring boot学习(4) SpringBoot 之Spring Data Jpa 支持(1)

    第一节:Spring Data Jpa 简介 Spring-Data-Jpa JPA(Java Persistence API)定义了一系列对象持久化的标准,目前实现这一规范的产品有Hibernate ...

  2. Spring Boot学习(一)——Spring Boot介绍

    Spring Boot介绍 Spring Boot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式 ...

  3. spring boot 学习(五)SpringBoot+MyBatis(XML)+Druid

    SpringBoot+MyBatis(xml)+Druid 前言 springboot集成了springJDBC与JPA,但是没有集成mybatis,所以想要使用mybatis就要自己去集成. 主要是 ...

  4. spring boot学习(十三)SpringBoot缓存(EhCache 2.x 篇)

    SpringBoot 缓存(EhCache 2.x 篇) SpringBoot 缓存 在 Spring Boot中,通过@EnableCaching注解自动化配置合适的缓存管理器(CacheManag ...

  5. spring boot 学习(十)SpringBoot配置发送Email

    SpringBoot配置发送Email 引入依赖 在 pom.xml 文件中引入邮件配置: <dependency> <groupId>org.springframework. ...

  6. spring boot学习(6) SpringBoot 之事务管理

    两个操作要么同时成功,要么同时失败: 事务的一致性: 以前学ssh ssm都有事务管理service层通过applicationContext.xml配置,所有service方法都加上事务操作: 用来 ...

  7. spring boot学习(2) SpringBoot 项目属性配置

    第一节:项目内置属性 application.properties配置整个项目的,相当于以前的web.xml: 注意到上一节的访问HelloWorld时,项目路径也没有加:直接是http://loca ...

  8. spring boot学习(7) SpringBoot 之表单验证

    第一节:SpringBoot 之表单验证@Valid 是spring-data-jpa的功能:   下面是添加学生的信息例子,要求姓名不能为空,年龄大于18岁.   贴下代码吧: Student实体: ...

  9. spring boot 学习入门篇【spring boot项目的搭建以及如何加载jsp界面】

    [ 前言]  Spring Boot 简介:Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过程.该框架使用了特定的方式来进行配置, ...

随机推荐

  1. bzoj1648

    题解: 简单灌水 然后统计一下 代码: #include<bits/stdc++.h> using namespace std; ; int ne[N],num,fi[N],n,k,m,x ...

  2. 重置delphi Printer对象

    http://www.efg2.com/Lab/Library/UseNet/1999/0714b.txt From: "Nick Ryan" <nick@avatardes ...

  3. PHP parse_url 一个好用的函数

    array parse_url ( string $url ) 本函数解析一个 URL 并返回一个关联数组,包含在 URL 中出现的各种组成部分. 对严重不合格的 URL,parse_url() 可能 ...

  4. (C/C++学习笔记) 十四. 动态分配

    十四. 动态分配 ● C语言实现动态数组 C语言实现动态数组,克服静态数组大小固定的缺陷 C语言中,数组长度必须在创建数组时指定,并且只能是一个常数,不能是变量.一旦定义了一个数组,系统将为它分配一个 ...

  5. bga

    本文记录在bga布线的难题. 1一开始就要预留好布线局域. 最近出现布线太密,修改时就麻烦了. http://bbs.elecfans.com/jishu_521995_1_1.html

  6. JVM自动内存管理:对象判定和回收算法

    可回收对象的判断方法 1.引用计数算法 2.可达性分析算法 引用计数算法 给对象中添加一个引用计数器,每当有一个地方引用它时,计数器值就加1:当引用失效时,计数器值就减1:任何时刻计数器为0的对象就是 ...

  7. 《C++ Primer》笔记-inline内联函数

    inline 函数避免函数调用的开销 // find longer of two strings const string &shorterString(const string &s ...

  8. Python mode_r

    f = open("例子.txt",mode="r",encoding="utf-8") print(f.read(5)) # 读取5个字符 ...

  9. Python id

    # id()函数可以帮我们查看一个变量的内存地址 a = 10 b = 30 print(id(a)) print(id(b)) lst = ["周杰伦","麻花藤&qu ...

  10. Spring Cloud Sleuth进阶实战

    转载请标明出处: http://blog.csdn.net/forezp/article/details/76795269 本文出自方志朋的博客 为什么需要Spring Cloud Sleuth 微服 ...