1.使用jpa
dao类必须继承JpaRepository<Label,String>, JpaSpecificationExecutor
public interface LabelDao extends JpaRepository<Label,String>, JpaSpecificationExecutor<Label>{
// JpaRepository提供了基本的增删改查
// JpaSpecificationExecutor用于做复杂的条件查询
}
2.统一异常处理类
package com.tensquare.base.controller;
import entity.Result;
import entity.StatusCode;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;
//统一异常处理类
@RestControllerAdvice
public class BaseExceptionHandler {
@ExceptionHandler(value = Exception.class) //申明捕获那个异常类
public Result exception(Exception e){
e.printStackTrace(); //将错误在控制台打印
return new Result(false, StatusCode.ERROR,e.getMessage());
}
}
3.(tenquare_base)
public List<Label> findsearch(Label label) {
return labelDao.findAll(new Specification<Label>() {
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cd) {
List<Predicate> list=new ArrayList<>();
if(label.getLabelname()!=null && !" ".equals(label.getLabelname())){
// //where labelname like "%小米%"
Predicate pared = cd.like(root.get("labelname").as(String.class), "%" +label.getLabelname() + "%");
list.add(pared);
}
if(label.getState()!=null && !" ".equals(label.getState())){
//where state ="1"
Predicate pared = cd.equal(root.get("state").as(String.class),label.getState());
list.add(pared);
}
Predicate[] predicate=new Predicate[list.size()];
// 把predicate转成数组
predicate=list.toArray(predicate);
return cd.and(predicate);
}
});
}
一。实现new Specification
4.分页查询
@RequestMapping(value = "/search/{page}/{size}",method = RequestMethod.POST)
public Result PageQuery(@RequestBody Label label,@PathVariable("page") int page,@PathVariable("size") int size){
Page<Label> pagedata= labelService.PageQuery(label,page,size);
return new Result(true,StatusCode.OK,"PageQuery查询成 功",new PageResult<Label>(pagedata.getTotalElements(),pagedata.getContent()));
}
public Page<Label> PageQuery(Label label, int page, int size) {
//分页
Pageable pageable= PageRequest.of(page-1,size);
return labelDao.findAll(new Specification<Label>() {
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cd) {
List<Predicate> list=new ArrayList<>();
if(label.getLabelname()!=null && !" ".equals(label.getLabelname())){
// //where labelname like "%小米%"
Predicate pared = cd.like(root.get("labelname").as(String.class), "%" +label.getLabelname() + "%");
list.add(pared);
}
if(label.getState()!=null && !" ".equals(label.getState())){
//where state ="1"
Predicate pared = cd.equal(root.get("state").as(String.class),label.getState());
list.add(pared);
}
Predicate[] predicate=new Predicate[list.size()];
// 把predicate转成数组
predicate=list.toArray(predicate);
return cd.and(predicate);
}
},pageable);
}
6.直接在dao层写jpa提供的方法
public interface EnterpriseDao extends JpaRepository<Enterprise,String>,JpaSpecificationExecutor<Enterprise>{
public List<Enterprise> findByIshot(String ishot); //where ishot=?
public List<Enterprise> findTopByNameAndIshot(String name,String ishot);
public List<Enterprise> queryById(String id);
public List<Enterprise> getById(String id);
7.写sql语句
nativeQuery = true:https://blog.csdn.net/myme95/article/details/84143341
package com.tensquare.qa.dao;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import com.tensquare.qa.pojo.Problem;
import org.springframework.data.jpa.repository.Query;
/**
* 数据访问接口
* @author Administrator
*
*/
public interface ProblemDao extends JpaRepository<Problem,String>,JpaSpecificationExecutor<Problem>{
@Query(value = "select * from tb_problem,tb_pl where id=problemid and labelid=? order by replytime desc",nativeQuery = true)
public Page<Problem> newlist(String labelid, Pageable pageable);
@Query(value = "select * from tb_problem,tb_pl where id=problemid and labelid=? order by reply desc",nativeQuery = true)
public Page<Problem> hotlist(String labelid, Pageable pageable);
@Query(value = "select * from tb_problem,tb_pl where id=problemid and reply=0 and labelid=? order by createtime desc",nativeQuery = true)
public Page<Problem> waitlist(String labelid, Pageable pageable);
}
8.报错
org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
解决方法:
@Service
@Transactional //加上这个注解
public class ArticleService {
}
8.redis缓存机制:
(suer模块)步骤
1.下载安装redis,启动服务器
参考文档https://blog.csdn.net/kevin860/article/details/97849533
2。pom.xml导入依赖
.<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency>
3.application.yml
spring
redis:
host: 127.0.0.1
4.导入模块,直接使用
@Autowired
private RedisTemplate redisTemplate;
9.spring cache缓存机制:
参考文档https://www.cnblogs.com/gdut-lss/p/11419256.html
步骤:
9.1:为GatheringApplication添加@EnableCaching开启缓存支持
9.2:
`/**
* 根据ID查询实体
* @param id
* @return
*/
@Cacheable(value="gathering",key="#id")
public Gathering findById(String id) {
return gatheringDao.findById(id).get();
}`
/**
* 修改
* @param gathering
* value的值必须和@Cacheable的value="gathering" 一样
*/
@CacheEvict(value="gathering",key="#gathering.id")
public void update(Gathering gathering) {
gatheringDao.save(gathering);
}
/**
* 删除
* @param id
*/
@CacheEvict(value="gathering",key="#id")
public void deleteById(String id) {
gatheringDao.deleteById(id);
}
使用场景:要设置过时时间则用redis,不用则用spring cache
10.mongodb使用(第三章):
10.1下载安装mongodb
10.2
## 1.启动mongodb的服务器
(1)首先打开命令提示符,创建一个用于存放数据的目录
md d:\data
(2)启动服务
mongod ‐‐dbpath=d:\data
## 2.通过mongodb客户端连接服务器 (新打开一个cmd窗口)
我们在启动信息中可以看到,mongoDB的默认端口是27017
如果我们想改变默认的启动端口,可以通过--port来指定端口
在命令提示符输入以下命令即可完成登陆
mongo
退出mongodb
exit
官网:https://www.mongodb.org.cn/tutorial/13.html
如果想使用mongodb原生命令
1.service注入
@Autowired
private MongoTemplate mongoTemplate;
例子:点赞功能
/**
* 点赞
* @param id
*/
public void updateThumbup(String id){
Spit spit = spitDao.findById(id).get();
spit.setThumbup(spit.getThumbup()+1);
spitDao.save(spit);
//使用mongodb原生命令
Query query=new Query();
query.addCriteria(Criteria.where("_id").is(id));
Update update=new Update();
update.inc("thumbup",1);
mongoTemplate.updateFirst(query,update,"spit");
}
11.ElasticSearch(第四章)
官网:https://www.elastic.co/cn/
1.下载网址:https://www.elastic.co/cn/downloads/past-releases/elasticsearch-5-6-8
2.使用ElasticSearch:
无需安装,解压安装包后即可使用
在命令提示符下,进入ElasticSearch安装目录下的bin目录,执行 elasticsearch 命令即可启动
elasticsearch
测试:我们打开浏览器,在地址栏输入http://127.0.0.1:9200/ 即可看到输出结果
{
"name" : "uV2glMR",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "RdV7UTQZT1‐Jnka9dDPsFg",
"version" : {
"number" : "5.6.8",
"build_hash" : "688ecce",
"build_date" : "2018‐02‐16T16:46:30.010Z",
"build_snapshot" : false,
"lucene_version" : "6.6.1"
},
"tagline" : "You Know, for Search"
}
2.1新建索引
例如我们要创建一个叫articleindex的索引 ,就以put方式提交
http://127.0.0.1:9200/articleindex/
2.2新建文档
以post方式提交 http://127.0.0.1:9200/articleindex/article
body:
{
"title":"SpringBoot2.0",
"content":"发布啦"
}
参考文档:Elasticsearch 基本语法汇总
11.1.Elasticsearch 的图形画化操作Head插件安装(都是第四章)
11.2 IK分词器
11.3 Logstash
Logstash是一款轻量级的日志搜集处理框架,可以方便的把分散的、多样化的日志搜集
起来,并进行自定义的处理,然后传输到指定的位置,比如某个服务器或者文件
12 消息中间件RabbitMQ(第五章)
参加启动服务器文档https://blog.csdn.net/qq_27409289/article/details/78201176
1.阿里云短信微服务
参考文档https://blog.csdn.net/Goligory/article/details/78135757
注意点:
//code是模板内容的占位符
smsUtil.sendSms(map.get("mobile"),template_code,sign_name,"{\"code\":\""+ map.get("mobilenumber") +"\"}");
} catch (ClientException e) {
13.密码加密与微服务鉴权JWT(第六章)
13.1 BCrypt密码加密
13.2 基于JWT的Token认证机制实现(tenquare_common)
13.3 拦截器方式实现token鉴权
步骤
1.写个拦截器类
参考文档:https://blog.csdn.net/heweimingming/article/details/79993591
package com.tensquare.user.Interceptor;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
@Component
public class JwtInterceptor implements HandlerInterceptor {
public boolean preHandle(javax.servlet.http.HttpServletRequest request, javax.servlet.http.HttpServletResponse response, java.lang.Object handler) throws java.lang.Exception {
System.out.println("拦截成功");
return true;
}
}
2.写个配置类
package com.tensquare.user.config;
import com.tensquare.user.Interceptor.JwtInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
@Configuration
public class JwtInterceptorConfig extends WebMvcConfigurationSupport {
@Autowired
private com.tensquare.user.Interceptor.JwtInterceptor JwtInterceptor;
protected void addInterceptors(org.springframework.web.servlet.config.annotation.InterceptorRegistry registry) {
//拦截的对象和被拦截的路径
registry.addInterceptor(JwtInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/**/login/**");
}
}
14.springboot 事务回滚;
https://blog.csdn.net/csdn565973850/article/details/100940940
前端知识点
1. SwaggerEditor安装与启动(第二章)
参考文档:https://blog.csdn.net/adminBfl/article/details/84248041
1.1 SwaggerUI
https://www.cnblogs.com/zhang6332/p/10682302.html
1.2 nginx
https://blog.csdn.net/VictoryKingLIU/article/details/91784881
1.3 Mock.js (官网http://mockjs.com/)是一款模拟数据生成器,旨在帮助前端攻城师独立于后端进行开发,帮助编写单元测试。提供了以下模拟功能:
根据数据模板生成模拟数据
模拟 Ajax 请求,生成并返回模拟数据
基于 HTML 模板生成模拟数据
Mock.js具有以下特点:
前后端分离
让前端攻城师独立于后端进行开发。
增加单元测试的真实性
通过随机数据,模拟各种场景。
开发无侵入
不需要修改既有代码,就可以拦截 Ajax 请求,返回模拟的响应数据。
1.4 (重点)Easy Mock 是杭州大搜车无线团队出品的一个极其简单、高效、 可视化、并且能快
速生成模拟数据的在线 mock 服务。以项目管理的方式组织 Mock List,能帮助我们更好
的管理 Mock 数据。
地址:https://www.easy-mock.com
在线文档:https://www.easy-mock.com/docs