Feat: [后台]:完成编辑接口

This commit is contained in:
fanxb 2019-07-17 17:30:40 +08:00
parent 7e491ab10e
commit 67d95c4a28
4 changed files with 478 additions and 426 deletions

View File

@ -1,82 +1,97 @@
package com.fanxb.bookmark.business.bookmark.controller; package com.fanxb.bookmark.business.bookmark.controller;
import com.fanxb.bookmark.business.bookmark.entity.BatchDeleteBody; import com.fanxb.bookmark.business.bookmark.entity.BatchDeleteBody;
import com.fanxb.bookmark.business.bookmark.service.BookmarkService; import com.fanxb.bookmark.business.bookmark.service.BookmarkService;
import com.fanxb.bookmark.common.entity.Bookmark; import com.fanxb.bookmark.common.entity.Bookmark;
import com.fanxb.bookmark.common.entity.Result; import com.fanxb.bookmark.common.entity.Result;
import com.fanxb.bookmark.common.util.UserContextHolder; import com.fanxb.bookmark.common.util.UserContextHolder;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*; import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile; import org.springframework.web.multipart.MultipartFile;
/** /**
* 类功能简述 * 类功能简述
* 类功能详述 * 类功能详述
* *
* @author fanxb * @author fanxb
* @date 2019/7/8 15:12 * @date 2019/7/8 15:12
*/ */
@RestController @RestController
@RequestMapping("/bookmark") @RequestMapping("/bookmark")
public class BookmarkController { public class BookmarkController {
@Autowired @Autowired
private BookmarkService bookmarkService; private BookmarkService bookmarkService;
/** /**
* Description: 获取路径为path的书签数据 * Description: 获取路径为path的书签数据
* *
* @param path 路径 * @param path 路径
* @return com.fanxb.bookmark.common.entity.Result * @return com.fanxb.bookmark.common.entity.Result
* @author fanxb * @author fanxb
* @date 2019/7/15 13:36 * @date 2019/7/15 13:36
*/ */
@GetMapping("/currentUser/path") @GetMapping("/currentUser/path")
public Result getCurrentBookmarkList(String path) { public Result getCurrentBookmarkList(String path) {
return Result.success(bookmarkService.getBookmarkListByPath(UserContextHolder.get().getUserId(), path)); return Result.success(bookmarkService.getBookmarkListByPath(UserContextHolder.get().getUserId(), path));
} }
/** /**
* Description: 上传书签备份文件并解析 * Description: 上传书签备份文件并解析
* *
* @param file 文件 * @param file 文件
* @param path 存放节点路径(根节点为空字符串 * @param path 存放节点路径(根节点为空字符串
* @return com.fanxb.bookmark.common.entity.Result * @return com.fanxb.bookmark.common.entity.Result
* @author fanxb * @author fanxb
* @date 2019/7/8 15:17 * @date 2019/7/8 15:17
*/ */
@PutMapping("/uploadBookmarkFile") @PutMapping("/uploadBookmarkFile")
public Result uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("path") String path) throws Exception { public Result uploadFile(@RequestParam("file") MultipartFile file, @RequestParam("path") String path) throws Exception {
bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file.getInputStream(), path); bookmarkService.parseBookmarkFile(UserContextHolder.get().getUserId(), file.getInputStream(), path);
return Result.success(null); return Result.success(null);
} }
/** /**
* Description: 新增一条书签 * Description: 新增一条书签
* *
* @param bookmark 书签信息 * @param bookmark 书签信息
* @return com.fanxb.bookmark.common.entity.Result * @return com.fanxb.bookmark.common.entity.Result
* @author fanxb * @author fanxb
* @date 2019/7/12 17:28 * @date 2019/7/12 17:28
*/ */
@PutMapping("") @PutMapping("")
public Result addOne(@RequestBody Bookmark bookmark) { public Result addOne(@RequestBody Bookmark bookmark) {
bookmark = bookmarkService.addOne(bookmark); bookmark = bookmarkService.addOne(bookmark);
return Result.success(bookmark); return Result.success(bookmark);
} }
/**
* Description: 批量删除 /**
* * Description: 编辑当前用户的一个书签节点
* @param body 批量删除表单 *
* @return com.fanxb.bookmark.common.entity.Result * @param bookmark bookmark
* @author fanxb * @return com.fanxb.bookmark.common.entity.Result
* @date 2019/7/12 17:28 * @author fanxb
*/ * @date 2019/7/17 14:40
@PostMapping("/batchDelete") */
public Result batchDelete(@RequestBody BatchDeleteBody body) { @PostMapping("/updateOne")
bookmarkService.batchDelete(UserContextHolder.get().getUserId(), body.getFolderIdList(), body.getBookmarkIdList()); public Result editCurrentUserBookmark(@RequestBody Bookmark bookmark) {
return Result.success(null); bookmarkService.updateOne(UserContextHolder.get().getUserId(), bookmark);
} return Result.success(null);
}
}
/**
* Description: 批量删除
*
* @param body 批量删除表单
* @return com.fanxb.bookmark.common.entity.Result
* @author fanxb
* @date 2019/7/12 17:28
*/
@PostMapping("/batchDelete")
public Result batchDelete(@RequestBody BatchDeleteBody body) {
bookmarkService.batchDelete(UserContextHolder.get().getUserId(), body.getFolderIdList(), body.getBookmarkIdList());
return Result.success(null);
}
}

