目录结构:(只跟book相关的)
model:
package com.cxb.model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
//自动生成表
@Entity
@Table(name="book")
public class Book {
@Id
@GeneratedValue
private Integer id;
@Column(length=100)
private String name;
@Column(length=50)
private String author;
@Column(length=50)
private Integer stock; //库存
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
}
BookDao:
package com.cxb.dao;
import java.util.List;
import javax.transaction.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import com.cxb.model.Book;
/**
* springbootJPA
* 这种就不需要写service类,直接在controller里面调用该dao的方法
* @author 81046
*
*/
public interface BookDao extends JpaRepository
//And --- 等价于 SQL 中的 and 关键字
public List
// Or --- 等价于 SQL 中的 or 关键字
public List
//Between --- 等价于 SQL 中的 between 关键字
public List
//LessThan --- 等价于 SQL 中的 "<"
public List
//GreaterThan --- 等价于 SQL 中的">"
public List
//IsNull --- 等价于 SQL 中的 "is null"
public List
//IsNotNull --- 等价于 SQL 中的 "is not null"
public List
//NotNull --- 与 IsNotNull 等价
public List
//Like --- 等价于 SQL 中的 "like"
public List
//NotLike --- 等价于 SQL 中的 "not like"
public List
//OrderBy --- 等价于 SQL 中的 "order by"
public List
//Not --- 等价于 SQL 中的 "! ="
public List
//In --- 等价于 SQL 中的 "in"
public List
//NotIn --- 等价于 SQL 中的 "not in"
public List
//***************************************
//利用原生的sql进行操作
// @Query 注解中编写 JPQL 语句
// 使用 @Modifying 进行修饰. 以通知 SpringData, 这是一个 UPDATE 或 DELETE 操作
@Query(value="select * from book where name = ?1 ",nativeQuery=true)
@Modifying
public List
@Query(value="delete from book where id = ?1 ",nativeQuery=true)
@Modifying
@Transactional
public void deleteBookById(int id);
//利用原生的SQL进行修改操作
@Query(value = "update book set name=?1 where id=?2 ", nativeQuery = true)
@Modifying
@Transactional
public void updateBookName(String name,int id);
//利用原生的SQL进行插入操作
@Query(value = "insert into book(name,author) value(?1,?2)", nativeQuery = true)
@Modifying
@Transactional
public void insertBook(String name,String author);
//分页查询 查询计算元素总个数总页数,数据多的情况下,代价是昂贵的
Page
//分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。
Slice
//分页查询所有
//分页查询 查询计算元素总个数总页数,数据多的情况下,代价是昂贵的
Page
@Query(value = "update book set stock=stock-?1 where id=?2", nativeQuery = true)
@Modifying
@Transactional
public void reduce(int num,int id);
}
BookController:
package com.cxb.controller;
import java.util.List;
import java.util.concurrent.Semaphore;
import javax.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Slice;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import com.cxb.dao.BookDao;
import com.cxb.model.Book;
@Controller
@RequestMapping("/book")
public class BookController {
@Autowired
private BookDao bookDao;
//处理并发事件
//定义资源的总数量
Semaphore semaphore=new Semaphore(1);
/** 查询所有的图书
* http://localhost:8080/book/list
* @return
*/
@RequestMapping(value="/list", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public List
return bookDao.findAll();
}
/**
* 新增图书
* @param request
* @return
*/
@RequestMapping(value="/saveBook", method=RequestMethod.POST,produces = "application/json; charset=utf-8")
@ResponseBody
public Book saveBook(HttpServletRequest request) {
String author = request.getParameter("author");
String name = request.getParameter("name");
String stock = request.getParameter("stock");
Book book = new Book();
book.setAuthor(author);
book.setName(name);
book.setStock(Integer.parseInt(stock));
return bookDao.save(book);
}
/**
* 修改图书
* @param request
* @return
*/
@RequestMapping(value="/updateBook", method=RequestMethod.POST,produces = "application/json; charset=utf-8")
@ResponseBody
public Book updateBook(HttpServletRequest request) {
String author = request.getParameter("author");
String name = request.getParameter("name");
String stock = request.getParameter("stock");
Book book = new Book();
book.setAuthor(author);
//设置id之后,就会执行update
book.setId(3);
book.setName(name);
book.setStock(Integer.parseInt(stock));
return bookDao.save(book);
}
/**
* 根据id删除图书
* @param request
*/
@RequestMapping(value="/delete", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public void delete(HttpServletRequest request) {
String id = request.getParameter("id");
bookDao.deleteById(Integer.parseInt(id));
}
/** 根据库存和名称查询图书
* http://localhost:8080/book/findByNameAndStock?name=庐州月&stock=20
* @param request
* @return
*/
@RequestMapping(value="/findByNameAndStock", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public List
String name = request.getParameter("name");
String stock = request.getParameter("stock");
return bookDao.findByNameAndStock(name,Integer.parseInt(stock));
}
/** 根据名称或者库存查询图书
* http://localhost:8080/book/findByNameOrStock?name=庐州月&stock=22
* @param request
* @return
*/
@RequestMapping(value="/findByNameOrStock", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public List
String name = request.getParameter("name");
String stock = request.getParameter("stock");
//满足条件1和条件2的集合
return bookDao.findByNameOrStock(name,Integer.parseInt(stock));
}
/**
* 根据库存量在某个区间查询图书
* @return
*/
@RequestMapping(value="/findByStockBetween", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public List
//满足条件1和条件2的集合
return bookDao.findByStockBetween(10,20);
}
/** 根据名称查询图书
* http://localhost:8080/book/findBookByName?name=千百度
* @param request
* @return
*/
@RequestMapping(value="/findBookByName", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public List
String name = request.getParameter("name");
return bookDao.findBookByName(name);
}
/** 根据id修改图书的名称
* http://localhost:8080/book/updateBookName?name=叹服&id=1
* @param request
*/
@RequestMapping(value="/updateBookName", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public void updateBookName(HttpServletRequest request) {
String name = request.getParameter("name");
String id = request.getParameter("id");
bookDao.updateBookName(name, Integer.parseInt(id));
}
/** 插入图书
* http://localhost:8080/book/insertBook?name=千百度1&author=许嵩
* @param request
*/
@RequestMapping(value="/insertBook", method=RequestMethod.POST,produces = "application/json; charset=utf-8")
@ResponseBody
public void insertBook(HttpServletRequest request) {
String name = request.getParameter("name");
String author = request.getParameter("author");
bookDao.insertBook(name, author);
}
/** 根据id删除图书
* http://localhost:8080/book/deleteBookById?id=6
* @param request
*/
@RequestMapping(value="/deleteBookById", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public void deleteBookById(HttpServletRequest request){
String id = request.getParameter("id");
bookDao.deleteById(Integer.parseInt(id));
}
/**
* 分页查询图书 根据名称和作者
* @param request
* @return
*/
@RequestMapping(value="/findByNameAndAuthor", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public Page
@SuppressWarnings("deprecation")
//根据id降序
Pageable pageable = new PageRequest(0,3, Sort.Direction.DESC,"id");
String name = request.getParameter("name");
String author = request.getParameter("author");
return bookDao.findByNameAndAuthor(name, author, pageable);
}
/**
* 分页查询所有的图书
* @return
*/
@RequestMapping(value="/findAll", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public Page
@SuppressWarnings("deprecation")
//根据id降序
Pageable pageable = new PageRequest(0,3, Sort.Direction.DESC,"id");
return bookDao.findAll(pageable);
}
/**
*
* @param request
* @return
*/
@RequestMapping(value="/findByName", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
Slice
@SuppressWarnings("deprecation")
//根据id降序
Pageable pageable = new PageRequest(0,3, Sort.Direction.DESC,"id");
String name = request.getParameter("name");
return bookDao.findByName(name, pageable);
}
/**
* 减库存 处理多线程(成功几个也会失败几个)
*/
@RequestMapping(value="/reduce", method=RequestMethod.GET,produces = "application/json; charset=utf-8")
@ResponseBody
public String reduce(HttpServletRequest request){
//可用资源数
int availablePermits = semaphore.availablePermits();
System.out.println("可用资源数量---"+availablePermits);
if(availablePermits>0) {
System.out.println("抢到资源****根据id修改该图书的库存");
try {
//请求占用一个资源
semaphore.acquire(1);
//根据id修改该图书的库存
String id = request.getParameter("id");
bookDao.reduce(5, Integer.parseInt(id));
System.out.println("根据id修改该图书的库存完成");
}catch (Exception e) {
e.printStackTrace();
}finally {
//释放一个资源
semaphore.release(1);
}
return "抢到资源处理业务逻辑,最后释放资源完成";
}else {
System.out.println("*********资源已被占用,稍后再试***********");
return "*********资源已被占用,稍后再试***********";
}
}
}
SpringBootThymeleafApplication:
package com.cxb;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.HttpMessageConverter;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.config.FastJsonConfig;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
@SpringBootApplication
//没有连接数据库的时候报错 需要加上这一句
//@EnableAutoConfiguration(exclude={DataSourceAutoConfiguration.class})
public class SpringBootThymeleafApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootThymeleafApplication.class, args);
}
/**
* 这里是为了使用阿里的fastjson 方式一
* @return
*/
@Bean
public HttpMessageConverters fastJsonConverters() {
FastJsonHttpMessageConverter fastConverter=new FastJsonHttpMessageConverter();
FastJsonConfig fastConfig=new FastJsonConfig();
fastConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
fastConverter.setFastJsonConfig(fastConfig);
HttpMessageConverter> converter=fastConverter;
return new HttpMessageConverters(converter);
}
}
application.yml:
spring:
thymeleaf:
#缓冲的配置
cache: false
check-template: true
check-template-location: true
#开启MVC thymeleaf 视图解析
enabled: true
encoding: utf-8
mode: HTML5
prefix: classpath:/templates/
suffix: .html
#配置数据源
datasource:
url: jdbc:mysql://127.0.0.1:3306/sp?useUnicode=true&characterEncoding=utf8
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver
jpa:
hibernate:
ddl-auto: update
show-sql: true
#指定mybatis映射文件的地址
mybatis:
#配置文件的路径
#config-location: classpath:mybatis-config.xml
mapper-locations: classpath:mapper/*.xml
# mybatis自动扫描包中的实体类,自动定义别名,别名是类名(首字母大写或小写都可以,一般用小写)
type-aliases-package: com.cxb.model
#pagehelper分页插件配置
pagehelper:
helper-dialect: mysql
reasonable: true
support-methods-arguments: true
params: countSql
pom.xml
这里的测试可以用并发测试工具访问下面的链接:
链接:http://localhost:8080/book/reduce