extends BaseMapper<实体类>
public interface UserMapper extends BaseMapper<User> {
}
@SpringBootApplication
//扫描接口所在包(放入容器中)
@MapperScan("com.itheima.mapper")
public class Springboot07MpApplication {
public static void main(String[] args) {
SpringApplication.run(Springboot07MpApplication.class, args);
}
}
@SpringBootTest
class Springboot07MpApplicationTests {
//注入接口
@Autowired
UserMapper userMapper;
//查询所有
@Test
void findAll() {
List<User> users = userMapper.selectList(null);
for (User user : users) {
System.out.println(user);
}
}
//根据id查询
@Test
void findById() {
User user = userMapper.selectById(1);
System.out.println(user);
}
//增 id会发生类型不匹配的问题
@Test
void save() {
User user = new User();
user.setName("李想");
user.setPassword("123456");
user.setAge(18);
user.setTel("123");
int row = userMapper.insert(user);
System.out.println("row = " + row);
}
//改
@Test
void update() {
User user = userMapper.selectById(1556120358787059714L);
user.setName("李晓");
user.setTel("123456");
int row = userMapper.updateById(user);
System.out.println("row = " + row);
}
使用MP封装的方法进行自增时,自增返回的主键需要使用Long封装类型的id,
@Configuration
public class MyBatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//创建mp拦截器
MybatisPlusInterceptor mpi = new MybatisPlusInterceptor();
//创建分页插件
mpi.addInnerInterceptor(new PaginationInnerInterceptor());
return mpi;
}
}
创建分页对象,使用有参方法
Page page = new Page<>(1, 3);
调用分页查询方法(参数1:page对象,参数2:查询器对象(查询条件))
userMapper.selectPage(page,null);
//分页查询
@Test
void pageTest() {
//1.创建分页对象
Page<User> page = new Page<>(1, 3);
//2.分页查询
userMapper.selectPage(page,null);
System.out.println("当前页是第:" + page.getCurrent()+"页");
System.out.println("每页显示条数:" + page.getSize());
System.out.println("当前页数据" + page.getRecords());
System.out.println("总页数:" + page.getPages());
System.out.println("总条数:" + page.getTotal());
}
# 开启mp的日志(sql语句输出到控制台)
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
<configuration>
configuration>
关于logback参考播客:https://www.jianshu.com/p/75f9d11ae011
spring:
main:
banner-mode: off # 关闭SpringBoot启动图标(banner)
注:关闭语句和mp控制台日志同级
# mybatis-plus日志控制台输出
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
banner: off # 关闭mybatisplus启动图标
//条件查询
@Test
void queryWrapperTest() {
//创建查询器
QueryWrapper<User> qw = new QueryWrapper<>();
//(数据库中的列名,条件)
qw.lt("age", 18);
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println("user = " + user);
}
}
//创建查询器
QueryWrapper<User> qw = new QueryWrapper<>();
qw.lambda().lt(User::getAge, 10);
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println("user = " + user);
}
}
//创建查询器
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge, 18);
List<User> users = userMapper.selectList(lqw);
for (User user : users) {
System.out.println("user = " + user);
}
}
//小于10或者大于25
//或者
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.lt(User::getAge, 10).or().gt(User::getAge, 25);
List<User> users = userMapper.selectList(lqw);
for (User user : users) {
System.out.println("user = " + user);
}
//账户和密码正确才可登录
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
lqw.eq(User::getName, "李晓").eq(User::getPassword, "123");
User user = userMapper.selectOne(lqw);
System.out.println("user = " + user);
QueryWrapper
方法与功能常用方法
方法 | 功能 | 备注 |
---|---|---|
eq | 指定列的值相同 | equals的简写 |
ne | 指定列的值不相同 | not equals的简写 |
lt | 指定列的值小于 | less then的简写 |
le | 指定列的值小于等于 | less then and equals的简写 |
gt | 指定列的值大于 | great then 的简写 |
ge | 指定列的值大于等于 | great then and equals的简写 |
between | 指定列的值在…和…之间 | |
notBetween | 指定列的值不在…和…之间 | |
like | 指定列的值等值模糊查询 | |
notLIke | 指定列的值不等值模糊查询 | |
orderByAsc | 按照指定的列升序排序 | |
orderByDesc | 按照指定的列降序排序 | |
groupBy | 按照指定的列分组 | |
having | 按照指定的列在分组后条件过滤 | |
in | 单条件多值查询 | |
isNull | 指定列的值为空 | |
isNOtNull | 指定列的值不为空 |
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//左右都模糊
lqw.like(User::getName, "张");
List<User> users = userMapper.selectList(lqw);
for (User user : users) {
System.out.println("user = " + user);
}
QueryWrapper<User> qw = new QueryWrapper<>();
//聚合的列(密码,个数)
//聚合的条件,根据密码的不同
qw.select("password", "count(*) as nums").groupBy("password");
List<Map<String, Object>> maps = userMapper.selectMaps(qw);
for (Map<String, Object> map : maps) {
System.out.println("map = " + map);
}
HashMap<String, Integer> map = new HashMap<>();
//map.put("min", 8);
map.put("max", 18);
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
Integer min = map.get("min");
Integer max = map.get("max");
//如果为null,不执行此条件
lqw.ge(min != null, User::getAge, 8);
lqw.le(User::getAge, 18);
List<User> users = userMapper.selectList(lqw);
for (User user : users) {
System.out.println("user = " + user);
}
//创建查询器对象
LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<>();
//创建查询条件
lqw.select(User::getName, User::getAge, User::getTel);
List<User> users = userMapper.selectList(lqw);
for (User user : users) {
System.out.println("user = " + user);
}
//创建查询器对象
QueryWrapper<User> qw = new QueryWrapper<>();
//创建查询条件
qw.select("name", "age");
List<User> users = userMapper.selectList(qw);
for (User user : users) {
System.out.println("user = " + user);
}
//指定表名 (解决表名和类名不一致)
@TableName("t_user")
public class User {
private Long id;
//@TableField("表中字段") (解决表字段和实体类属性名不一致)
@TableField("username")
//实体类属性
private String name;
//mp自动开启了驼峰映射
//不参与查询,但是不影响其他操作,只是对查询有影响
@TableField(select = false)
private String passWord;
private Integer age;
private String tel;
//该变量不参与数据库的CRUD
@TableField(exist = false)
private String online;
mp自动开启驼峰命名
mybatis-plus:
configuration:
# 自动开启驼峰映射
map-underscore-to-camel-case: true
public class User {
//自增
@TableId(type = IdType.AUTO)
private Long id;
mybatis-plus:
global-config:
db-config:
# 全局配置使用雪花算法 可替换(@TableId(type = IdType.AUTO))
id-type: auto
# 表的前缀 可替换(@TableName("t_user"))
table-prefix: t_
//删除指定多条数据
List<Long> list = new ArrayList<>();
list.add(1402551342481838081L);
list.add(1402553134049501186L);
list.add(1402553619611430913L);
userDao.deleteBatchIds(list);
//查询指定多条数据
List<Long> list = new ArrayList<>();
list.add(1L);
list.add(3L);
list.add(4L);
userDao.selectBatchIds(list);
前提:要在数据库中添加响应字段
//逻辑删除字段,标记当前记录是否被删除
// value表示未删除,delval表示已删除
@TableLogic(value="0", delval="1")
private Integer deleted;
mybatis-plus:
global-config:
db-config:
table-prefix: tbl_
# 逻辑删除字段名
logic-delete-field: deleted
# 逻辑删除字面值:未删除为0
logic-not-delete-value: 0
# 逻辑删除字面值:删除为1
logic-delete-value: 1
悲观锁:假设最坏地情况必定会发生,为了避免这种情况发生,我从一开始就给他杜绝了。(Synchronized
)
乐观锁:总是假设最好的情况,每次去拿数据的时候都认为别人不会修改,所以不用上锁。
只在更新的时候会判断一下在此期间别人有没有去更新这个数据。
version
字段来实现。version
字段的值一同读出,数据每更新一次,对此version
值加1 @Version
private Integer version;
SQL
语句拼装@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mpInterceptor() {
//1.定义Mp拦截器
MybatisPlusInterceptor mpInterceptor = new MybatisPlusInterceptor();
//2.添加乐观锁拦截器
mpInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return mpInterceptor;
}
}
//1.先通过要修改的数据id将当前数据查询出来
User user = userDao.selectById(3L); //version=3
User user2 = userDao.selectById(3L); //version=3
user2.setName("Jock aaa");
userDao.updateById(user2); //version=>4
user.setName("Jock bbb");
userDao.updateById(user); //verion=3?条件还成立吗?
执行前先执行查询语句
执行修改时使用vesion字段作为乐观锁的检查依据