SpringBoot--简单处理高并发demo - Go语言中文社区

SpringBoot--简单处理高并发demo


目录结构:(只跟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<Book, Integer>{

//And --- 等价于 SQL 中的 and 关键字
public List<Book> findByNameAndStock(String name,int stock);

// Or --- 等价于 SQL 中的 or 关键字
public List<Book> findByNameOrStock(String name,int stock);

//Between --- 等价于 SQL 中的 between 关键字
public List<Book> findByStockBetween(int min,int max);

//LessThan --- 等价于 SQL 中的 "<"
public List<Book> findByStockLessThan(int max);

//GreaterThan --- 等价于 SQL 中的">"  
public List<Book> findByStockGreaterThan(int min);  

//IsNull --- 等价于 SQL 中的 "is null"
public List<Book> findByNameIsNull();

//IsNotNull --- 等价于 SQL 中的 "is not null"
public List<Book> findByNameIsNotNull();  

//NotNull --- 与 IsNotNull 等价
public List<Book> findByNameNotNull(); 

//Like --- 等价于 SQL 中的 "like"
public List<Book> findByNameLike(String name); 

//NotLike --- 等价于 SQL 中的 "not like"
public List<Book> findByNameNotLike(String name); 

//OrderBy --- 等价于 SQL 中的 "order by"
public List<Book> findByNameNotNullOrderByStockAsc();  

//Not --- 等价于 SQL 中的 "! ="
public List<Book> findByNameNot(String name);

//In --- 等价于 SQL 中的 "in"
public List<Book> findByNameIn(String name);

//NotIn --- 等价于 SQL 中的 "not in"
public List<Book> findByNameNotIn(String name);


//***************************************
//利用原生的sql进行操作

// @Query 注解中编写 JPQL 语句
// 使用 @Modifying 进行修饰. 以通知   SpringData, 这是一个 UPDATE 或 DELETE 操作
@Query(value="select * from book where name = ?1 ",nativeQuery=true)
@Modifying
public List<Book> findBookByName(String name);


@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<Book> findByNameAndAuthor(String name ,String author,Pageable pageable);  
   
   //分页查询,返回的是一个片段,它只知道下一片段或者上一片段是否可用。  
   Slice<Book> findByName(String name,Pageable pageable); 
   
   //分页查询所有
   //分页查询 查询计算元素总个数总页数,数据多的情况下,代价是昂贵的  
   Page<Book> findAll(Pageable pageable); 
   
   @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<Book> 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<Book> findByNameAndStock(HttpServletRequest request) {
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<Book> findByNameOrStock(HttpServletRequest request){
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<Book> findByStockBetween(){
//满足条件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<Book> findBookByName(HttpServletRequest request){
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<Book> findByNameAndAuthor(HttpServletRequest request){
@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<Book> findAll(){
@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<Book> findByName(HttpServletRequest request){
@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

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>


<groupId>com.cxb</groupId>
<artifactId>SpringBoot-Thymeleaf</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>


<name>SpringBoot-Thymeleaf</name>
<description>Demo project for Spring Boot</description>


<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.2.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>


<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>


<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>


<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>

<!--thymeleaf -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.1</version>
</dependency>
<!-- mybatis的分页插件 -->
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper-spring-boot-starter -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper-spring-boot-starter</artifactId>
    <version>1.2.3</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.2</version>
</dependency>

<dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.15</version>
        </dependency>
        
        <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<!-- https://mvnrepository.com/artifact/junit/junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>



<!-- <dependency>
    <groupId>io.fabric8.devops.apps</groupId>
    <artifactId>elasticsearch</artifactId>
    <version>2.2.335</version>
</dependency>

 
<dependency>
    <groupId>org.springframework.data</groupId>
    <artifactId>spring-data-elasticsearch</artifactId>
</dependency>

<dependency>
    <groupId>net.java.dev.jna</groupId>
    <artifactId>jna</artifactId>
</dependency>



<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-elasticsearch</artifactId>
</dependency>

<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>securesm</artifactId>
    <version>1.0</version>
</dependency>

<dependency>
    <groupId>net.sf.jopt-simple</groupId>
    <artifactId>jopt-simple</artifactId>
    <version>3.2</version>
</dependency>


<dependency>
    <groupId>org.elasticsearch</groupId>
    <artifactId>jna</artifactId>
    <version>4.4.0</version>
</dependency>


<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpclient</artifactId>
    <version>4.5.3</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore</artifactId>
    <version>4.4.6</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpasyncclient</artifactId>
    <version>4.1.2</version>
</dependency>

<dependency>
    <groupId>org.apache.httpcomponents</groupId>
    <artifactId>httpcore-nio</artifactId>
    <version>4.4.4</version>
</dependency>

<dependency>
    <groupId>commons-codec</groupId>
    <artifactId>commons-codec</artifactId>
    <version>1.10</version>
</dependency>

<dependency>
    <groupId>com.github.spullara.mustache.java</groupId>
    <artifactId>compiler</artifactId>
    <version>0.8.13</version>
</dependency>

<dependency>
    <groupId>org.locationtech.spatial4j</groupId>
    <artifactId>spatial4j</artifactId>
    <version>0.7</version>
</dependency>


<dependency>
    <groupId>com.vividsolutions</groupId>
    <artifactId>jts</artifactId>
    <version>1.12</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queryparser</artifactId>
    <version>5.5.5</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-queries</artifactId>
    <version>5.2.1</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-sandbox</artifactId>
    <version>6.3.0</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-spatial</artifactId>
    <version>5.5.4</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-spatial-extras</artifactId>
    <version>6.3.0</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-spatial3d</artifactId>
    <version>7.1.0</version>
</dependency>

<dependency>
    <groupId>org.apache.lucene</groupId>
    <artifactId>lucene-suggest</artifactId>
    <version>6.2.1</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-smile</artifactId>
    <version>2.4.4</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-yaml</artifactId>
    <version>2.8.9</version>
</dependency>

<dependency>
    <groupId>com.fasterxml.jackson.dataformat</groupId>
    <artifactId>jackson-dataformat-cbor</artifactId>
    <version>2.8.1</version>
</dependency> -->


</dependencies>


<build>
  <plugins>
    <plugin>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-maven-plugin</artifactId>
    </plugin>
  </plugins>
</build>

</project>

 

这里的测试可以用并发测试工具访问下面的链接:

  链接:http://localhost:8080/book/reduce

 

    

 

 

 

版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/qq_33371766/article/details/80775785
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-07 15:18:39
  • 阅读 ( 743 )
  • 分类:

0 条评论

请先 登录 后评论

官方社群

GO教程

猜你喜欢