1. Mybatis 接口注解说明
1.1 需求说明
Mybatis实现数据查询时有2种Sql的写法.
- 将所有的Sql语句都写到xml 映射文件中. (万能操作方式)
- 可以将Sql语句通过注解的方式标识在接口方法中.(只适用于简单操作)
1.2 注解的种类
说明: 该注解一般都是操作简单的数据查询,如果遇到关联查询/复杂Sql则使用Mapper映射文件的方式 更加通用.
1.3 Mybatis 案例练习
1.3.1 测试方法
@SpringBootTest
public class TestMybatis {
//明确:注入一定是对象
//SpringBoot为了整合mybatis,简化代码结构 Spring动态的为Mybatis的接口
//创建代理对象
//代理: 根据原有对象的模型,在运行期动态创建了一个一模一样功能的实例化对象
//案例: 孙悟空(接口)/克隆一个一模一样的对象
@Autowired
private UserMapper userMapper;
@Test
public void testFind(){
System.out.println(userMapper.getClass());
List<User> userList = userMapper.findAll();
System.out.println(userList);
}
//根据ID查询数据
@Test
public void findUserById(){
User user = userMapper.findUserById(11);
System.out.println(user);
}
//新增用户
//数据从哪里来 前端动态获取
@Test
public void insert(){
User user = new User();
user.setName("星期五").setSex("男").setAge(18);
userMapper.insert(user);
System.out.println("新增成功");
}
//将星期五的年龄改为20 性别改为女
@Test
public void update(){
User user = new User();
user.setAge(20).setSex("女").setName("星期五");
userMapper.updateByName(user);
}
}
1.3.2 Mapper接口文件写法
1.3.1 测试方法
@SpringBootTest
public class TestMybatis {
//明确:注入一定是对象
//SpringBoot为了整合mybatis,简化代码结构 Spring动态的为Mybatis的接口
//创建代理对象
//代理: 根据原有对象的模型,在运行期动态创建了一个一模一样功能的实例化对象
//案例: 孙悟空(接口)/克隆一个一模一样的对象
@Autowired
private UserMapper userMapper;
@Test
public void testFind(){
System.out.println(userMapper.getClass());
List<User> userList = userMapper.findAll();
System.out.println(userList);
}
//根据ID查询数据
@Test
public void findUserById(){
User user = userMapper.findUserById(11);
System.out.println(user);
}
//新增用户
//数据从哪里来 前端动态获取
@Test
public void insert(){
User user = new User();
user.setName("星期五").setSex("男").setAge(18);
userMapper.insert(user);
System.out.println("新增成功");
}
//将星期五的年龄改为20 性别改为女
@Test
public void update(){
User user = new User();
user.setAge(20).setSex("女").setName("星期五");
userMapper.updateByName(user);
}
}
1.3.2 Mapper接口文件写法
2. MybatisPlus
2.1 MP介绍
说明: MyBatis-Plus (opens new window)(简称 MP)是一个 MyBatis (opens new window)的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。
2.2 为什么使用MP
场景说明: 小红是一个10年开发 ,月薪100万. 需要小红开发一套京淘项目实现最常用的CURD功能. 像这类操作 即简单又繁琐.如果大量的代码都由程序员自己手写 则影响开发效率.
需求: 像这类又简单 又繁琐的工作最好交给框架自动完成.
说明: 使用MP主要完成单表的CURD操作简化开发
2.3 MP入门案例
2.3.1 实现步骤
- 导入jar包文件
- 思想: 使用对象的方式操作数据库
- 编辑POJO 实现对象与数据表的映射关系.
- 继承公共的接口,获取常用的CURD操作.
- 实现数据操作.
2.3.2 引入jar包
<!--spring整合mybatis-plus MP中包含了mybatis的包所以将原来的包删除 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.3</version>
</dependency>
2.3.3 编辑POJO
说明:
1.POJO应该与数据库中的表完成映射
2.POJO中的属性与表中的字段一一映射.
注解:
1. @TableName(“demo_user”) //实现对象与表名映射
2. //设定主键自增 @TableId(type = IdType.AUTO)
3. @TableField(“name”) 实现属性与字段映射.
规则: 如果属性与字段的名称一致,则注解可以省略
实际用法:
2.3.4 继承公共的接口
说明: 继承接口之后,必须添加泛型对象 否则程序无法执行
父级中的接口:
MP将常用的CURD的方法进行了抽取. 以后子类如果需要调用.则直接使用即可.
配置过程:
2.3.5 MP生效配置
说明: 将原来的mybatis 改为mybatis-plus
2.3.6 MP 入门案例
说明: 以对象的方式操作数据库 单表几乎不写Sql 简化代码操作
//思想: 以对象的方式操作数据库 单表几乎不写Sql
//简化CURD操作
@Test
public void testInsert(){
User user = new User();
user.setName("MP").setAge(19).setSex("其他");
userMapper.insert(user);
}
2.4 MP工作原理
核心思想: 以对象的方式操作数据库.
配置:
1. 编辑POJO与数据表的映射.
2. 编辑POJO属性与表字段映射. 映射.
3. 封装了大量的常用CURD API 简化用户调用
4. 根据对象动态的生成Sql语句.
执行过程:
1. 程序业务开始调用
userMapper.insert(user);
2. 根据Mapper接口动态获取操作的泛型对象.获取对象之后获取表的相关数据
public interface UserMapper extends BaseMapper
3. 只要获取对象 获取了 表名称,字段名称.数据的值
4. 将对象转化为特定的Sql,之后交给Mybatis执行.
userMapper.insert(user对象)
deptMapper.insert(dept对象)
carMapper.insert(car对象)
Sql: insert into demo_user(id,name,age,sex) values(null,xxx,xx,xx)
2.5 MP常用操作
2.5.1 根据ID查询
//1.根据id主键 查询id=1的数据
//SELECT id,name,age,sex FROM demo_user WHERE id=?
@Test
public void testSelect1(){
User user = userMapper.selectById(1);
System.out.println(user);
}
2.5.2 selectList查询(一)
//2.查询name="小乔" sex="男"的用户
//Sql: select * from demo_user where name="xx" and sex="xx"
@Test
public void testSelect2(){
//创建条件构造器 封装where条件的.
User user = new User();
user.setName("小乔").setSex("男");
//实现时会动态的根据对象中不为null的属性,拼接where条件,
//默认的关系链接符 and
QueryWrapper queryWrapper = new QueryWrapper(user);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.3 selectList查询(二)
//3.查询name="小乔" sex="男"的用户
//Sql:SELECT id,name,age,sex FROM demo_user WHERE name=? AND sex=?
@Test
public void testSelect3(){
QueryWrapper<User> queryWrapper = new QueryWrapper();
queryWrapper.eq("name","小乔")
.eq("sex","男");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.4 selectList查询(三)
//4.查询 age> 18 sex="女"的用户
//Sql:SELECT * demo_user WHERE age > 18 and sex="女"
//逻辑运算符 > gt, < lt, = eq, >= ge, <= le, != ne
@Test
public void testSelect4(){
QueryWrapper<User> queryWrapper = new QueryWrapper();
queryWrapper.gt("age",18)
.eq("sex","女");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.5 selectList查询-like关键字
//5. like关键字
//5.1 查询name包含"乔" where name like '%乔%'
//5.2 查询name以乔结尾的 where name like '%乔'
@Test
public void testSelect5(){
QueryWrapper<User> queryWrapper = new QueryWrapper();
//queryWrapper.like("name","乔");
queryWrapper.likeLeft("name","乔");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.6 selectList查询-in关键字
/**
* 6. in 关键字
* 需求: 查询ID为1,3,5,6的数据
* Sql: select * from demo_user where id in (1,3,5,6)
*/
@Test
public void testSelect6(){
//一般的数组采用包装类型,使用对象身上的方法 基本类型没有方法
Integer[] ids = {1,3,5,6};
QueryWrapper<User> queryWrapper = new QueryWrapper();
queryWrapper.in("id",ids);
//采用可变参数类型 实现查询
//queryWrapper.in("id",1,3,5,6);
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.7 selectList查询-order by
/**
* 关键字: order by 排序
* 默认规则: 升序 asc 如果降序 desc
* 需求: 查询性别为男的用户并且 按照年龄降序排列.
* Sql: select * from demo_user where sex="男" order by age desc
*/
@Test
public void testSelect7(){
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("sex","男")
.orderByDesc("age");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.8 selectList查询-动态Sql
/**
* 动态Sql:
* 根据用户的条件,动态的拼接where条件
* 案例: 根据sex,age查询数据
* 1.select * from demo_user where age > 18 and sex="女"
* API说明:
* queryWrapper.gt(判断条件,字段名称,字段值)
* 判断条件: true 则动态的拼接where条件
* false 不会拼接where条件
* 判断语句:
* Boolean sexBoo = (sex !=null) && sex.length()>0;
*/
@Test
public void testSelect8(){
Integer age = 18;
String sex = "女";
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
Boolean ageBoo = (age !=null);
Boolean sexBoo = StringUtils.hasLength(sex);
queryWrapper.gt(ageBoo, "age",age)
.eq(sexBoo,"sex","女");
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
2.5.8 selectList查询-objs
/**
* 练习9: 只获取主键ID的值
* Sql: select id from demo_user
*/
@Test
public void testSelect9(){
List idList = userMapper.selectObjs(null);
System.out.println(idList);
}
2.5.9 删除操作
/**
* 练习10: 删除name="xxx"的数据
*/
public void testDelete(){
//删除ID为100的数据
userMapper.deleteById(100);
//userMapper.deleteBatchIds(null);
//删除操作的条件构造器
QueryWrapper queryWrapper = new QueryWrapper();
queryWrapper.eq("name","xxx");
userMapper.delete(queryWrapper);
}
2.5.10 更新操作-byId
/**
* 练习11: 数据修改
* 案例1: 要求修改id=233 name改为="晚上吃什么"
* API说明: userMapper.updateById(对象信息)
*/
@Test
public void testUpdate(){
//修改除ID之外的所有不为null的数据,id当作where一位条件
User user = new User();
user.setId(233).setName("晚上吃什么");
userMapper.updateById(user);
}
2.5.11 更新操作-任意字段
/**
* 练习12: 数据修改
* 案例2: 将name=mp的用户改为name="宵夜吃什么" age=20 sex=女
* API说明:
* userMapper.update(对象,修改条件构造器)
* 对象: 修改后的数据使用对象封装
* 修改条件构造器: 负责修改的where条件
*/
@Test
public void testUpdate2(){
User user = new User();
user.setName("宵夜吃什么").setAge(20).setSex("女");
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.eq("name","MP");
userMapper.update(user,updateWrapper);
}