wordpress怎么看展現(xiàn)量北京百度推廣優(yōu)化排名
文章目錄
- 1.MybatisPlus實(shí)現(xiàn)基本的CRUD
- 快速開始
- 常見注解
- 常見配置
- 2.使用條件構(gòu)建造器構(gòu)建查詢和更新語句
- 條件構(gòu)造器
- 自定義SQL
- Service接口
官網(wǎng)
MybatisPlus無侵入和方便快捷.
MybatisPlus不僅僅可以簡(jiǎn)化單表操作,而且還對(duì)Mybatis的功能有很多的增強(qiáng)??梢宰屛覀兊拈_發(fā)更加的簡(jiǎn)單,高效。
通過今天的學(xué)習(xí),我們要達(dá)成下面的目標(biāo):
- 能利用MybatisPlus實(shí)現(xiàn)基本的CRUD
- 會(huì)使用條件構(gòu)建造器構(gòu)建查詢和更新語句
1.MybatisPlus實(shí)現(xiàn)基本的CRUD
快速開始
初始化工程: 配置文件
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root
logging:level:com.itheima: debugpattern:dateformat: HH:mm:ss
mybatis:mapper-locations: classpath*:mapper/*.xml
實(shí)體類
@Data
public class User {/*** 用戶id*/private Long id;/*** 用戶名*/private String username;/*** 密碼*/private String password;/*** 注冊(cè)手機(jī)號(hào)*/private String phone;/*** 詳細(xì)信息*/private String info;/*** 使用狀態(tài)(1正常 2凍結(jié))*/private Integer status;/*** 賬戶余額*/private Integer balance;/*** 創(chuàng)建時(shí)間*/private LocalDateTime createTime;/*** 更新時(shí)間*/private LocalDateTime updateTime;
}
dao層/mapper層
public interface UserMapper{void saveUser(User user);void deleteUser(Long id);void updateUser(User user);User queryUserById(@Param("id") Long id);List<User> queryUserByIds(@Param("ids") List<Long> ids);
}
mapper.xml
<?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">
<mapper namespace="com.itheima.mp.mapper.UserMapper"><insert id="saveUser" parameterType="com.itheima.mp.domain.po.User">INSERT INTO `user` (`id`, `username`, `password`, `phone`, `info`, `balance`)VALUES(#{id}, #{username}, #{password}, #{phone}, #{info}, #{balance});</insert><update id="updateUser" parameterType="com.itheima.mp.domain.po.User">UPDATE `user`<set><if test="username != null">`username`=#{username}</if><if test="password != null">`password`=#{password}</if><if test="phone != null">`phone`=#{phone}</if><if test="info != null">`info`=#{info}</if><if test="status != null">`status`=#{status}</if><if test="balance != null">`balance`=#{balance}</if></set>WHERE `id`=#{id};</update><delete id="deleteUser" parameterType="com.itheima.mp.domain.po.User">DELETE FROM user WHERE id = #{id}</delete><select id="queryUserById" resultType="com.itheima.mp.domain.po.User">SELECT *FROM userWHERE id = #{id}</select><select id="queryUserByIds" resultType="com.itheima.mp.domain.po.User">SELECT *FROM user<if test="ids != null">WHERE id IN<foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></if>LIMIT 10</select></mapper>
現(xiàn)在我們來改造!用mp快速體驗(yàn)一下:
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3.1</version></dependency>
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.itheima.mp.domain.po.User;
import org.apache.ibatis.annotations.Param;import java.util.List;public interface UserMapper extends BaseMapper<User> {
}
把那些方法全部都刪除了,然后把mapper.xml文件也一并刪除.我們繼承的這個(gè)"爸爸"里面這些方法它都有,所以我們直接去測(cè)試類測(cè)試即可.
import com.itheima.mp.domain.po.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDateTime;
import java.util.List;@SpringBootTest
class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testvoid testInsert() {User user = new User();user.setId(5L);user.setUsername("Lucy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userMapper.insert(user);}@Testvoid testSelectById() {User user = userMapper.selectById(5L);System.out.println("user = " + user);}@Testvoid testQueryByIds() {List<User> users = userMapper.selectBatchIds(List.of(1L, 2L, 3L, 4L));users.forEach(System.out::println);}@Testvoid testUpdateById() {User user = new User();user.setId(5L);user.setBalance(20000);userMapper.updateById(user);}@Testvoid testDeleteUser() {userMapper.deleteById(5L);}
}
全部都能測(cè)試成功,而且updateById語句如果你沒有修改其他的字段那么其他字段不會(huì)修改.這樣實(shí)現(xiàn)單表增刪改查全部搞定.
常見注解
MybatisPlus通過掃描實(shí)體類,并基于反射獲取實(shí)體類信息作為數(shù)據(jù)庫(kù)表信息.
@Data
@TableName("user")
public class User {/*** 用戶id*/@TableId(type = IdType.AUTO)//默認(rèn)使用雪花算法生成idprivate Long id;/*** 用戶名*/
// @TableField("`username`")private String username;/*** 密碼*/
// @TableField(exist = false)private String password;/*** 注冊(cè)手機(jī)號(hào)*/private String phone;/*** 詳細(xì)信息*/private String info;/*** 使用狀態(tài)(1正常 2凍結(jié))*/private Integer status;/*** 賬戶余額*/private Integer balance;/*** 創(chuàng)建時(shí)間*/private LocalDateTime createTime;/*** 更新時(shí)間*/private LocalDateTime updateTime;
}
常見配置
但是其實(shí)大部分都是默認(rèn)配置具體可以看官網(wǎng)那些是默認(rèn)配置
mybatis-plus:type-aliases-package: com.itheima.mp.domain.poglobal-config:db-config:id-type: auto
2.使用條件構(gòu)建造器構(gòu)建查詢和更新語句
核心功能:
條件構(gòu)造器
@Testvoid testQueryWrapper(){Wrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info","balance").like("username", "o").ge("balance", 1000);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}
debug信息:
14:40:41 DEBUG 26264 — [ main] c.i.mp.mapper.UserMapper.selectList : ==> Preparing: SELECT id,username,info,balance FROM user WHERE (username LIKE ? AND balance >= ?)
14:40:41 DEBUG 26264 — [ main] c.i.mp.mapper.UserMapper.selectList : > Parameters: %o%(String), 1000(Integer)
14:40:41 DEBUG 26264 — [ main] c.i.mp.mapper.UserMapper.selectList : < Total: 1
@Testvoid testUpdateWrapper(){//1.要更新的數(shù)據(jù)User user = new User();user.setBalance(2000);//2.更新的條件QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");//3.執(zhí)行更新userMapper.update(user,wrapper);}
debug日志信息:
14:45:32 DEBUG 15964 — [ main] com.itheima.mp.mapper.UserMapper.update : ==> Preparing: UPDATE user SET balance=? WHERE (username = ?)
14:45:32 DEBUG 15964 — [ main] com.itheima.mp.mapper.UserMapper.update : > Parameters: 2000(Integer), jack(String)
14:45:32 DEBUG 15964 — [ main] com.itheima.mp.mapper.UserMapper.update : < Updates: 1
@Testvoid testUpdateWrapper(){UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance + 200").in("id", List.of(1L, 2L, 3L, 4L));userMapper.update(null,wrapper);}
但是這種寫法是硬編碼.
推薦Lambda
@Testvoid testLambdaQueryWrapper(){LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<User>().select(User::getId, User::getUsername,User::getInfo, User::getBalance).like(User::getUsername, "o").ge(User::getBalance, 1000);List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}
自定義SQL
我們可以利用MybatisPlus的wrapper來構(gòu)建where條件,然后自己定義SQL語句中剩下部分.
這樣確實(shí)方便但是這是在業(yè)務(wù)層中,這在很多企業(yè)中是不允許的.
@Testvoid testCustomSql(){List<Long>ids = List.of(1L, 2L, 3L, 4L);int amount = 200;QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);userMapper.updateBalanceByIds(wrapper, amount);}
public interface UserMapper extends BaseMapper<User> {@Update("UPDATE user set balance = balance + #{amount} ${ew.customSqlSegment}")void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper, @Param("amount") int amount);
}
Service接口
@SpringBootTest
class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSave(){User user = new User();
// user.setId(5L);user.setUsername("yyy");user.setPassword("123");user.setPhone("18688990011");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}@Testvoid testQuery(){List<User> users = userService.listByIds(List.of(1L, 2L, 3L));users.forEach(System.out::println);}}
我們發(fā)現(xiàn)Iservice 和 baseMapper其實(shí)有很多方法都是重復(fù)的,從功能上是一致的,那我們應(yīng)該如何選擇?這里給出一個(gè)案例來進(jìn)行講解:
<!--swagger-->
<dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi2-spring-boot-starter</artifactId><version>4.1.0</version>
</dependency>
<!--web-->
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId>
</dependency>
然后配置swagger信息
knife4j:enable: trueopenapi:title: 用戶管理接口文檔description: "用戶管理接口文檔"email: zhanghuyi@itcast.cnconcat: 虎哥url: https://www.itcast.cnversion: v1.0.0group:default:group-name: defaultapi-rule: packageapi-rule-resources:- com.itheima.mp.controller
@Data
@ApiModel(description = "用戶表單實(shí)體")
public class UserFormDTO {@ApiModelProperty("id")private Long id;@ApiModelProperty("用戶名")private String username;@ApiModelProperty("密碼")private String password;@ApiModelProperty("注冊(cè)手機(jī)號(hào)")private String phone;@ApiModelProperty("詳細(xì)信息,JSON風(fēng)格")private String info;@ApiModelProperty("賬戶余額")private Integer balance;
}
@Data
@ApiModel(description = "用戶VO實(shí)體")
public class UserVO {@ApiModelProperty("用戶id")private Long id;@ApiModelProperty("用戶名")private String username;@ApiModelProperty("詳細(xì)信息")private String info;@ApiModelProperty("使用狀態(tài)(1正常 2凍結(jié))")private Integer status;@ApiModelProperty("賬戶余額")private Integer balance;
}
@Api(tags = "用戶管理接口")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {private final IUserService userService;// 注入userService 有final才注入// public UserController(IUserService userService) {
// this.userService = userService;
// }@ApiOperation("新增用戶接口")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.DTO拷貝1到POUser user = BeanUtil.copyProperties(userDTO, User.class);//2.新增userService.save(user);}@ApiOperation("刪除用戶接口")@DeleteMapping("/{id}")public void DeleteUser(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("根據(jù)id查詢用戶接口")@GetMapping("/{id}")public UserVO queryUser(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id){User user = userService.getById(id);UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);return userVO;}@ApiOperation("根據(jù)id批量查詢用戶接口")@PostMappingpublic List<UserVO> queryUser(@RequestParam("ids") List<Long> ids){List<User> users = userService.listByIds(ids);return BeanUtil.copyToList(users, UserVO.class);}}
以后在大多數(shù)場(chǎng)景下直接用IService就可以了,因?yàn)檫@幾個(gè)沒有業(yè)務(wù)邏輯。
第五個(gè)接口是有業(yè)務(wù)的接口,要判斷狀態(tài),判斷余額數(shù)量等等。。
在controller中
@ApiOperation("扣減用戶余額接口")@PutMapping("/{id}/deduction/{money}")public void deduction(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id,@ApiParam(name = "money", value = "扣減金額", required = true) @PathVariable("money") Integer money) {userService.deduction(id, money);}
service層
public interface IUserService extends IService<User> {void deduction(Long id, Integer money);
}
serviceImpl
@Service
public class UserServiceImlp extends ServiceImpl<UserMapper, User> implements IUserService {@Overridepublic void deduction(Long id, Integer money) {//1. 根據(jù)id查詢用戶User user = this.getById(id);//2.檢驗(yàn)用戶狀態(tài)if(user==null || user.getStatus()!=1){throw new RuntimeException("用戶狀態(tài)異常");}//3.檢驗(yàn)余額是否充足if(user.getBalance()<money){throw new RuntimeException("余額不足");}//4.扣除余額baseMapper.deductBalance(id,money);}
}
mapper:
public interface UserMapper extends BaseMapper<User> {@Update("UPDATE user set balance = balance + #{amount} ${ew.customSqlSegment}")void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper, @Param("amount") int amount);@Update("UPDATE user set balance = balance - #{money} WHERE id = #{id}")void deductBalance(@Param("id") Long id,@Param("money") Integer money);
}
import cn.hutool.core.bean.BeanUtil;
import com.itheima.mp.domain.dto.UserFormDTO;
import com.itheima.mp.domain.po.User;
import com.itheima.mp.domain.vo.UserVO;
import com.itheima.mp.service.IUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;import java.util.List;@Api(tags = "用戶管理接口")
@RestController
@RequestMapping("/user")
@RequiredArgsConstructor
public class UserController {private final IUserService userService;// 注入userService 有final才注入// public UserController(IUserService userService) {
// this.userService = userService;
// }@ApiOperation("新增用戶接口")@PostMappingpublic void saveUser(@RequestBody UserFormDTO userDTO){//1.DTO拷貝1到POUser user = BeanUtil.copyProperties(userDTO, User.class);//2.新增userService.save(user);}@ApiOperation("刪除用戶接口")@DeleteMapping("/{id}")public void DeleteUser(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id){userService.removeById(id);}@ApiOperation("根據(jù)id查詢用戶接口")@GetMapping("/{id}")public UserVO queryUser(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id){User user = userService.getById(id);UserVO userVO = BeanUtil.copyProperties(user, UserVO.class);return userVO;}@ApiOperation("根據(jù)id批量查詢用戶接口")@PostMappingpublic List<UserVO> queryUser(@RequestParam("ids") List<Long> ids){List<User> users = userService.listByIds(ids);return BeanUtil.copyToList(users, UserVO.class);}@ApiOperation("扣減用戶余額接口")@PutMapping("/{id}/deduction/{money}")public void deduction(@ApiParam(name = "id", value = "用戶id", required = true) @PathVariable("id") Long id,@ApiParam(name = "money", value = "扣減金額", required = true) @PathVariable("money") Integer money) {userService.deduction(id, money);}}
query:
@Data
@ApiModel(description = "用戶查詢條件實(shí)體")
public class UserQuery {@ApiModelProperty("用戶名關(guān)鍵字")private String name;@ApiModelProperty("用戶狀態(tài):1-正常,2-凍結(jié)")private Integer status;@ApiModelProperty("余額最小值")private Integer minBalance;@ApiModelProperty("余額最大值")private Integer maxBalance;
}
controller:
@ApiOperation("根據(jù)復(fù)雜條件查詢用戶接口")@GetMapping("/list")public List<UserVO> queryUserByCondition(UserQuery query){List<User>users = userService.queryUsers(query.getName(),query.getStatus(),query.getMinBalance(),query.getMaxBalance())return BeanUtil.copyToList(users, UserVO.class);}
IUservice:
public interface IUserService extends IService<User> {void deduction(Long id, Integer money);List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance);
}
serviceimpl
public List<User> queryUsers(String name, Integer status, Integer minBalance, Integer maxBalance) {return lambdaQuery().like(name != null, User::getUsername, name).eq(status != null, User::getStatus, status).ge(minBalance != null, User::getBalance, minBalance).le(name != null, User::getBalance, maxBalance).list();}
@Service
public class UserServiceImlp extends ServiceImpl<UserMapper, User> implements IUserService {@Transactionalpublic void deduction(Long id, Integer money) {//1. 根據(jù)id查詢用戶User user = this.getById(id);//2.檢驗(yàn)用戶狀態(tài)if(user==null || user.getStatus()!=1){throw new RuntimeException("用戶狀態(tài)異常");}//3.檢驗(yàn)余額是否充足if(user.getBalance()<money){throw new RuntimeException("余額不足");}//4.扣除余額
// baseMapper.deductBalance(id,money);int remainBalance = user.getBalance()-money;//樂觀鎖 compare and setlambdaUpdate().set(User::getBalance,remainBalance).set(remainBalance==0,User::getStatus,2).eq(User::getId,id).eq(User::getBalance,user.getBalance()) //樂觀鎖 讓并發(fā)安全性更好.update();//不要忘記這一條}
}
上面哪一種一條條執(zhí)行,每一次提交都是一次網(wǎng)絡(luò)請(qǐng)求,每次網(wǎng)絡(luò)請(qǐng)求都要耗費(fèi)一定的時(shí)間,而下面每次插入1000條,采取預(yù)編譯方案,相當(dāng)于每1000次才發(fā)一次網(wǎng)絡(luò)請(qǐng)求
如何把我們的sql語句變成這樣?用動(dòng)態(tài)SQL,foreach,或者還是使用mp的批處理指令,但是你會(huì)發(fā)現(xiàn)這個(gè)sql語句不對(duì)啊,但其實(shí)這個(gè)不對(duì)只是缺少了一個(gè)參數(shù)rewriteBatchedStatements=true
參數(shù),這個(gè)配置是mysql的配置,默認(rèn)為false所以我們之前以為的批處理實(shí)際上都是一條條的插入,所以我們要改這個(gè)配置
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=truedriver-class-name: com.mysql.cj.jdbc.Driverusername: rootpassword: root
在url后面加上這個(gè)參數(shù)即可