1.Mybatis 接口注解说明
1.1 需求说明
Mybatis实现数据查询时有两种Sql写法
1.将所有的Sql语句都写到XML语句都写到xml映射文件中(万能操作方式)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-DNeWTNpm-1624682865935)(…/…/…/图片/资料Pcs/20210625092018252.png)]
- 可以将Sql语句通过注解的方式标识在接口方法中(只使用简单操作)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IhF4G2Kh-1624682865940)(…/…/…/图片/资料Pcs/2021062509243076.png)]
1.2 注解的种类
说明:该注解一般都是操作的数据查询,如果遇到关联查询/复杂Sql则使用Mapper映射文件的方式更加优化
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nBnr8iDP-1624682865945)(…/…/…/图片/资料Pcs/2021062509265292.png)]
1.3 Mybatis 案例练习
1.3.1 测试方法
@SpringBootTest
public class TestMybatis{
//明确:注入一定是对象
//SpringBoot为了整合mybatis,简化代码结构 Spring冬天的为Mybatis的接口
//创建代理对象
//代理:根据原有对象的模型,在运行期动态创建了一个一样的实例化对象
//案例:孙悟空(接口)/克隆一样的对象
@Autowied
private UserMapper userMapper;
@Test
publiv 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("yes");
}
//将新七五的年龄改为20 心别改为女
@Test
public void update(){
User user = new User();
user.setAge(20).setSex("女").setName("新七五");
userMapper.updateByName(user);
}
}
1.3.2 Mapper接口文件写法
//@Mapper //Spring为改接口创建一个代理对象
public interface UserMapper{
//查询所有的user表数据
List<User> findAll();
//注意事项:映射文件和注解二选一
@Select("select*from demo_user where id = #{id}")
//@Insert("") //新增时使用
//@Update("") //更新
//@Detele("") //删除
User findUserById(int id);
//#{name} 从对象中获取指定的属性的值,#有预编译的效果 防止Sql注入攻击
@Insert("insert into demo_user(id,name,age,sex) value (null,#{name},#{age},#{sex})")
void insert(User user);
@Update("update demo_user set age=#{age},sex=#{sex} where name=#{name}")
void updateByName(User user);
}
2. MybatisPlus
2.1 MP介绍
说明:MyBatis-Plus(opens new window)(简称MP)是一个MyBatis(open new window)的增强工具,在MyBatis的基础上只做增强不做改变,为简化开发、提高效率而生。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a9IONty8-1624682865950)(…/…/…/图片/资料Pcs/20210625101908408.png)]
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中的属性与吧hi澳中的字段——映射
注解:
1.@TableName(“demo_user”)//事项对象与表名映射
2.//设定主键自增@TableId(type=IdType.AUTO)
3.@TableFieId(“name”)实现属性与字段映射
规则:如果属性域字段的名称一致,则注解可以省略
实际用法:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-t0hIJif2-1624682865952)(…/…/…/图片/资料Pcs/image-20210626111856750.png)]
2.3.4 继承公共的接口
说明:继承接口之后,必须添加泛型对象,否则程序无法执行
父级中的接口:
MP将常用的CURD的方法进行了抽取,以后子类如果需要调用,则直接使用即可。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cgWjRRUm-1624682865955)(…/…/…/图片/资料Pcs/20210625113255977.png)]
配置过程:
2.3.5 MP生效配置
说明:将原来的mybatis改为mybatis-plus
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z8ipet0L-1624682865957)(…/…/…/图片/资料Pcs/image-20210626112252436.png)]
2.3.6 MP入门案例
说明:以对象的方式操作数据库,单表几乎不写Sql简化代码操作
//思想:以对象的方式操作数据库 单表几乎不写Sql
//简化CURD操作
@Test
public void testInsert(){
User user = new User();
user.setName("MP").setAge(19).setSex("ss");
userMapper.insert(user);
}
2.4 MP工作原理
核心思想:以对象的方式操作数据库
配置:
1.编辑POJO与数据表的映射
2.编辑POJO属性与表字段映射.映射表
3.封装了大量的常用CURD API简化用户调用
4.根据对象动态的生成Sql语句
执行过程:
-
程序业务开始调用
userMapper.insert(对象) -
根据Mapper接口动态获取操作的泛型对象,获取对象之后获取表的相关数据
public interface UserMapper extends BaseMapper -
只要获取对象 获取表名称 字段
-
将对象转换为特定的Sql,之后交给Mybatis执行
userMapper.insert(user对象)
deptMapper.insert(dept对象)Sql:insert into (表名)(字段名) values (字段的值)
2.5 MP常用操作
//1.根据id查询
@Test
public void testSelect1(){
User user = userMapper.selectById(521);
System.out.println(user);
}
//2.查询新明为景天 性别为男的用户
//Sql: select*from demo_user where name="xxx" and sex="xxx"
@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);
}
/*3.查询姓名为赵云 性别为男的用户
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);
}
/*4.查询年龄大于18的性别为女的用户
* Sql: select*from demo_user where age>18 and sex="女"
* 逻辑运算符: > gt , < lt , = eq , >= ge , <= le , != ne */
@Test
public void testSelect4(){
//创建新的MD条件构造器对象+泛型
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//设置MD条件构造器的条件
queryWrapper.gt("age",18).eq("sex","女");
//通过List集合打印MD结果
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/*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<User>queryWrapper2 = new QueryWrapper<>();
// queryWrapper2.likeLeft("name","天");
List<User> userList = userMapper.selectList(queryWrapper);
// List<User> userList1 = userMapper.selectList(queryWrapper2);
System.out.println(userList);
// System.out.println(userList1);
}
/*6. 关键字 in
需求:查询ID为1,3,5,6的数据
Sql:select*from demo_user where id in (1,3,5,6)
java基础:参数中使用...表示可变参数类型 多个参数逗号分隔
一般定义可变参数类型时 位于方法的最后一位
可变参数类型的实质就是数组,学法不同
*/
@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);
}
/*7.关键字: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);
}
/*动态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","女").orderByDesc("age","id");
//附加条件 按照age降序排序 age相同时,通过id降序排序
List<User> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/*9.只获取主键ID的值
* Sql:select id from demo_user*/
@Test
public void testSelect9(){
List idList = userMapper.selectObjs(null);
System.out.println(idList);
}
/*10. 删除 name = "xxx" 的数据*/
@Test
public void testDelete(){
//删除ID为100的数据
userMapper.deleteById(58);
//userMapper.deleteBatchIds(null);
//删除操作的条件构造器
QueryWrapper queryWrapper= new QueryWrapper();
queryWrapper.eq("name","xxx");
userMapper.delete(queryWrapper);
}
/*11.数据修改/更新
* 案例:要求修改id=522 name改为紫萱
* API说明:userMapper.updateById(对象信息)*/
@Test
public void testUpdate(){
//修改除了ID之外的所有不为null的数据,id当作where唯一条件
User user = new User();
user.setId(522).setName("紫萱");
userMapper.updateById(user);
}
/*12.数据修改2
* 案例:将name为星期五的用户改为 name仙剑传5 age13 sex 2
* API说明:
* userMapper.update(对象,修改条件构造器)
* 对象:修改后的数据使用对象封装
* 修改条件构造器:负责修改的where的条件*/
@Test
public void testUpdate2(){
User user = new User();
user.setName("仙剑传5").setAge(13).setSex("2");
UpdateWrapper updateWrapper = new UpdateWrapper();
updateWrapper.eq("name","星期五");
userMapper.update(user,updateWrapper);
}