View File

@ -1,83 +1,101 @@
package com.fanxb.bookmark.business.bookmark.dao; package com.fanxb.bookmark.business.bookmark.dao;
import com.fanxb.bookmark.common.entity.Bookmark; import com.fanxb.bookmark.common.entity.Bookmark;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List; import java.util.List;
/** /**
* 类功能简述 * 类功能简述
* 类功能详述 * 类功能详述
* *
* @author fanxb * @author fanxb
* @date 2019/7/8 16:39 * @date 2019/7/8 16:39
*/ */
@Component @Component
public interface BookmarkDao { public interface BookmarkDao {
/** /**
* Description: 插入一条书签记录 * Description: 插入一条书签记录
* *
* @param node node * @param node node
* @return void * @return void
* @author fanxb * @author fanxb
* @date 2019/7/8 16:49 * @date 2019/7/8 16:49
*/ */
void insertOne(Bookmark node); void insertOne(Bookmark node);
/** /**
* Description: 根据用户名和name获取节点id * Description: 根据用户名和name获取节点id
* *
* @param userId 用户名 * @param userId 用户名
* @param name 姓名 * @param name 姓名
* @param path 当前节点路径 * @param path 当前节点路径
* @return Integer * @return Integer
* @author fanxb * @author fanxb
* @date 2019/7/8 17:18 * @date 2019/7/8 17:18
*/ */
Integer selectIdByUserIdAndNameAndPath(@Param("userId") int userId, @Param("name") String name, @Param("path") String path); Integer selectIdByUserIdAndNameAndPath(@Param("userId") int userId, @Param("name") String name, @Param("path") String path);
/** /**
* Description: * Description:
* *
* @param userId 用户id * @param userId 用户id
* @param path 父节点路径 * @param path 父节点路径
* @return java.lang.Integer * @return java.lang.Integer
* @author fanxb * @author fanxb
* @date 2019/7/8 17:35 * @date 2019/7/8 17:35
*/ */
Integer selectMaxSort(@Param("userId") int userId, @Param("path") String path); Integer selectMaxSort(@Param("userId") int userId, @Param("path") String path);
/** /**
* Description: 根据用户id获取其所有数据 * Description: 根据用户id获取其所有数据
* *
* @param userId userid * @param userId userid
* @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark> * @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
* @author fanxb * @author fanxb
* @date 2019/7/9 18:55 * @date 2019/7/9 18:55
*/ */
List<Bookmark> getListByUserId(int userId); List<Bookmark> getListByUserId(int userId);
List<Bookmark> getListByUserIdAndPath(@Param("userId") int userId,@Param("path") String path); /**
* Description: 根据userId和path查询path下的子节点
/** *
* Description: 删除某用户某个书签文件下所有数据 * @param userId userId
* * @param path path
* @param userId 用户id * @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
* @param folderId 文件夹id * @author fanxb
* @author fanxb * @date 2019/7/17 14:48
* @date 2019/7/12 14:13 */
*/ List<Bookmark> getListByUserIdAndPath(@Param("userId") int userId, @Param("path") String path);
void deleteUserFolder(@Param("userId") int userId, @Param("folderId") int folderId);
/**
/** * Description: 删除某用户某个书签文件下所有数据
* Description: 删除用户书签 *
* * @param userId 用户id
* @param userId 用户id * @param folderId 文件夹id
* @param bookmarkIds 书签id * @author fanxb
* @author fanxb * @date 2019/7/12 14:13
* @date 2019/7/12 17:24 */
*/ void deleteUserFolder(@Param("userId") int userId, @Param("folderId") int folderId);
void deleteUserBookmark(@Param("userId") int userId, @Param("bookmarkIds") List<Integer> bookmarkIds);
} /**
* Description: 删除用户书签
*
* @param userId 用户id
* @param bookmarkIds 书签id
* @author fanxb
* @date 2019/7/12 17:24
*/
void deleteUserBookmark(@Param("userId") int userId, @Param("bookmarkIds") List<Integer> bookmarkIds);
/**
* Description: 编辑书签
*
* @author fanxb
* @date 2019/7/17 14:49
* @param bookmark bookmark
*/
void editBookmark(Bookmark bookmark);
}

