1. Mybaits-plus 项目整合
1.1 修改案例讲解
@Test
public void updateUserById ( ) {
User user = new User ( 354 , "六耳猕猴" , null , null ) ;
int rows = userMapper. updateById ( user) ;
System . out. println ( "响应了" + rows + "行" ) ;
}
@Test
public void updateUserByName ( ) {
User user = new User ( null , "齐天大圣" , null , null ) ;
UpdateWrapper < User > updateWrapper = new UpdateWrapper < > ( ) ;
updateWrapper. eq ( "name" , "猴子" ) ;
userMapper. update ( user, updateWrapper) ;
System . out. println ( "修改操作成功!!!" ) ;
}
1.2 MP后台项目改造
1.2.1 导入jar包
< dependency>
< groupId> com.baomidou</ groupId>
< artifactId> mybatis-plus-boot-starter</ artifactId>
< version> 3.4.3</ version>
</ dependency>
1.2.2 编辑POJO ItemCat
@Data
@Accessors ( chain = true )
@TableName ( "item_cat" )
public class ItemCat extends BasePojo {
@TableId ( type = IdType . AUTO)
private Integer id;
private Integer parentId;
private String name;
private Boolean status;
private Integer level;
@TableField ( exist = false )
private List < ItemCat > children;
}
1.2.3 编辑ItemCatMapper接口
public interface ItemCatMapper extends BaseMapper < ItemCat > {
}
1.2.4 修改YML文件
server :
port : 8091
spring :
datasource :
driver-class-name : com.mysql.cj.jdbc.Driver
url : jdbc: mysql: //127.0.0.1: 3306/jt? serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username : root
password : root
mybatis-plus :
type-aliases-package : com.jt.pojo
mapper-locations : classpath: /mybatis/mappers/*.xml
configuration :
map-underscore-to-camel-case : true
logging :
level :
com.jt.mapper : debug
1.2.5 层级代码结构
1.3 商品分类页面跳转
说明: 编辑路由 index.js
import Vue from 'vue'
import VueRouter from 'vue-router'
import Login from '../components/Login.vue'
import ElementUI from '../components/ElementUI.vue'
import Home from '../components/Home.vue'
import User from '../components/user/user.vue'
import ItemCat from '../components/items/ItemCat.vue'
Vue. use ( VueRouter)
const routes = [
{
path: '/' , redirect: '/login' } ,
{
path: '/login' , component: Login} ,
{
path: '/elementUI' , component: ElementUI} ,
{
path: '/home' , component: Home, children: [
{
path: '/user' , component: User} ,
{
path: '/itemCat' , component: ItemCat}
] }
]
页面效果展现
2 完成商品分类业务
2.1 页面JS分析
生命周期函数
created ( ) {
this . findItemCatList ( )
} ,
获取数据函数说明
async findItemCatList ( ) {
const {
data: result
} = await this . $http. get ( "/itemCat/findItemCatList/3" )
if ( result. status !== 200 ) return this . $message. error ( "获取商品分类列表失败!!" )
this . itemCatList = result. data
} ,
2.2 业务接口文档
请求路径: /itemCat/findItemCatList/{level}
请求类型: get
请求参数: level
参数名称
参数说明
备注
level
查询级别
1查询一级分类 2查询1-2 级商品分类 3查询1-2-3级商品分类
业务说明: 查询3级分类菜单数据 要求三层结构嵌套
返回值: SysResult对象
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
3级商品分类信息
2.3 商品分类表结构说明
表结构
sql案例练习
SELECT * FROM item_cat WHERE parent_id = 0
SELECT * FROM item_cat WHERE parent_id = 249
SELECT * FROM item_cat WHERE parent_id = 281
小结: 商品分类表,通过parent_id 来指定父子级关系.
2.4 编辑ItemCatController
@RestController
@CrossOrigin
@RequestMapping ( "/itemCat" )
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
@GetMapping ( "findItemCatList/{level}" )
public SysResult findItemCatList ( @PathVariable Integer level) {
List < ItemCat > itemCatList = itemCatService. findItemCatList ( level) ;
return SysResult . success ( itemCatList) ;
}
}
2.5 编辑ItemCatService
package com. jt. service ;
import com. baomidou. mybatisplus. core. conditions. query. QueryWrapper ;
import com. jt. mapper. ItemCatMapper ;
import com. jt. pojo. ItemCat ;
import org. springframework. beans. factory. annotation. Autowired ;
import org. springframework. stereotype. Service ;
import java. util. List ;
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private ItemCatMapper itemCatMapper;
@Override
public List < ItemCat > findItemCatList ( Integer level) {
QueryWrapper queryWrapper = new QueryWrapper ( ) ;
queryWrapper. eq ( "parent_id" , 0 ) ;
List < ItemCat > oneList = itemCatMapper. selectList ( queryWrapper) ;
for ( ItemCat oneItemCat : oneList) {
int oneId = oneItemCat. getId ( ) ;
queryWrapper. clear ( ) ;
queryWrapper. eq ( "parent_id" , oneId) ;
List < ItemCat > twoList = itemCatMapper. selectList ( queryWrapper) ;
for ( ItemCat twoItemCat : twoList) {
int twoId = twoItemCat. getId ( ) ;
queryWrapper. clear ( ) ;
queryWrapper. eq ( "parent_id" , twoId) ;
List < ItemCat > threeList = itemCatMapper. selectList ( queryWrapper) ;
twoItemCat. setChildren ( threeList) ;
}
oneItemCat. setChildren ( twoList) ;
}
return oneList;
}
}
2.6 上述案例分析
上述的案例 采用多级循环的方式. 将来会耗费服务器资源 100次 内层100次 总循环1万次. 暂时可以接受
上述的代码 频繁访问数据库.导致数据库压力增大.严重时可能导致数据库服务器宕机. 不能接受的 优化策略: 降低数据库访问的次数
2.7 采用数据结构优化代码
思路:
用户查询所有的数据库信息. (1-2-3所有数据)
数据结构 Map<k,v> key唯一的, value可以任意类型. 思路: Map<parentId,List> 例子:
Map<0,List<一级ItemCat对象>>
Map<249,List<二级ItemCat对象>>
Map<281,List<三级ItemCat对象>> 利用map 封装父子关系.
2.8 代码具体实现
@Service
public class ItemCatServiceImpl implements ItemCatService {
@Autowired
private ItemCatMapper itemCatMapper;
public Map < Integer , List < ItemCat > > getMap ( ) {
Map < Integer , List < ItemCat > > map = new HashMap < > ( ) ;
List < ItemCat > itemCatList = itemCatMapper. selectList ( null ) ;
for ( ItemCat itemCat : itemCatList) {
Integer key = itemCat. getParentId ( ) ;
if ( map. containsKey ( key) ) {
map. get ( key) . add ( itemCat) ;
} else {
List < ItemCat > list = new ArrayList < > ( ) ;
list. add ( itemCat) ;
map. put ( key, list) ;
}
}
return map;
}
@Override
public List < ItemCat > findItemCatList ( Integer level) {
long startTime = System . currentTimeMillis ( ) ;
Map < Integer , List < ItemCat > > map = getMap ( ) ;
if ( level == 1 ) {
return map. get ( 0 ) ;
}
if ( level == 2 ) {
return getTwoList ( map) ;
}
List < ItemCat > oneList = getThreeList ( map) ;
long endTime = System . currentTimeMillis ( ) ;
System . out. println ( "优化前的耗时: 500ms,优化后耗时:" + ( endTime - startTime) + "ms" ) ;
return oneList;
}
private List < ItemCat > getThreeList ( Map < Integer , List < ItemCat > > map) {
List < ItemCat > oneList = getTwoList ( map) ;
for ( ItemCat oneItemCat : oneList) {
List < ItemCat > twoList = oneItemCat. getChildren ( ) ;
if ( twoList == null || twoList. size ( ) == 0 ) {
continue ;
}
for ( ItemCat twoItemCat : twoList) {
int twoId = twoItemCat. getId ( ) ;
List < ItemCat > threeList = map. get ( twoId) ;
twoItemCat. setChildren ( threeList) ;
}
}
return oneList;
}
private List < ItemCat > getTwoList ( Map < Integer , List < ItemCat > > map) {
List < ItemCat > oneList = map. get ( 0 ) ;
for ( ItemCat oneItemCat : oneList) {
int oneId = oneItemCat. getId ( ) ;
List < ItemCat > twoList = map. get ( oneId) ;
oneItemCat. setChildren ( twoList) ;
}
return oneList;
}
}
3 商品分类新增实现
3.1 页面JS分析
页面JS分析
itemCatForm: {
name: '' ,
parentId: 0 ,
level: 1
} ,
async addItemCatForm ( ) {
this . $refs. itemCatFormRef. validate ( async validate => {
if ( ! validate) return
const {
data: result
} = await this . $http. post ( "/itemCat/saveItemCat" , this . itemCatForm)
if ( result. status !== 200 ) return this . $message. error ( "新增商品分类失败" )
this . $message. success ( "新增商品分类成功!!!" )
this . findItemCatList ( ) ;
this . addItemCatDialogVisible = false
} )
} ,
3.2 商品分类新增接口文档
请求路径: /itemCat/saveItemCat
请求类型: post
请求参数: 表单数据
参数名称
参数说明
备注
name
商品分类名称
不能为null
parentId
用户父级ID
不能为null
level
分类级别
1 2 3 商品分类级别
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
3.3 编辑ItemCatController
@PostMapping ( "/saveItemCat" )
public SysResult saveItem ( @RequestBody ItemCat itemCat) {
itemCatService. saveItem ( itemCat) ;
return SysResult . success ( ) ;
}
3.4 编辑ItemCatService
@Override
@Transactional
public void saveItem ( ItemCat itemCat) {
Date date = new Date ( ) ;
itemCat. setStatus ( true ) . setCreated ( date) . setUpdated ( date) ;
itemCatMapper. insert ( itemCat) ;
}
4. 商品分类删除操作
4.1 删除业务接口
请求路径: /itemCat/deleteItemCat
请求类型: delete
业务描述: 当删除节点为父级时,应该删除自身和所有的子节点
请求参数:
参数名称
参数说明
备注
id
用户id号
不能为null
level
商品分类级别
一级,二级,三级
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功 201表示服务器异常
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
4.2 前端页面JS
1. 页面JS
< el- button type= "danger" icon= "el-icon-delete" @click= "deleteItemCatBtn(scope.row)" > 删除< / el- button>
2. 发起Ajax请求
const {
data: result} = await this . $http. delete ( "/itemCat/deleteItemCat" , {
params: {
id: itemCat. id, level: itemCat. level} } )
if ( result. status !== 200 ) return this . $message. error ( "删除商品分类失败" )
this . $message. success ( "删除数据成功" )
this . findItemCatList ( )
4.3 编辑ItemCatController
@DeleteMapping ( "/deleteItemCat" )
public SysResult deleteItemCat ( Integer id, Integer level) {
itemCatService. deleteItemCat ( id, level) ;
return SysResult . success ( ) ;
}
4.4 编辑ItemCatService
@Override
public void deleteItemCat ( Integer id, Integer level) {
if ( level == 3 ) {
itemCatMapper. deleteById ( id) ;
}
if ( level == 2 ) {
QueryWrapper < ItemCat > queryWrapper = new QueryWrapper < > ( ) ;
queryWrapper. eq ( "parent_id" , id)
. or ( )
. eq ( "id" , id) ;
itemCatMapper. delete ( queryWrapper) ;
}
if ( level == 1 ) {
QueryWrapper < ItemCat > queryWrapper = new QueryWrapper ( ) ;
queryWrapper. eq ( "parent_id" , id) ;
List twoIds = itemCatMapper. selectObjs ( queryWrapper) ;
queryWrapper. clear ( ) ;
queryWrapper. in ( twoIds. size ( ) > 0 , "parent_id" , twoIds)
. or ( )
. in ( twoIds. size ( ) > 0 , "id" , twoIds)
. or ( )
. eq ( "id" , id) ;
itemCatMapper. delete ( queryWrapper) ;
}
}
5. 修改
5.1 状态修改操作
5.1.1 页面JS分析
1. 页面JS 函数
updateStatus ( scope. row)
2. 页面JS
async updateStatus ( itemCat ) {
const {
data: result
} = await this . $http. put ( ` /itemCat/status/ ${
itemCat. id} / ${
itemCat. status} ` )
if ( result. status !== 200 ) return this . $message. error ( "修改状态失败" )
this . $message. success ( "状态修改成功" )
} ,
5.1.2 业务接口文档
请求路径: /itemCat/status/{id}/{status}
请求类型: put
请求参数:
参数名称
参数说明
备注
id
用户ID值
不能为null
status
用户的状态信息
不能为null
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
5.1.3 编辑ItemCatController
@PutMapping ( "/status/{id}/{status}" )
public SysResult updateStatus ( ItemCat itemCat) {
itemCatService. updateStatus ( itemCat) ;
return SysResult . success ( ) ;
}
5.1.4 编辑ItemCatService
@Override
@Transactional
public void updateStatus ( ItemCat itemCat) {
itemCat. setUpdated ( new Date ( ) ) ;
itemCatMapper. updateById ( itemCat) ;
}
5.2 商品分类修改操作
5.2.1 页面JS分析
1. 指定修改的按钮
< el- button type= "success" icon= "el-icon-edit" @click= "updateItemCatBtn(scope.row)" > 编辑< / el- button>
2. 数据的回显
updateItemCatBtn ( itemCat ) {
this . updateItemCatForm = itemCat
this . updateItemCatDialogVisible = true
} ,
3. 修改页面的JS
< el- dialog title= "修改商品分类" : visible. sync= "updateItemCatDialogVisible" width= "50%" >
< ! -- 定义分类表单 -- >
< el- form : model= "updateItemCatForm" : rules= "rules" ref= "upDateItemCatForm" label- width= "100px" >
< el- form- item label= "分类名称:" prop= "name" >
< el- input v- model= "updateItemCatForm.name" > < / el- input>
< / el- form- item>
< / el- form>
< span slot= "footer" class = "dialog-footer" >
< el- button @click= "updateItemCatDialogVisible = false" > 取 消< / el- button>
< el- button type= "primary" @click= "updateItemCat" > 确 定< / el- button>
< / span>
< / el- dialog>
4. 修改按钮的JS
async updateItemCat ( ) {
const {
data: result} =
await this . $http. put ( '/itemCat/updateItemCat' , this . updateItemCatForm)
if ( result. status !== 200 ) return this . $message. error ( "更新商品分类失败" )
this . $message. success ( "更新商品分类成功" )
this . findItemCatList ( ) ;
this . updateItemCatDialogVisible = false ;
} ,
5.2.2 页面接口文档
请求路径: /itemCat/updateItemCat
请求类型: put
请求参数: 表单数据 ItemCat对象
返回值: SysResult对象
参数名称
参数说明
备注
status
状态信息
200表示服务器请求成功
msg
服务器返回的提示信息
可以为null
data
服务器返回的业务数据
可以为null
数据解析:
5.2.3 编辑ItemCatController
@PutMapping ( "/updateItemCat" )
public SysResult updateItemCat ( @RequestBody ItemCat itemCat) {
itemCatService. updateItemCat ( itemCat) ;
return SysResult . success ( ) ;
}
5.2.4 编辑ItemCatService
@Override
@Transactional
public void updateItemCat ( ItemCat itemCat) {
ItemCat temp = new ItemCat ( ) ;
temp. setId ( itemCat. getId ( ) )
. setName ( itemCat. getName ( ) )
. setUpdated ( new Date ( ) ) ;
itemCatMapper. updateById ( temp) ;
}
5.3 debug断点调试