1. Mybaits plus project integration
1.1 explanation of modified cases
/**
* MP update operation
* Note: change the name of id=354 to "six eared macaque"
*/
@Test
public void updateUserById(){
User user = new User(354,"Six eared macaque",null,null);
int rows = userMapper.updateById(user);
System.out.println("Responded"+ rows +"that 's ok");
}
/**
* MP update operation
* Note: change the data named "monkey" to "Qi Tian Da Sheng"
* Usage:
* 1. Parameter 1: encapsulate the modified data
* 2. Parameter 2: encapsulate the modified condition
* Sql: update demo_user set name="Qi Tian Da Sheng "where name =" monkey“
*/
@Test
public void updateUserByName(){
//1. Encapsulate and modify data with pojo objects
User user = new User(null,"Qi Tian Da Sheng",null,null);
//1. Use UpdateWrapper to encapsulate the where condition
UpdateWrapper<User> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name","monkey");
userMapper.update(user,updateWrapper);
System.out.println("Modification operation succeeded!!!");
}
1.2 MP background project transformation
1.2.1 import jar package
<!--Import MP of jar Package file-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
1.2.2 edit POJO ItemCat
@Data
@Accessors(chain = true)
@TableName("item_cat") //Associated data table
public class ItemCat extends BasePojo{
@TableId(type = IdType.AUTO)//Primary key auto increment
private Integer id; //Primary key
private Integer parentId; //Define parent menu to enable hump rule mapping
private String name; //Classification name
private Boolean status; //Classification status 0 disabled 1 normal
private Integer level; //Commodity classification level 1 2 3
@TableField(exist = false) //Property is not a table field
private List<ItemCat> children;
}
1.2.3 edit ItemCatMapper interface
public interface ItemCatMapper extends BaseMapper<ItemCat> {
}
1.2.4 modify YML file
#Configure port number
server:
port: 8091
#Manage data sources
spring:
datasource:
#Use of high version driver
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
#Set user name and password
username: root
password: root
#Spring boot integrates mybatis plus
mybatis-plus:
#Specify alias package
type-aliases-package: com.jt.pojo
#Scan the mapping file under the specified path
mapper-locations: classpath:/mybatis/mappers/*.xml
#Turn on hump mapping
configuration:
map-underscore-to-camel-case: true
# The L2 cache starts by default, so it can be simplified
#Print mysql log
logging:
level:
com.jt.mapper: debug
1.2.5 hierarchical code structure
1.3 product classification page Jump
Description: edit route 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'
//Using routing mechanism
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}
]}
]
Page effect display
2. Complete commodity classification business
2.1 page JS analysis
- Life cycle function
//Define initialization function
created() {
//Get commodity classification list data by default
this.findItemCatList()
},
- Get data function description
async findItemCatList() {
const {
data: result
} = await this.$http.get("/itemCat/findItemCatList/3")
if (result.status !== 200) return this.$message.error("Failed to get commodity classification list!!")
this.itemCatList = result.data
},
2.2 business interface documents
- Request path: / itemCat/findItemCatList/{level}
- Request type: get
- Request parameter: level
Parameter name | Parameter description | remarks |
---|
level | Query level | 1 query level 1 Classification 2 query level 1-2 commodity classification 3 query level 1-2-3 commodity classification |
- Business description: querying Level 3 Classification menu data requires a three-tier nested structure
- Return value: SysResult object
Parameter name | Parameter description | remarks |
---|
status | status information | 200 indicates that the server request was successful |
msg | Prompt information returned by the server | Can be null |
data | Business data returned by the server | Level 3 commodity classification information |
2.3 structure description of commodity classification table
- Table structure
- sql case exercise
/*All first level menus parent_id=0*/
SELECT * FROM item_cat WHERE parent_id = 0
/*Query the secondary menu of automobile users*/
SELECT * FROM item_cat WHERE parent_id = 249
/*Query the three-level menu of on-board electrical appliances*/
SELECT * FROM item_cat WHERE parent_id = 281
Summary: commodity classification table, specifying parent-child relationship through parent_id
2.4 editing ItemCatController
@RestController
@CrossOrigin
@RequestMapping("/itemCat")
public class ItemCatController {
@Autowired
private ItemCatService itemCatService;
/**
* Demand: query commodity classification information
* Parameters: / {level} 1 level 1 2 level 1 2 Level 3 level 1 2 Level 3
* url: /itemCat/findItemCatList/{level} restFul
* Return value: sysresult (Level 3 list information)
*/
@GetMapping("findItemCatList/{level}")
public SysResult findItemCatList(@PathVariable Integer level){
List<ItemCat> itemCatList = itemCatService.findItemCatList(level);
return SysResult.success(itemCatList);
}
}
2.5 editing 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;
/**
* Step 1. Query the first level menu list
* @param level
* @return
*/
@Override
public List<ItemCat> findItemCatList(Integer level) {
//1. Query level-1 menu
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("parent_id",0);
List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
//2. Query secondary menu secondary data is the sub level of primary data encapsulated in primary data
for(ItemCat oneItemCat : oneList){
int oneId = oneItemCat.getId(); //Primary object ID
//Empty original condition must have
queryWrapper.clear();
queryWrapper.eq("parent_id",oneId);
List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
for(ItemCat twoItemCat : twoList){
//Get secondary classification ID
int twoId = twoItemCat.getId();
//Query Level 3 list information
queryWrapper.clear();
queryWrapper.eq("parent_id",twoId);
List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
//Encapsulate a tertiary list into a secondary object
twoItemCat.setChildren(threeList);
}
//Encapsulate secondary data into primary objects
oneItemCat.setChildren(twoList);
}
return oneList;
}
}
2.6 above case analysis
- The above case adopts a multi-level cycle. In the future, it will consume 100 server resources, 100 inner layers and 10000 cycles in total. It is acceptable for the time being
- The above code frequently accesses the database, resulting in increased database pressure. In severe cases, it may lead to database server downtime. Unacceptable
Optimization strategy: reduce the number of database accesses
2.7 using data structure optimization code
Idea:
- Users query all database information. (1-2-3 all data)
- The data structure map < K, V > key is unique, and value can be of any type
Idea: Map < parentid, list >
example: - Map < 0, list < first level ItemCat Object > >
- Map < 249, list < secondary ItemCat Object > >
- Map < 281, list < Level 3 ItemCat Object > >
map is used to encapsulate parent - child relationship
2.8 code implementation
@Service
public class ItemCatServiceImpl implements ItemCatService{
@Autowired
private ItemCatMapper itemCatMapper;
/**
* Encapsulate all database records with Map collection
* Encapsulated data:
* 1.Traverse all data information
* 2.Get the value of each parentId
* example:
* 1.{id=1,parentId=0,name="Zhang San "}
* 2.{id=2,parentId=0,name="Li Si "}
* 3.{id=3,parentId=1,name="Wang Wu "}
* Map= {
* key : value
* 0 : List[Zhang San object, Li Si object...],
* 1 : List[Wang Wu...]
* }
* @return
*/
public Map<Integer,List<ItemCat>> getMap(){
Map<Integer,List<ItemCat>> map = new HashMap<>();
//1. Query all database information
List<ItemCat> itemCatList = itemCatMapper.selectList(null);
//2. Encapsulate the data into the map set
for (ItemCat itemCat : itemCatList){
Integer key = itemCat.getParentId(); //Get parentId as key
//3. Judge whether there is a value in the map set
if(map.containsKey(key)){
//With value: get the List collection and append yourself to it
map.get(key).add(itemCat);
}else{
//No value: add data. Fill yourself as the first element
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();
//Obtain child information according to level
if(level == 1){ //Get only the first level list information
return map.get(0);
}
if(level == 2){ //Obtain primary and secondary data
return getTwoList(map);
}
List<ItemCat> oneList = getThreeList(map);
long endTime = System.currentTimeMillis();
System.out.println("Time before optimization: 500ms,Time consuming after optimization:"+(endTime - startTime)+"ms");
return oneList;
}
//To obtain the three-level list information, first obtain the level 1 data, then obtain the level 2 data, and then obtain the level 3 data
private List<ItemCat> getThreeList(Map<Integer, List<ItemCat>> map) {
//1. Call the level 2 menu method
List<ItemCat> oneList = getTwoList(map);
//2. The implementation idea traverses the primary set, obtains secondary data, and encapsulates the tertiary menu
for(ItemCat oneItemCat : oneList){
//2.1 obtaining secondary data
List<ItemCat> twoList = oneItemCat.getChildren();
if(twoList == null || twoList.size()==0){
//Judge whether the secondary collection is null. If it is null, it means there is no secondary menu
continue;
}
for (ItemCat twoItemCat : twoList){
int twoId = twoItemCat.getId();
List<ItemCat> threeList = map.get(twoId);
twoItemCat.setChildren(threeList);
}
}
return oneList;
}
//Get the first and second level menu information through the map set
private List<ItemCat> getTwoList(Map<Integer, List<ItemCat>> map) {
List<ItemCat> oneList = map.get(0);
//To obtain secondary information, you should first traverse the primary collection
for (ItemCat oneItemCat : oneList){
int oneId = oneItemCat.getId();
//Get the secondary set according to the primary Id
List<ItemCat> twoList = map.get(oneId);
oneItemCat.setChildren(twoList);
}
return oneList;
}
/**
* Step 1. Query the first level menu list
* @param level
* @return
*/
/* @Override
public List<ItemCat> findItemCatList(Integer level) {
long startTime = System.currentTimeMillis();
//1.Query level 1 menu
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("parent_id",0);
List<ItemCat> oneList = itemCatMapper.selectList(queryWrapper);
//2.Query Level 2 menu level 2 data is the sub level of level 1 data encapsulated in level 1 data
for(ItemCat oneItemCat : oneList){
int oneId = oneItemCat.getId(); //Primary object ID
//Empty original condition must have
queryWrapper.clear();
queryWrapper.eq("parent_id",oneId);
List<ItemCat> twoList = itemCatMapper.selectList(queryWrapper);
for(ItemCat twoItemCat : twoList){
//Get secondary classification ID
int twoId = twoItemCat.getId();
//Query Level 3 list information
queryWrapper.clear();
queryWrapper.eq("parent_id",twoId);
List<ItemCat> threeList = itemCatMapper.selectList(queryWrapper);
//Encapsulate a tertiary list into a secondary object
twoItemCat.setChildren(threeList);
}
//Encapsulate secondary data into primary objects
oneItemCat.setChildren(twoList);
}
long endTime = System.currentTimeMillis();
System.out.println("Time consuming: "+ (endTime - startTime)+"ms ");
return oneList;
}*/
}
3. Implementation of adding commodity classification
3.1 page JS analysis
- Page JS analysis
//Define new objects for commodity classification
itemCatForm: {
name: '', //Define commodity classification name
parentId: 0, //Default parent ID=0
level: 1 //The default is the first level menu
},
async addItemCatForm() {
//Verify the whole form first
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("Failed to add commodity classification")
this.$message.success("Successfully added commodity classification!!!")
//If the addition is successful, the classification list information will be refreshed
this.findItemCatList();
this.addItemCatDialogVisible = false
})
},
3.2 new interface document for commodity classification
- Request path: / itemCat/saveItemCat
- Request type: post
- Request parameter: form data
Parameter name | Parameter description | remarks |
---|
name | Commodity classification name | Cannot be null |
parentId | User parent ID | Cannot be null |
level | Classification level | 1 2 3 commodity classification level |
- Return value: SysResult object
Parameter name | Parameter description | remarks |
---|
status | status information | 200 indicates that the server request is successful, and 201 indicates that the server is abnormal |
msg | Prompt information returned by the server | Can be null |
data | Business data returned by the server | Can be null |
3.3 editing ItemCatController
/**
* Business requirements: add a new commodity classification
* URL: /itemCat/saveItemCat
* Type: post
* Parameters: {name ":" AAAAA "," parentid ": 0," level ": 1} JSON string
* Return value: SysResult object
*/
@PostMapping("/saveItemCat")
public SysResult saveItem(@RequestBody ItemCat itemCat){
itemCatService.saveItem(itemCat);
return SysResult.success();
}
3.4 editing ItemCatService
@Override
@Transactional //Transaction control
public void saveItem(ItemCat itemCat) {
Date date = new Date();
itemCat.setStatus(true).setCreated(date).setUpdated(date);//start-up
itemCatMapper.insert(itemCat);
}
4. Delete commodity classification
4.1 deleting a business interface
- Request path: / itemCat/deleteItemCat
- Request type: delete
- Business description: when the deleted node is the parent, it should delete itself and all child nodes
- Request parameters:
Parameter name | Parameter description | remarks |
---|
id | User id number | Cannot be null |
level | Commodity classification level | Level I, level II, level III |
- Return value result SysResult object
Parameter name | Parameter description | remarks |
---|
status | status information | 200 indicates that the server request is successful, and 201 indicates that the server is abnormal |
msg | Prompt information returned by the server | Can be null |
data | Business data returned by the server | Can be null |
4.2 front end page JS
1. page JS
<el-button type="danger" icon="el-icon-delete" @click="deleteItemCatBtn(scope.row)">delete</el-button>
2. launch Ajax request
//Pass classification id
const {data: result} = await this.$http.delete("/itemCat/deleteItemCat",{params:{id:itemCat.id,level:itemCat.level}})
if(result.status !== 200) return this.$message.error("Failed to delete commodity classification")
this.$message.success("Data deleted successfully")
//After the deletion is successful, refresh the page data
this.findItemCatList()
4.3 editing ItemCatController
/**
* Finish deleting the commodity classification
* 1. Edit URL: /itemCat/deleteItemCat
* 2. Parameter: id/level
* 3. Return value: SysResult()
*/
@DeleteMapping("/deleteItemCat")
public SysResult deleteItemCat(Integer id,Integer level){
itemCatService.deleteItemCat(id,level);
return SysResult.success();
}
4.4 edit ItemCatService
//Delete commodity classification data
@Override
public void deleteItemCat(Integer id, Integer level) {
//Judge whether it is a level 3 menu
if(level == 3){
itemCatMapper.deleteById(id);
}
if(level == 2){
//If it is level 2, you should first obtain level 3 data, then delete it, and then delete yourself
//delete from item_cat where parent_id=#{id} or id = #{id}
QueryWrapper<ItemCat> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("parent_id",id)
.or()
.eq("id",id);
itemCatMapper.delete(queryWrapper);
}
/**
* How to delete the first level menu?
* 1.Get secondary ID
* Ultimate sql: delete from item_cat where parent_id in (twoIds)
* or id in (twoIds)
* or id = #{id}
*/
if(level == 1){
QueryWrapper<ItemCat> queryWrapper = new QueryWrapper();
queryWrapper.eq("parent_id",id);
List twoIds = itemCatMapper.selectObjs(queryWrapper);
//wipe data
queryWrapper.clear();
//Rule: if the level 2 menu has a value, level 2 and level 3 will be deleted
queryWrapper.in(twoIds.size()>0,"parent_id",twoIds)
.or()
.in(twoIds.size()>0,"id",twoIds)
.or()
.eq("id",id);
itemCatMapper.delete(queryWrapper);
}
}
5. Modification
5.1 status modification
5.1.1 page JS analysis
1. page JS function
updateStatus(scope.row)
2. page JS
//Modify status information according to ID
async updateStatus(itemCat) {
const {
data: result
} = await this.$http.put(`/itemCat/status/${itemCat.id}/${itemCat.status}`)
if (result.status !== 200) return this.$message.error("Failed to modify status")
this.$message.success("Status modified successfully")
},
5.1.2 business interface documents
- Request path: / itemCat/status/{id}/{status}
- Request type: put
- Request parameters:
Parameter name | Parameter description | remarks |
---|
id | User ID value | Cannot be null |
status | User status information | Cannot be null |
- Return value: SysResult object
Parameter name | Parameter description | remarks |
---|
status | status information | 200 indicates that the server request was successful |
msg | Prompt information returned by the server | Can be null |
data | Business data returned by the server | Can be null |
5.1.3 editing ItemCatController
/**
* Modify commodity classification status
* URL: /itemCat/status/{id}/{status}
* Request type: PUT/POST
* Request parameter: id/status
* Return value: SysResult object
*/
@PutMapping("/status/{id}/{status}")
public SysResult updateStatus(ItemCat itemCat){
itemCatService.updateStatus(itemCat);
return SysResult.success();
}
5.1.4 edit ItemCatService
@Override
@Transactional
public void updateStatus(ItemCat itemCat) {//id/status
itemCat.setUpdated(new Date());
itemCatMapper.updateById(itemCat);
}
5.2 modifying commodity classification
5.2.1 page JS analysis
1.Specifies the button to modify
<el-button type="success" icon="el-icon-edit" @click="updateItemCatBtn(scope.row)">edit</el-button>
2. Echo of data
//Due to the hierarchical relationship, all modifications can only modify the name
updateItemCatBtn(itemCat) {
this.updateItemCatForm = itemCat
this.updateItemCatDialogVisible = true
},
3. Modify page JS
<el-dialog title="Modify commodity classification" :visible.sync="updateItemCatDialogVisible" width="50%">
<!-- Define classification form -->
<el-form :model="updateItemCatForm" :rules="rules" ref="upDateItemCatForm" label-width="100px">
<el-form-item label="Classification name:" 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">Cancel</el-button>
<el-button type="primary" @click="updateItemCat">determine</el-button>
</span>
</el-dialog>
4. Modify button JS
async updateItemCat() {
//Modify commodity classification information
const {data: result} =
await this.$http.put('/itemCat/updateItemCat', this.updateItemCatForm)
if (result.status !== 200) return this.$message.error("Failed to update product classification")
this.$message.success("Update commodity classification succeeded")
this.findItemCatList();
this.updateItemCatDialogVisible = false;
},
5.2.2 page interface document
- Request path: / itemCat/updateItemCat
- Request type: put
- Request parameter: form data ItemCat object
- Return value: SysResult object
Parameter name | Parameter description | remarks |
---|
status | status information | 200 indicates that the server request was successful |
msg | Prompt information returned by the server | Can be null |
data | Business data returned by the server | Can be null |
- Data analysis:
5.2.3 editing ItemCatController
/**
* Modify commodity classification name
* URL: /itemCat/updateItemCat
* Parameter: JSON string of the whole form
* Return value: SysResult object
*/
@PutMapping("/updateItemCat")
public SysResult updateItemCat(@RequestBody ItemCat itemCat){
itemCatService.updateItemCat(itemCat);
return SysResult.success();
}
5.2.4 edit ItemCatService
//Since only the name of the page is modified, sql only modifies name/updated
@Override
@Transactional
public void updateItemCat(ItemCat itemCat) {
//The user only modifies name,updated by id
ItemCat temp = new ItemCat();
temp.setId(itemCat.getId())
.setName(itemCat.getName())
.setUpdated(new Date());
itemCatMapper.updateById(temp);
}
5.3 debug breakpoint debugging