品牌查询后台代码
品牌的查詢
商品分類完成以后,自然輪到了品牌功能了。
先看看我們要實現的效果:
點擊“品牌管理”菜單:
路由路徑:/item/brand
根據路由文件知,對應的頁面是:src/pages/item/Brand.vue
后臺提供查詢接口
前臺頁面已經準備好,接下來就是后臺提供數據接口了。
數據庫表
?
CREATE TABLE `tb_brand` (`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '品牌id',`name` varchar(50) NOT NULL COMMENT '品牌名稱',`image` varchar(200) DEFAULT '' COMMENT '品牌圖片地址',`letter` char(1) DEFAULT '' COMMENT '品牌的首字母',PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=325400 DEFAULT CHARSET=utf8 COMMENT='品牌表,一個品牌下有多個商品(spu),一對多關系';簡單的四個字段,不多解釋。
這里需要注意的是,品牌和商品分類之間是多對多關系。因此我們有一張中間表,來維護兩者間關系:
CREATE TABLE `tb_category_brand` (`category_id` bigint(20) NOT NULL COMMENT '商品類目id',`brand_id` bigint(20) NOT NULL COMMENT '品牌id',PRIMARY KEY (`category_id`,`brand_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品分類和品牌的中間表,兩者是多對多關系';但是,你可能會發現,這張表中并沒有設置外鍵約束,似乎與數據庫的設計范式不符。為什么這么做?
-
外鍵會嚴重影響數據庫讀寫的效率
-
數據刪除時會比較麻煩
在電商行業,性能是非常重要的。我們寧可在代碼中通過邏輯來維護表關系,也不設置外鍵。
mapper
通用mapper來簡化開發:
public interface BrandMapper extends Mapper<Brand> { }controller
編寫controller先思考四個問題,參照前端頁面的控制臺
-
請求方式:查詢,肯定是Get
-
請求路徑:分頁查詢,/brand/page
-
請求參數:根據我們剛才編寫的頁面,有分頁功能,有排序功能,有搜索過濾功能,因此至少要有5個參數:
-
page:當前頁,int
-
rows:每頁大小,int
-
sortBy:排序字段,String
-
desc:是否為降序,boolean
-
key:搜索關鍵詞,String
-
-
響應結果:分頁結果一般至少需要兩個數據
-
total:總條數
-
items:當前頁數據
-
totalPage:有些還需要總頁數
-
這里我們封裝一個類,來表示分頁結果:
public class PageResult<T> {private Long total;// 總條數private Integer totalPage;// 總頁數private List<T> items;// 當前頁數據public PageResult() {}public PageResult(Long total, List<T> items) {this.total = total;this.items = items;}public PageResult(Long total, Long totalPage, List<T> items) {this.total = total;this.totalPage = totalPage;this.items = items;}public Long getTotal() {return total;}public void setTotal(Long total) {this.total = total;}public List<T> getItems() {return items;}public void setItems(List<T> items) {this.items = items;}public Long getTotalPage() {return totalPage;}public void setTotalPage(Long totalPage) {this.totalPage = totalPage;} }另外,這個PageResult以后可能在其它項目中也有需求,因此我們將其抽取到learn-common中,提高復用性:
不要忘記在learn-item-service工程的pom.xml中引入learn-common的依賴:
<dependency><groupId>com.leyou.common</groupId><artifactId>leyou-common</artifactId><version>1.0.0-SNAPSHOT</version> </dependency>接下來,我們編寫Controller
@RestController @RequestMapping("brand") public class BrandController {@Autowiredprivate BrandService brandService;/*** 根據查詢條件分頁并排序查詢品牌信息* @param key* @param page* @param rows* @param sortBy* @param desc* @return*/@GetMapping("page")public ResponseEntity<PageResult<Brand>> queryBrandsByPage(@RequestParam(value = "key", required = false)String key,@RequestParam(value = "page", defaultValue = "1")Integer page,@RequestParam(value = "rows", defaultValue = "5")Integer rows,@RequestParam(value = "sortBy", required = false)String sortBy,@RequestParam(value = "desc", required = false)Boolean desc){PageResult<Brand> result = this.brandService.queryBrandsByPage(key, page, rows, sortBy, desc);if (CollectionUtils.isEmpty(result.getItems())){return ResponseEntity.notFound().build();}return ResponseEntity.ok(result);} }Service
@Service public class BrandService {@Autowiredprivate BrandMapper brandMapper;/*** 根據查詢條件分頁并排序查詢品牌信息** @param key* @param page* @param rows* @param sortBy* @param desc* @return*/public PageResult<Brand> queryBrandsByPage(String key, Integer page, Integer rows, String sortBy, Boolean desc) {// 初始化example對象Example example = new Example(Brand.class);Example.Criteria criteria = example.createCriteria();// 根據name模糊查詢,或者根據首字母查詢if (StringUtils.isNotBlank(key)) {criteria.andLike("name", "%" + key + "%").orEqualTo("letter", key);}// 添加分頁條件PageHelper.startPage(page, rows);// 添加排序條件if (StringUtils.isNotBlank(sortBy)) {example.setOrderByClause(sortBy + " " + (desc ? "desc" : "asc"));}List<Brand> brands = this.brandMapper.selectByExample(example);// 包裝成pageInfoPageInfo<Brand> pageInfo = new PageInfo<>(brands);// 包裝成分頁結果集返回return new PageResult<>(pageInfo.getTotal(), pageInfo.getList());} }測試
通過瀏覽器訪問試試:http://api.learn.com/api/item/brand/page
接下來,去頁面請求數據并渲染
總結