View File

@ -1,183 +1,196 @@
package com.fanxb.bookmark.business.bookmark.service; package com.fanxb.bookmark.business.bookmark.service;
import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao; import com.fanxb.bookmark.business.bookmark.dao.BookmarkDao;
import com.fanxb.bookmark.common.entity.Bookmark; import com.fanxb.bookmark.common.entity.Bookmark;
import com.fanxb.bookmark.common.exception.CustomException; import com.fanxb.bookmark.common.exception.CustomException;
import com.fanxb.bookmark.common.util.UserContextHolder; import com.fanxb.bookmark.common.util.UserContextHolder;
import org.jsoup.Jsoup; import org.jsoup.Jsoup;
import org.jsoup.nodes.Document; import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element; import org.jsoup.nodes.Element;
import org.jsoup.select.Elements; import org.jsoup.select.Elements;
import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DuplicateKeyException; import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service; import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional; import org.springframework.transaction.annotation.Transactional;
import java.io.InputStream; import java.io.InputStream;
import java.util.List; import java.util.List;
/** /**
* 类功能简述 * 类功能简述
* 类功能详述 * 类功能详述
* *
* @author fanxb * @author fanxb
* @date 2019/7/8 15:00 * @date 2019/7/8 15:00
*/ */
@Service @Service
public class BookmarkService { public class BookmarkService {
/** /**
* chrome导出书签tag * chrome导出书签tag
*/ */
private static final String DT = "dt"; private static final String DT = "dt";
private static final String A = "a"; private static final String A = "a";
@Autowired @Autowired
private BookmarkDao bookmarkDao; private BookmarkDao bookmarkDao;
/** /**
* Description: 解析书签文件 * Description: 解析书签文件
* *
* @param stream 输入流 * @param stream 输入流
* @param path 存放路径 * @param path 存放路径
* @author fanxb * @author fanxb
* @date 2019/7/9 18:44 * @date 2019/7/9 18:44
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void parseBookmarkFile(int userId, InputStream stream, String path) throws Exception { public void parseBookmarkFile(int userId, InputStream stream, String path) throws Exception {
Document doc = Jsoup.parse(stream, "utf-8", ""); Document doc = Jsoup.parse(stream, "utf-8", "");
Elements elements = doc.select("html>body>dl>dt"); Elements elements = doc.select("html>body>dl>dt");
//获取当前层sort最大值 //获取当前层sort最大值
Integer sortBase = bookmarkDao.selectMaxSort(1, path); Integer sortBase = bookmarkDao.selectMaxSort(1, path);
if (sortBase == null) { if (sortBase == null) {
sortBase = 0; sortBase = 0;
} }
int count = 0; int count = 0;
for (int i = 0, length = elements.size(); i < length; i++) { for (int i = 0, length = elements.size(); i < length; i++) {
if (i == 0) { if (i == 0) {
Elements firstChildren = elements.get(0).child(1).children(); Elements firstChildren = elements.get(0).child(1).children();
count = firstChildren.size(); count = firstChildren.size();
for (int j = 0; j < count; j++) { for (int j = 0; j < count; j++) {
dealBookmark(userId, firstChildren.get(j), path, sortBase + j); dealBookmark(userId, firstChildren.get(j), path, sortBase + j);
} }
} else { } else {
dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1); dealBookmark(userId, elements.get(i), path, sortBase + count + i - 1);
} }
} }
} }
/** /**
* Description: 根据userId和path获取书签列表 * Description: 根据userId和path获取书签列表
* *
* @param userId userId * @param userId userId
* @param path path * @param path path
* @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark> * @return java.util.List<com.fanxb.bookmark.common.entity.Bookmark>
* @author fanxb * @author fanxb
* @date 2019/7/15 13:40 * @date 2019/7/15 13:40
*/ */
public List<Bookmark> getBookmarkListByPath(int userId, String path) { public List<Bookmark> getBookmarkListByPath(int userId, String path) {
return bookmarkDao.getListByUserIdAndPath(userId, path); return bookmarkDao.getListByUserIdAndPath(userId, path);
} }
/** /**
* Description: 批量删除书签 * Description: 批量删除书签
* *
* @param userId 用户id * @param userId 用户id
* @param folderIdList 书签文件夹id list * @param folderIdList 书签文件夹id list
* @param bookmarkIdList 书签id list * @param bookmarkIdList 书签id list
* @author fanxb * @author fanxb
* @date 2019/7/12 14:09 * @date 2019/7/12 14:09
*/ */
@Transactional(rollbackFor = Exception.class) @Transactional(rollbackFor = Exception.class)
public void batchDelete(int userId, List<Integer> folderIdList, List<Integer> bookmarkIdList) { public void batchDelete(int userId, List<Integer> folderIdList, List<Integer> bookmarkIdList) {
for (Integer item : folderIdList) { for (Integer item : folderIdList) {
bookmarkDao.deleteUserFolder(userId, item); bookmarkDao.deleteUserFolder(userId, item);
bookmarkIdList.add(item); bookmarkIdList.add(item);
} }
bookmarkDao.deleteUserBookmark(userId, bookmarkIdList); bookmarkDao.deleteUserBookmark(userId, bookmarkIdList);
} }
/** /**
* Description: 详情 * Description: 详情
* *
* @param bookmark 插入一条记录 * @param bookmark 插入一条记录
* @return com.fanxb.bookmark.common.entity.Bookmark * @return com.fanxb.bookmark.common.entity.Bookmark
* @author fanxb * @author fanxb
* @date 2019/7/12 17:18 * @date 2019/7/12 17:18
*/ */
public Bookmark addOne(Bookmark bookmark) { public Bookmark addOne(Bookmark bookmark) {
int userId = UserContextHolder.get().getUserId(); int userId = UserContextHolder.get().getUserId();
Integer sort = bookmarkDao.selectMaxSort(userId, bookmark.getPath()); Integer sort = bookmarkDao.selectMaxSort(userId, bookmark.getPath());
bookmark.setSort(sort == null ? 1 : sort + 1); bookmark.setSort(sort == null ? 1 : sort + 1);
bookmark.setUserId(userId); bookmark.setUserId(userId);
bookmark.setCreateTime(System.currentTimeMillis()); bookmark.setCreateTime(System.currentTimeMillis());
bookmark.setAddTime(bookmark.getCreateTime()); bookmark.setAddTime(bookmark.getCreateTime());
try { try {
bookmarkDao.insertOne(bookmark); bookmarkDao.insertOne(bookmark);
} catch (DuplicateKeyException e) { } catch (DuplicateKeyException e) {
throw new CustomException("同级目录下不能存在相同名称的数据"); throw new CustomException("同级目录下不能存在相同名称的数据");
} }
return bookmark; return bookmark;
} }
/**
/** * Description: 编辑某个用户的某个书签
* Description: 处理html节点解析出文件夹和书签 *
* * @author fanxb
* @param ele 待处理节点 * @date 2019/7/17 14:42
* @param path 节点路径不包含自身 * @param userId userId
* @param sort 当前层级中的排序序号 * @param bookmark bookmark
* @author fanxb */
* @date 2019/7/8 14:49 public void updateOne(int userId,Bookmark bookmark){
*/ bookmark.setUserId(userId);
private void dealBookmark(int userId, Element ele, String path, int sort) { bookmarkDao.editBookmark(bookmark);
if (!DT.equalsIgnoreCase(ele.tagName())) { }
return;
}
Element first = ele.child(0); /**
if (A.equalsIgnoreCase(first.tagName())) { * Description: 处理html节点解析出文件夹和书签
//说明为链接 *
Bookmark node = new Bookmark(userId, path, first.ownText(), first.attr("href"), first.attr("icon") * @param ele 待处理节点
, Long.valueOf(first.attr("add_date")) * 1000, sort); * @param path 节点路径不包含自身
//存入数据库 * @param sort 当前层级中的排序序号
insertOne(node); * @author fanxb
} else { * @date 2019/7/8 14:49
//说明为文件夹 */
Bookmark node = new Bookmark(userId, path, first.ownText(), Long.valueOf(first.attr("add_date")) * 1000, sort); private void dealBookmark(int userId, Element ele, String path, int sort) {
Integer sortBase = 0; if (!DT.equalsIgnoreCase(ele.tagName())) {
if (insertOne(node)) { return;
sortBase = bookmarkDao.selectMaxSort(node.getUserId(), path); }
if (sortBase == null) { Element first = ele.child(0);
sortBase = 0; if (A.equalsIgnoreCase(first.tagName())) {
} //说明为链接
} Bookmark node = new Bookmark(userId, path, first.ownText(), first.attr("href"), first.attr("icon")
String childPath = path + "." + node.getBookmarkId(); , Long.valueOf(first.attr("add_date")) * 1000, sort);
Elements children = ele.child(1).children(); //存入数据库
for (int i = 0, size = children.size(); i < size; i++) { insertOne(node);
dealBookmark(userId, children.get(i), childPath, sortBase + i + 1); } else {
} //说明为文件夹
} Bookmark node = new Bookmark(userId, path, first.ownText(), Long.valueOf(first.attr("add_date")) * 1000, sort);
} Integer sortBase = 0;
if (insertOne(node)) {
/** sortBase = bookmarkDao.selectMaxSort(node.getUserId(), path);
* Description: 插入一条书签如果已经存在同名书签将跳过 if (sortBase == null) {
* sortBase = 0;
* @param node node }
* @return boolean 如果已经存在返回true否则false }
* @author fanxb String childPath = path + "." + node.getBookmarkId();
* @date 2019/7/8 17:25 Elements children = ele.child(1).children();
*/ for (int i = 0, size = children.size(); i < size; i++) {
private boolean insertOne(Bookmark node) { dealBookmark(userId, children.get(i), childPath, sortBase + i + 1);
//先根据name,userId,parentId获取此节点id }
Integer id = bookmarkDao.selectIdByUserIdAndNameAndPath(node.getUserId(), node.getName(), node.getPath()); }
if (id == null) { }
bookmarkDao.insertOne(node);
return false; /**
} else { * Description: 插入一条书签如果已经存在同名书签将跳过
node.setBookmarkId(id); *
return true; * @param node node
} * @return boolean 如果已经存在返回true否则false
} * @author fanxb
* @date 2019/7/8 17:25
} */
private boolean insertOne(Bookmark node) {
//先根据name,userId,parentId获取此节点id
Integer id = bookmarkDao.selectIdByUserIdAndNameAndPath(node.getUserId(), node.getName(), node.getPath());
if (id == null) {
bookmarkDao.insertOne(node);
return false;
} else {
node.setBookmarkId(id);
return true;
}
}
}

View File

@ -1,79 +1,85 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.fanxb.bookmark.business.bookmark.dao.BookmarkDao"> <mapper namespace="com.fanxb.bookmark.business.bookmark.dao.BookmarkDao">
<insert id="insertOne" useGeneratedKeys="true" keyColumn="bookmarkId" keyProperty="bookmarkId"> <insert id="insertOne" useGeneratedKeys="true" keyColumn="bookmarkId" keyProperty="bookmarkId">
insert into bookmark(userId,path,type,name,url,icon,sort,addTime,createTime) insert into bookmark(userId,path,type,name,url,icon,sort,addTime,createTime)
value value
( #{userId},#{path},#{type},#{name}, ( #{userId},#{path},#{type},#{name},
<if test="url == null"> <if test="url == null">
"","", "","",
</if> </if>
<if test="url != null"> <if test="url != null">
#{url},#{icon}, #{url},#{icon},
</if> </if>
#{sort},#{addTime},#{createTime}) #{sort},#{addTime},#{createTime})
</insert> </insert>
<select id="selectIdByUserIdAndNameAndPath" resultType="java.lang.Integer"> <select id="selectIdByUserIdAndNameAndPath" resultType="java.lang.Integer">
select bookmarkId select bookmarkId
from bookmark from bookmark
where userId = #{userId} and path = #{path} and name = #{name}; where userId = #{userId} and path = #{path} and name = #{name};
</select> </select>
<select id="selectMaxSort" resultType="java.lang.Integer"> <select id="selectMaxSort" resultType="java.lang.Integer">
select max(sort) select max(sort)
from bookmark from bookmark
where userId = #{userId} and path = #{path} where userId = #{userId} and path = #{path}
</select> </select>
<select id="getListByUserId" resultType="com.fanxb.bookmark.common.entity.Bookmark"> <select id="getListByUserId" resultType="com.fanxb.bookmark.common.entity.Bookmark">
select select
bookmarkId, bookmarkId,
path, path,
type, type,
name, name,
url, url,
icon, icon,
sort sort
from bookmark from bookmark
where userId = #{userId} where userId = #{userId}
order by path, sort order by path, sort
</select> </select>
<select id="getListByUserIdAndPath" resultType="com.fanxb.bookmark.common.entity.Bookmark"> <select id="getListByUserIdAndPath" resultType="com.fanxb.bookmark.common.entity.Bookmark">
select select
bookmarkId, bookmarkId,
path, path,
type, type,
name, name,
url, url,
icon, icon,
sort sort
from bookmark from bookmark
where userId = #{userId} and path = #{path} where userId = #{userId} and path = #{path}
order by sort order by sort
</select> </select>
<delete id="deleteUserFolder"> <delete id="deleteUserFolder">
DELETE DELETE
FROM FROM
bookmark bookmark
WHERE WHERE
userId = #{userId} userId = #{userId}
and path LIKE (SELECT a.path and path LIKE (SELECT a.path
FROM (SELECT CONCAT(path, '.', '${folderId}', '%') AS path FROM (SELECT CONCAT(path, '.', '${folderId}', '%') AS path
FROM bookmark FROM bookmark
WHERE bookmarkId = #{folderId}) a); WHERE bookmarkId = #{folderId}) a);
</delete> </delete>
<delete id="deleteUserBookmark"> <delete id="deleteUserBookmark">
delete from bookmark where userId = #{userId} and bookmarkId in delete from bookmark where userId = #{userId} and bookmarkId in
<foreach collection="bookmarkIds" item="item" open="(" close=")" separator=","> <foreach collection="bookmarkIds" item="item" open="(" close=")" separator=",">
#{item} #{item}
</foreach> </foreach>
</delete> </delete>
<update id="editBookmark" parameterType="com.fanxb.bookmark.common.entity.Bookmark">
update bookmark
set name = #{name}, url = #{url}
where bookmarkId = #{bookmarkId} and userId = #{userId}
</update>
</mapper> </mapper>