@Autowired
ISongsService songsService;
@Test
public void add(){
Songs s=new Songs(null,"11","xx",null,"xx歌曲","2020-02-12");
songsService.save(s);
System.out.println(s);
}
// 根据 ID 选择修改,entity指的是实体类的意思,
//注意:①仅会根据主键id修改实体类中不为null的非主键字段。
//②若使用的数据库是MySQL,那么实体类的主键字段前必须加上@TableId注解
boolean updateById(T entity);
@Autowired
ISongsService songsService;
@Test
public void updateOne(){
// 根据 ID来修改
Songs songs = new Songs(1002, "凤凰传奇", null, null, "策马奔腾", null);
boolean b = songsService.updateById(songs);
System.out.println("更新结果:"+b);
}
// 根据ID 批量更新, entityList传的是集合Collection的实现类,可以是ArrayList
//注意:①仅会根据主键id批量修改实体类中不为null的非主键字段。
//②若使用的数据库是MySQL,那么实体类的主键字段前必须加上@TableId注解
boolean updateBatchById(Collection<T> entityList);
@Test
public void updateMore(){
// 根据 ID来批量更新,也是不为null的非主键字段都会更新
List<Songs> list=new ArrayList<>();
list.add(new Songs(1002, "周杰伦", null, null, "七里香", null));
list.add(new Songs(1004, "汪苏泷", null, null, "三国杀", null));
list.add(new Songs(1005, "凤凰传奇", null, null, "荷塘月色", null));
boolean b = songsService.updateBatchById(list);
System.out.println("批量更新结果:"+b);
}
// 根据 ID 删除,可以传Integer或者String类型的数据,因为都实现了java.io.Serializable接口
boolean removeById(Serializable id);
//常规删除:删除单条
@Test
public void deleteOne(){
boolean b = songsService.removeById(1004);
System.out.println("删除单条结果:"+b);
}
// 删除(根据ID 批量删除)
boolean removeBatchByIds(Collection<?> list)
//常规删除:批量删除
@Test
public void deleteMore(){
List<Integer> list=new ArrayList<>();
list.add(1002);
list.add(1005);
boolean b = songsService.removeBatchByIds(list);
System.out.println("结果:"+b);
}
并不是真正的从数据表删除这条数据,而是将表中的逻辑删除字段的值变更为1(此时就代表逻辑删除成功了)
注意:①若是自定义sql,就需要自己写where子句
②默认是以0表示未删除,1表示已删除
③逻辑删除本质就是更改表的某个字段,在查询和更新的时候给定规则去进行筛选
@TableLogic
private Integer del;
package com.zlz.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.*;
/**
*
*
*
*
* @author zlz
* @since 2023-01-02
*/
//①改动地方1
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Songs implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String singerName;
private String album;
private String albumImg;
private String name;
//②改动地方2,调成String形式,就不用转型了
private String releaseDate;
//需要加上属性名 @TableLogic表示逻辑删除
@TableLogic
private Integer del;
}
@Test
public void remove(){
boolean b = songsService.removeById(1006);
System.out.println("逻辑删除结果: "+b);
}
@Test
public void find(){
Songs s=songsService.getById(1006);
System.out.println("逻辑删除后再查该数据的结果:"+s);
}
@Test
public void updateOne(){
// 根据 ID来修改
Songs songs = new Songs(1006, "凤凰传奇", null, null, "策马奔腾", null,null);
boolean b = songsService.updateById(songs);
System.out.println("配置了逻辑删除后,更新的结果为:"+b);
}
① 当要更新一条记录的时候,希望这条记录没有被别人更新
② 为了解决多个用户同时修改相同的数据时的冲突问题
③ 乐观锁是业务的实现(代码不加锁)
④ 修改时,会根据版本修改,修改成功后会递增版本
⑤ 乐观锁只是修改的时候起作用,支持的数据类型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
@Version
private Integer v;
package com.zlz.entity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import java.io.Serializable;
import java.util.Date;
import com.baomidou.mybatisplus.annotation.TableLogic;
import com.baomidou.mybatisplus.annotation.Version;
import lombok.*;
/**
*
*
*
*
* @author zlz
* @since 2023-01-02
*/
//①改动地方1
@AllArgsConstructor
@NoArgsConstructor
@Data
public class Songs implements Serializable {
private static final long serialVersionUID = 1L;
@TableId(value = "id", type = IdType.AUTO)
private Integer id;
private String singerName;
private String album;
private String albumImg;
private String name;
private String releaseDate;
//② 乐观锁配置
@Version
private Integer v;
}
//加上乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
package com.zlz.config;
import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@MapperScan("com.zlz.mapper")//mapper接口扫描,@MapperScan也可以放在启动类PlusStart上面(启动类也算配置类)
public class PlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//设置分页插件,别的拦截器也是addInnerInterceptor加入进去
PaginationInnerInterceptor pi = new PaginationInnerInterceptor();
pi.setDbType(DbType.MYSQL);//设置数据库类型为MySQL
pi.setOverflow(true);//溢出分页处理,默认是false不处理,需要设置成true,保证分页合理化
interceptor.addInnerInterceptor(pi);
//加上乐观锁插件
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
@Test
public void positiveLock(){
//查询到的版本都是一样的
Songs s1 = songsService.getById(1006);
Songs s2 = songsService.getById(1006);
//模拟修改
s1.setName("光年之外");
//第一个用户修改成功后,版本会加1
boolean b1 = songsService.updateById(s1);
System.out.println("第一个用户修改的结果: "+b1);
//第二个用户并发修改时 版本就会查询不到,就会修改失败
boolean b2 = songsService.updateById(s2);
System.out.println("第二个用户修改的结果: "+b2);
}
@RequestMapping("update")
@ResponseBody
public boolean update(){
Songs s = songsService.getById(2);
return songsService.updateById(s);
}