商品微服务搭建
商品微服务搭建
商品微服务主要是实现对商品的增删改查相关操作,以及商品相关信息的增删改查。
公共组件工程搭建
创建changgou-service-api子模块changgou-service-goods-api,并将资料\javabean\changgou-service-goods-api
中的Pojo导入到工程中。
修改父工程changgou-service-api的pom.xml,添加persistence-api
和changgou-common
的依赖,代码如下:
<dependencies> <!--通用的common--> <dependency> <groupId>com.changgou</groupId> <artifactId>changgou-common</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <!--每个工程都有Pojo,都需要用到该包对应的注解--> <dependency> <groupId>javax.persistence</groupId> <artifactId>persistence-api</artifactId> <version>1.0</version> <scope>compile</scope> </dependency> </dependencies>
商品微服务工程搭建
修改changgou-service的pom.xml每个微服务可能都需要访问数据库所以引入changgou-common-db
的依赖,代码如下:
<!--依赖-->
<dependencies>
<dependency>
<groupId>com.changgou</groupId>
<artifactId>changgou-common-db</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
在changgou-service中创建changgou-service-goods ,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"> <parent> <artifactId>changgou-service</artifactId> <groupId>com.changgou</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>changgou-service-goods</artifactId> <!--依赖--> <dependencies> <dependency> <groupId>com.changgou</groupId> <artifactId>changgou-service-goods-api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> </project>
在resources下创建配置文件application.yml
server: port: 18081 spring: application: name: goods datasource: driver-class-name: com.mysql.jdbc.Driver url: jdbc:mysql://192.168.211.132:3306/changgou_goods?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC username: root password: 123456 eureka: client: service-url: defaultZone: http://127.0.0.1:7001/eureka instance: prefer-ip-address: true feign: hystrix: enabled: true #mybatis的配置 可以不配置 需要整合通用mapper #mybatis: # configuration: # map-underscore-to-camel-case: true # mapper-locations: classpath:mapper/*Mapper.xml # type-aliases-package: com.changgou.goods.pojo
在包com.changgou包下创建启动类GoodsApplication,代码如下:
package com.changgou; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.netflix.eureka.EnableEurekaClient; @SpringBootApplication @EnableEurekaClient public class GoodsApplication { public static void main(String[] args) { SpringApplication.run(GoodsApplication.class, args); } }
启动changgou-service-goods
再访问<http://localhost:7001/>
效果如下:·
表结构分析
品牌表:tb_brand
代码实现
上面品牌表对应Brand实体类
@Table(name="tb_brand") public class Brand implements Serializable{ @Id private Integer id;//品牌id private String name;//品牌名称 private String image;//品牌图片地址 private String letter;//品牌的首字母 private Integer seq;//排序 // getter and setter .....(省略) }
@Table和@Id都是JPA注解,@Table用于配置表与实体类的映射关系,@Id用于标识主键属性。
品牌列表
①Dao创建
在changgou-service-goods微服务下创建com.changgou.goods.dao.BrandMapper接口,代码如下:
public interface BrandMapper extends Mapper<Brand> { }
继承了Mapper接口,就自动实现了增删改查的常用方法。
②业务层
创建com.changgou.goods.service.BrandService接口,代码如下:
public interface BrandService { /*** * 查询所有品牌 * @return */ List<Brand> findAll(); }
创建com.changgou.goods.service.impl.BrandServiceImpl实现类,代码如下:
@Service public class BrandServiceImpl implements BrandService { }
③控制层
控制层 com.changgou.goods包下创建controller包 ,包下创建类
@RestController @RequestMapping("/brand") @CrossOrigin public class BrandController { }
④在启动类加入tk.mybatis.spring.annotation.MapperScan的注解扫描
//注意 要使用通用的mapper的组件扫描 @MapperScan(basePackages = {"com.changgou.goods.dao"}) // mapper接口继承了通用的mapper //默认提供一些方法: // insert // update // delete // select
⑤增删改查相关操作接口的实现
dao层
package com.changgou.goods.dao; import com.changgou.goods.pojo.Brand; import org.apache.ibatis.annotations.Select; import tk.mybatis.mapper.common.Mapper; import java.util.List; public interface BrandMapper extends Mapper<Brand> { @Select(value="select tb.* from tb_brand tb ,tb_category_brand tbc where tb.id = tbc.brand_id and tbc.category_id=#{categoryid}") List<Brand> findByCategory(Integer categoryid); }
service层
package com.changgou.goods.service; import com.changgou.goods.pojo.Brand; import com.github.pagehelper.PageInfo; import java.util.List; public interface BrandService { /*** * Brand多条件分页查询 * @param brand * @param page * @param size * @return */ PageInfo<Brand> findPage(Brand brand, int page, int size); /*** * Brand分页查询 * @param page * @param size * @return */ PageInfo<Brand> findPage(int page, int size); /*** * Brand多条件搜索方法 * @param brand * @return */ List<Brand> findList(Brand brand); /*** * 删除Brand * @param id */ void delete(Integer id); /*** * 修改Brand数据 * @param brand */ void update(Brand brand); /*** * 新增Brand * @param brand */ void add(Brand brand); /** * 根据ID查询Brand * @param id * @return */ Brand findById(Integer id); /*** * 查询所有Brand * @return */ List<Brand> findAll(); List<Brand> findByCategory(Integer id); }
serviceImpl层
package com.changgou.goods.service.impl; import com.changgou.goods.dao.BrandMapper; import com.changgou.goods.pojo.Brand; import com.changgou.goods.service.BrandService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; import tk.mybatis.mapper.entity.Example; import java.util.List; @Service public class BrandServiceImpl implements BrandService { @Autowired private BrandMapper brandMapper; /** * Brand条件+分页查询 * @param brand 查询条件 * @param page 页码 * @param size 页大小 * @return 分页结果 */ @Override public PageInfo<Brand> findPage(Brand brand, int page, int size){ //分页 PageHelper.startPage(page,size); //搜索条件构建 Example example = createExample(brand); //执行搜索 return new PageInfo<Brand>(brandMapper.selectByExample(example)); } /** * Brand分页查询 * @param page * @param size * @return */ @Override public PageInfo<Brand> findPage(int page, int size){ //静态分页 PageHelper.startPage(page,size); //分页查询 return new PageInfo<Brand>(brandMapper.selectAll()); } /** * Brand条件查询 * @param brand * @return */ @Override public List<Brand> findList(Brand brand){ //构建查询条件 Example example = createExample(brand); //根据构建的条件查询数据 return brandMapper.selectByExample(example); } /** * Brand构建查询对象 * @param brand * @return */ public Example createExample(Brand brand){ Example example=new Example(Brand.class); Example.Criteria criteria = example.createCriteria(); if(brand!=null){ // 品牌id if(!StringUtils.isEmpty(brand.getId())){ criteria.andEqualTo("id",brand.getId()); } // 品牌名称 if(!StringUtils.isEmpty(brand.getName())){ criteria.andLike("name","%"+brand.getName()+"%"); } // 品牌图片地址 if(!StringUtils.isEmpty(brand.getImage())){ criteria.andEqualTo("image",brand.getImage()); } // 品牌的首字母 if(!StringUtils.isEmpty(brand.getLetter())){ criteria.andEqualTo("letter",brand.getLetter()); } // 排序 if(!StringUtils.isEmpty(brand.getSeq())){ criteria.andEqualTo("seq",brand.getSeq()); } } return example; } /** * 删除 * @param id */ @Override public void delete(Integer id){ brandMapper.deleteByPrimaryKey(id); } /** * 修改Brand * @param brand */ @Override public void update(Brand brand){ brandMapper.updateByPrimaryKey(brand); } /** * 增加Brand * @param brand */ @Override public void add(Brand brand){ brandMapper.insert(brand); } /** * 根据ID查询Brand * @param id * @return */ @Override public Brand findById(Integer id){ return brandMapper.selectByPrimaryKey(id); } /** * 查询Brand全部数据 * @return */ @Override public List<Brand> findAll() { return brandMapper.selectAll(); } @Override public List<Brand> findByCategory(Integer id) { //两种方案: //1. 自己写sql语句直接执行 推荐 //2. 调用通用的mapper的方法 一个个表查询 return brandMapper.findByCategory(id); } }
controller层
package com.changgou.goods.controller; import com.changgou.goods.pojo.Brand; import com.changgou.goods.service.BrandService; import com.github.pagehelper.PageInfo; import entity.Result; import entity.StatusCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; import java.util.List; @RestController @RequestMapping("/brand") @CrossOrigin public class BrandController { @Autowired private BrandService brandService; /*** * Brand分页条件搜索实现 * @param brand * @param page * @param size * @return */ @PostMapping(value = "/search/{page}/{size}" ) public Result<PageInfo> findPage(@RequestBody(required = false) Brand brand, @PathVariable int page, @PathVariable int size){ //调用BrandService实现分页条件查询Brand PageInfo<Brand> pageInfo = brandService.findPage(brand, page, size); return new Result(true,StatusCode.OK,"查询成功",pageInfo); } /*** * Brand分页搜索实现 * @param page:当前页 * @param size:每页显示多少条 * @return */ @GetMapping(value = "/search/{page}/{size}" ) public Result<PageInfo> findPage(@PathVariable int page, @PathVariable int size){ //调用BrandService实现分页查询Brand PageInfo<Brand> pageInfo = brandService.findPage(page, size); return new Result<PageInfo>(true,StatusCode.OK,"查询成功",pageInfo); } /*** * 多条件搜索品牌数据 * @param brand * @return */ @PostMapping(value = "/search" ) public Result<List<Brand>> findList(@RequestBody(required = false) Brand brand){ //调用BrandService实现条件查询Brand List<Brand> list = brandService.findList(brand); return new Result<List<Brand>>(true,StatusCode.OK,"查询成功",list); } /*** * 根据ID删除品牌数据 * @param id * @return */ @DeleteMapping(value = "/{id}" ) public Result delete(@PathVariable Integer id){ //调用BrandService实现根据主键删除 brandService.delete(id); return new Result(true,StatusCode.OK,"删除成功"); } /*** * 修改Brand数据 * @param brand * @param id * @return */ @PutMapping(value="/{id}") public Result update(@RequestBody Brand brand,@PathVariable Integer id){ //设置主键值 brand.setId(id); //调用BrandService实现修改Brand brandService.update(brand); return new Result(true,StatusCode.OK,"修改成功"); } /*** * 新增Brand数据 * @param brand * @return */ @PostMapping public Result add(@RequestBody Brand brand){ //调用BrandService实现添加Brand brandService.add(brand); return new Result(true,StatusCode.OK,"添加成功"); } /*** * 根据ID查询Brand数据 * @param id * @return */ @GetMapping("/{id}") public Result<Brand> findById(@PathVariable Integer id){ //调用BrandService实现根据主键查询Brand Brand brand = brandService.findById(id); return new Result<Brand>(true,StatusCode.OK,"查询成功",brand); } /*** * 查询Brand全部数据 * @return */ @GetMapping public Result<List<Brand>> findAll(){ try { System.out.println("aaaaa====="); Thread.sleep(3000); System.out.println("bbbb====="); } catch (InterruptedException e) { e.printStackTrace(); } //调用BrandService实现查询所有Brand List<Brand> list = brandService.findAll(); return new Result<List<Brand>>(true, StatusCode.OK,"查询成功",list) ; } /** * * @return */ @GetMapping("/category/{id}") public Result<List<Brand>> findBrandByCategory(@PathVariable(name="id") Integer id){ List<Brand> brandList = brandService.findByCategory(id); return new Result<List<Brand>>(true,StatusCode.OK,"查询品牌列表成功",brandList); } }
⑥使用postman对接口进行测试
公共异常处理
为了使我们的代码更容易维护,我们创建一个类集中处理异常,该异常类可以创建在changgou-common工程中,创建com.changgou.framework.exception.BaseExceptionHandler,代码如下:
@ControllerAdvice public class BaseExceptionHandler { /*** * 异常处理 * @param e * @return */ @ExceptionHandler(value = Exception.class) @ResponseBody public Result error(Exception e) { e.printStackTrace(); return new Result(false, StatusCode.ERROR, e.getMessage()); } }
注意:@ControllerAdvice注解,全局捕获异常类,只要作用在@RequestMapping上,所有的异常都会被捕获。
可以将异常处理类BaseExceptionHandler放入公共工具类中需要注意包位置需要被微服务工程扫描到,这样全部的微服务就都会使用该异常捕获类了。