base 模块下 pom.xml 加入依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.xuan</groupId>
<artifactId>tensquare_common</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
创建启动类:
@SpringBootApplication
public class BaseApplication {
public static void main(String[] args) {
SpringApplication.run(BaseApplication.class, args);
}
@Bean
public IdWorker idWorker() {
return new IdWorker(1, 1);
}
}
在resources 目录下创建 application.yml
这里需要注意的是 spring-application-name : 横岗必须为中间横岗 因为在后期服务之间相互调用的时候只有中间横才能被服务识别。
我们的第一张表示标签表 表结构如下所示 :
我们在base 模块下面创建 pojo包
并创建 实体 Label
@Entity
@Table(name = "tb_label")
public class Label implements Serializable {
@Id
private String id;
/**
* 标签名称
*/
private String labelname;
/**
* 状态
*/
private String state;
/**
* 使用数量
*/
private Long count;
/**
* 关注数
*/
private Long fans;
/**
* 是否推荐
*/
private String recommend;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getLabelname() {
return labelname;
}
public void setLabelname(String labelname) {
this.labelname = labelname;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public Long getCount() {
return count;
}
public void setCount(Long count) {
this.count = count;
}
public Long getFans() {
return fans;
}
public void setFans(Long fans) {
this.fans = fans;
}
public String getRecommend() {
return recommend;
}
public void setRecommend(String recommend) {
this.recommend = recommend;
}
}
接下来创建数据访问接口 dao 层 创建dao包
包下创建 LabelDao接口
代码如下:
public interface LabelDao extends JpaRepository<Label, String>, JpaSpecificationExecutor<Label> {
}
接下来在模块下面创建 service包 包下创建LabelService 类
@Service("labelService")
@Transactional
public class LabelService {
@Autowired
private LabelDao labelDao;
@Autowired
private IdWorker idWorker;
/**
* <p>Description: 查询全部标签 </p>
*
* @author Yat-Xuan
* @params: []
* @return: java.util.List<com.tensquare.base.pojo.Label>
* @Date: 2018/11/13 0013 14:49
* @Modified By:
*/
public List<Label> findAll() {
return labelDao.findAll();
}
/**
* <p>Description: 根据ID查询标签 </p>
*
* @author Yat-Xuan
* @params: [id]
* @return: com.tensquare.base.pojo.Label
* @Date: 2018/11/13 0013 14:49
* @Modified By:
*/
public Label findById(String id) {
return labelDao.findById(id).get();
}
/**
* <p>Description:增加标签 </p>
*
* @author Yat-Xuan
* @params: [label]
* @return: void
* @Date: 2018/11/13 0013 14:50
* @Modified By:
*/
public void save(Label label) {
/**
* 设置ID
*/
label.setId(idWorker.nextId() + "");
labelDao.save(label);
}
/**
* 修改标签
*
* @param label
*/
public void update(Label label) {
labelDao.save(label);
}
/**
* 删除标签
*
* @param id
*/
public void deleteById(String id) {
labelDao.deleteById(id);
}
public List<Label> findSearch(Label label) {
return labelDao.findAll(getPredicate(label));
}
public Page<Label> pageQuery(Label label, int page, int size) {
PageUtil pageUtil = new PageUtil();
pageUtil.setCurrNo(page);
pageUtil.setSize(size);
Pageable pageable = PageRequest.of(pageUtil.getCurrNo() - 1, pageUtil.getSize());
return labelDao.findAll(getPredicate(label), pageable);
}
public Specification<Label> getPredicate(Label label) {
return new Specification<Label>() {
/**
*
* @param root 根对象,也就是要把条件封装到那个对象中去。类似:where 类名=label.getId
* @param criteriaQuery 封装的都是查询的关键字 比如:order by, group by等
* @param criteriaBuilder 用来封装条件对象,如果直接返回null 表示不需要任何查询条件
* @return
*/
@Override
public Predicate toPredicate(Root<Label> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//new 一个集合存放所有的条件
List<Predicate> list = new ArrayList<>();
if (label.getLabelname() != null && !"".equals(label.getLabelname())) {
//下面相当于 where like "%小明%"
Predicate predicate =
criteriaBuilder.like(root.get("labelname").as(String.class), "%" + label.getLabelname() + "%");
list.add(predicate);
}
if (label.getState() != null && !"".equals(label.getState())) {
Predicate predicate =
criteriaBuilder.equal(root.get("state").as(String.class), label.getState());
list.add(predicate);
}
if (label.getRecommend() != null && !"".equals(label.getRecommend())) {
Predicate predicate =
criteriaBuilder.equal(root.get("recommend").as(String.class), label.getRecommend());
list.add(predicate);
}
if (label.getCount() != null && !"".equals(label.getCount())) {
Predicate predicate =
criteriaBuilder.equal(root.get("count").as(String.class), label.getCount());
list.add(predicate);
}
if (label.getFans() != null && !"".equals(label.getFans())) {
Predicate predicate =
criteriaBuilder.equal(root.get("fans").as(String.class), label.getFans());
list.add(predicate);
}
//new 一个数组作为最终返回值的条件
Predicate[] predicates = new Predicate[list.size()];
//把list转成数组
predicates = list.toArray(predicates);
return criteriaBuilder.and(predicates);
}
};
}
}
这个service 里面有需要注意的点 是 有用到分页 以及条件查询 需要注意一下
分页工具如下:pageutil
public class PageUtil {
/**
* 当前页码
*/
private int currNo = 1;
/**
* 每页显示条数
*/
private int size = 15;
/**
* 总页码
*/
private int totalCurrNo;
/**
* 总数据
*/
private int totalSize;
public PageUtil() {
}
public PageUtil(int currNo, int size) {
this.currNo = currNo == 0 ? 1 : currNo > this.totalCurrNo ? this.totalCurrNo : currNo;
this.size = size == 0 ? 15 : size;
}
public int getCurrNo() {
return currNo;
}
public void setCurrNo(int currNo) {
this.currNo = currNo == 0 ? 1 : currNo > this.totalCurrNo ? this.totalCurrNo : currNo;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size == 0 ? 15 : size;
}
public int getTotalCurrNo() {
return totalCurrNo;
}
public void setTotalCurrNo(int totalCurrNo) {
this.totalCurrNo = totalCurrNo;
}
public int getTotalSize() {
return totalSize;
}
public void setTotalSize(int totalSize) {
this.totalSize = totalSize;
if (this.totalSize > 0) {
this.totalCurrNo = this.totalSize % this.size == 0 ? this.totalSize / this.size : this.totalSize / this.size + 1;
} else {
this.totalCurrNo = 1;
}
}
}
最后需要完成的是 controller 部分:
@RestController
@CrossOrigin
@RequestMapping("/label")
@RefreshScope
public class LabelController {
@Resource
private LabelService labelService;
@GetMapping
public Result findAll() {
return new Result(true, StatusCode.OK, "查询成功", labelService.findAll());
}
@GetMapping("/{labelId}")
public Result findById(@PathVariable("labelId") String labelId) {
return new Result(true, StatusCode.OK, "查询成功", labelService.findById(labelId));
}
@PostMapping
public Result save(@RequestBody Label label) {
labelService.save(label);
return new Result(true, StatusCode.OK, "新增成功");
}
@PutMapping("/{labelId}")
public Result update(@PathVariable String labelId, @RequestBody Label label) {
label.setId(labelId);
labelService.update(label);
return new Result(true, StatusCode.OK, "更新成功");
}
@DeleteMapping("/{labelId}")
public Result delete(@PathVariable String labelId) {
labelService.deleteById(labelId);
return new Result(true, StatusCode.OK, "删除成功");
}
@PostMapping("/search")
public Result findSearch(@RequestBody Label label) {
List<Label> list = labelService.findSearch(label);
return new Result(true, StatusCode.OK, "查询成功", list);
}
@PostMapping("/search/{page}/{size}")
public Result pageQuery(@RequestBody Label label, @PathVariable int page, @PathVariable int size) {
Page<Label> pageData = labelService.pageQuery(label, page, size);
return new Result(true, StatusCode.OK, "查询成功",
new PageResult<Label>(pageData.getTotalElements(), pageData.getContent()));
}
}
此 controller 需要注意的是:@RefreshScope
这个注解
最后为了使我们的代码更容易做维护 我们做一个类集中处理异常
controller 包下创建 BaseExceptionHandler
@RestControllerAdvice
public class BaseExceptionHandler {
@ExceptionHandler(value = Exception.class)
public Result exception(Exception e) {
e.printStackTrace();
return new Result(false, StatusCode.ERROR, e.getMessage());
}
}
这里还需要注意一个点:跨域: