** Mybatis-Plus 从不会到熟练使用 **

Mybatis-Plus 从不会到熟练使用

一. MyBaits-Plus简介及快速入门

1.1学习前的技术储备

  • 熟悉Lambda表达式
  • 熟悉SpringBoot、Maven
  • 最好熟悉MyBatis

1.2Mybatis vs JPA

  • MyBatis的优势:

    • SQL语句可以自由控制,更灵活,性能更高
    • SQL与代码分离,易于阅读和维护
    • 提供XML标签,支持编写动态SQL语句
  • JPA的优势:

    • JPA移植性比较好(JPQL)
    • 提供了很多CRUD方法、开发效率高
    • 对象化程度更高
  • MyBatis的劣势:

    • 简单的CRUD操作还得写SQL语句
    • XML中有大量的SQL需要维护
    • MyBaits自身功能有限,但支持Plugin

MP: Mybatis-Plus的出现就是为了解决MyBatis的缺点又能继承它的优点来的;

1.3 MyBatis-Plus的简介

  • MP是一个MyBatis的增强工具,只做增强不做改变
  • 文档及项目地址: 直接百度即可

1.4 特性介绍

  • 无侵入、损耗小、强大的CRUD操作
  • 支持Lambda形式调用,支持多种数据库
  • 支持主键自动生成,支持ActiveRecord模式
  • 支持自定义全局通用操作,支持关键词自动转义
  • 内置代码生成器、内置分页插件、内置性能分析插件
  • 内置全局拦截插件、内置SQL注入剥离器

1.5 快速入门

  • 步骤:
    在这里插入图片描述
  • 过程:
  1. 创建名字为mp 的数据库

  2. 放入数据: user 表,图示:
    在这里插入图片描述

  3. 初始化数据:
    在这里插入图片描述

  4. 建好表并存入数据,然后创建项目:

    1. groupId: com.mp
    2. ArtiafctId: first
    3. 引入依赖:
    		<dependency>
    			<groupId>org.springframework.boot</groupI>
    			<artifactId>spring-boot-starter</artifactId>
    		</dependency>
    		<dependency>
    			<groupId>org.springframework.boot</groupI>
    			<artifactId>spring-boot-starter-test</artifactId>
    		<scope>test</scope>
    		</dependency>
    		<dependency>
    			<groupId>org.projectlombok</groupI>
    			<artifactId>lombok</artifactId>
    			<optional>true</optional>
    		</dependency>
    		<dependency>
    			<groupId>com.baomidou</groupI>
    			<artifactId>mybaits-plus-boot-starter</artifactId>
    			<version>3.1.0</version>
    		</dependency>
    		<dependency>
    			<groupId>mysql</groupI>
    			<artifactId>mysql-connector-java</artifactId>
    		</dependency>
    
    1. 在resource的目录下创建application.yml:
    	spring:
    		datasource:
    			driver-class-name: com.mysql.cj.jdbc.Driver
    			url: jdbc:mysql://localhost:3306/mp?useSSL=false&Timezone=GMT%2B8
    			username: root
    			password: root
    
    1. 创建启动类: com.mp.Application
    		@SpringBootApplication
    		@MapperScan("com.mp.dao")
    		public class Application{
    			SpringApplication.run(Application.class,args);
    		}
    
    1. 创建实体类User:com.mp.entity.User
    		@Data
    		@ToString
    		public class User{
    		//主键
    		private Long id;
    		//姓名
    		private String name;
    		//年龄
    		private Integer age;
    		//邮箱
    		private String email;
    		//直属上级
    		private Long managerId;
    		//创建时间
    		private LocalDateTime createTime;
    		}
    
    1. 创建dao层接口UserMapper: com.mp.dao.UserMapper
    		public interface UserMapper extends BaseMapper<User>
    
    1. 创建测试类:SimpleTest com.mp.SimpleTest;
    		@RunWith(SpringRunner.class)
    		@SpringBootTest
    		public class SimpleTest{
    
    		@Autowried
    		private UserMapper userMapper;
    
    		@Test
    		public void select(){
    			List<User>list=userMapper.selectList(null);
    			Assert.assertEquals(5,list.size());
    			list.forEach(System.out::println);
    		}
    		}
    

1.6 分析:

  • SSM传统编程模式:

    • 接口中写抽象方法
    • XML或注解写SQL
    • Service中调用接口
    • Controller中调用
  • 通用Mapper

    • 写代码前对application.yml的操作:
    	logging:
    		level:
    			root: warn
    			com.mp.dao: trace
    		pattern:
    			console: '%p%m%n'
    
    • 新增方法:创建测试类:InsertTest.java
    	@RunWith(SpringRunner.class)
    	@SpringBootTest
    	public class InsertTest{
    
    	@Autowried
    	private UserMapper userMapper;
    
    	@Test
    	public void insert(){
    		User user=new User();
    		user.setName("刘明强");
    		user.setAge(31);
    		user.setManagerId(1088248166370832385L)
    		user.setCreateTime(LocalDateTime.now());
    		int rows.userMapper.insert(user);
    		System.out.println("影响记录数"+rows);
    	}	
    

1.7 常用注解:

  • @TableName(“数据库表名”): 用来表示此Entity下的类与数据库表名的对应关系
  • @TableId(“数据库主键Id名字”) 如果是userId与user_id之间的关系则不需要给value,它是放在在主键上面的
  • @TableField: 它是放在其他字段上面的

如果属性名与数据库字段一致则无需修改,如果不一致则在括号中给对应的数据库字段名,如下所示:

//加上注解的改变(已在数据库中,将该表名改为mp_user,字段id改为user_id)
@Data
@TableName("mp_user")
public class User{
//主键
@TableId
private Long userId;
@TableField("name");
private String realName;
private Integer age;
private String email;
private Long managerId;
private LocalDateTime createTime;
}

1.7 排除非表字段的三种方式

  • 概述: 有些字段我们在数据库中不想保存此记录,则可以进行忽略,则此属性的值不会被保存;
  • 方式:
    • 方式一: 加上transient关键词:(为null)
      • 如: private transient String 属性名; (不参与序列化)
    • 方式二: 使用静态变量static : (全类唯一一份,不符合要求)
      • 如: private static String 属性名 并设置静态的get,set方法
    • 方式三: 使用@TableField(exist=false): (每个对象有自己单独的一份)
    		@TableField(exist=false);
    		private String 属性名;
    

二. 增删查改

2.1 查询

  • 前面为了展示注解的作用,对数据库和对应的实体类进行了修改,这里假设已经还原;
  • 结构:
    • 基本查询方法
    • 以条件构造器为参数的查询方法
    • select 中字段不全出现的处理方法

2.2 查询演示:

	@SpringBootTest
	@RunWith(SpringRunner.class)
	public class RetrieveTest{
	
	@Autowired
	private UserMapper userMapper;
	
	/**
	* 根据Id查询
	* /
	@Test
	public void selectById(){
		User user=userMapper.selectById(1094590409767661570L);
		System.out.println(user);
	}
	
	/**
	* 根据Id集合查询
	* /
	@Test
	public void selectIds(){
		List<Long> idsList=Arrays.asList(10945920410xxx,xxxxx,xxxxx,xxxx);//获取id集合
		List<User> userList=userMapper.selectBatchIds(idsList);
		userList.forEach(System.out::println);
	}
	
	/**
	*根据条件查询
	*/
	@Test
	public void selectByMap(){
		Map<String,Object> columnMap=new HashMap<>();
	//	columnMap.put("name","王天风");	//必须与数据库中的对应,如果没有会报错
		columnMap.put("age",27);		//键是数据库中的列  where age= 27
		List<User> userList=userMapper.selectByMap(columnMap);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求: 名字中包含雨并且年龄小于40
	* name like '%雨%' and age<40 
	*/
	@Test
	public void selectByWrapper1(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.like("name","雨").It("age",40);
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	} 
	/**
	* 条件构造器查询
	* 需求2: 名字中包含雨并且年龄大于等于20且小于等于40并且email不为空
	* name like '%雨%' and age between 20 and 40 and email is not null
	*/
	@Test
	public void selectByWrapper2(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求3: 名字为王姓或者年龄大于等于25,按照年龄降序排列,年龄相同按照id升序排列;   
	* name like '王%' or age>= 25 order by age desc,id asc
	*/
	@Test
	public void selectByWrapper3(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.likeRight("name","王").or().ge("age",25).orderByDesc("age").orderByAsc("id");
		List<User> userList= userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求4: 创建日期为2019年2月14日并且直属上级为名字为王姓
	* data_format(craete_time,'$Y-%m-%d')and manager_id in (select id from user where name like '王%')
	*/
	@Test
	public void selectByWrapper4(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.apply("date_format(create_time,'%Y-%m-%d')=2019-02-14").inSql("manager_id","select id from user where name like '王%'");
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求5: 名字为王姓并且(年龄小于40或邮箱不为空)
	* name like '王%' and (age<40 or email is not null)
	*/
	@Test
	public void selectByWrapper5(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.likeRight("name","王").and(wq->wq.It("age",40).or().isNotNull("email"));
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求6: 名字为王姓或者(年龄小于40并且年龄大于20并且邮箱不为空)
	* name like '王%' or (age<40 and age>20 and email is not null)
	*/
	@Test
	public void selectByWrapper5(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.likeRight("name","王").or(wq->wq.It("age",40).gt("age",20).isNotNull("email"));
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	
	/**
	* 条件构造器查询
	* 需求7: (年龄小于40或邮箱不为空)并且名字为王姓
	* (age<40 or email is not null) and name like '王%'
	*/
	@Test
	public void selectByWrapper7(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.nested(wq.It("age",40).or().isNotNull("email")).likeRight("name","王");
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求8: 年龄为30、31、34、35
	* age in (30、31、34、35)
	*/
	@Test
	public void selectByWrapper8(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.in("age",Arrays.asList(30,31,34,35));
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求9:只返回满足条件的其中一条语句即可
	* limit 1
	*/
	@Test
	public void selectByWrapper9(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.in("age",Arrays.asList(30,31,34,35)).last("limit 1");
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}
	
	/**
	* 条件构造器查询
	* 需求10: 名字中包含雨并且年龄小于40   只查询id,name两个字段
	* name like '%雨%' and age<40 
	*/
	@Test
	public void selectByWrapper10(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.select("id","name").like("name","雨").It("age",40);
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	} 
	
	
	/**
	* 条件构造器查询
	* 需求10: 名字中包含雨并且年龄小于40   只查询部分字段使用排除法
	* select id,name,age,email from user where like '%雨%' and age<40
	*/
	@Test
	public void selectByWrapper10(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.like("name","雨").It("age",40).select(User.class,info->!info.getColumn().equals("create_time")&&!info.getColumn().equals("manager_id"));
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
		} 
	}

condition作用:当它的值为true的时候,这个方法才会执行

	@Test
	public void testCondition(){
	String name="王";
	String email="";
	condition(name,email);
	}
	
	private void condition(String name,String email){
	QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
	//if(StringUtils.isNotEmpty(name)){
	//queryWrapper.like("name",name);
	//}
	//if(StringUtils.isNotEmpty(email)){
	//	queryWrapper.like("email",email);
	//}
	 // 下面的写法可以替代上面的这两个
	queryWrapper.like(StringUtils.isNotEmpty(name),"name",name).like(StringUtils.isNotEmpty(email),"email",email);
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}

实体作为条件构造器构造方法的参数

	@Test
	public void selectByWrapperEntity(){
		User whereUser=new User();
		whereUser.setName("刘红雨");
		whereUser.setAge(32);
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>(whereUser);
		queryWrapper.like("name","雨").It("age",40);		//这条语句写上,会与whereUser这条同时生效;
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}

在这里插入图片描述

  • 当加上了SqlCondition.like,那么name字段的内容就与queryWrapper.like(“name”,“雨”)意思一致;它里面还有很多种,有空自己可以去看看;

2.3 AllEq用法

	@Test
	public void selectByWrapperAllEq(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		Map<String,Object> params=new HashMap<String,Object>();
		params.put("name","王天风");
		params.put("age",25);
		//queryWrapper.allEq(params);
		//过滤查询
		queryWrapper.allEq((k,v)!k.equals("name"),params);
		List<User> userList=userMapper.selectList(queryWrapper);
		userList.forEach(System.out::println);
	}

在这里插入图片描述

这里allEq就可以加搜索条件

2.4 其他使用条件构造器的方法

  • 核心代码
	QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
	queryWrapper.select("id","name").like("name","雨").It("age",40);
	//使用selectMaps,返回的结果是键值对,即Key为字段名,value为值名;
	//使用了select指定了id,name,则返回的只有这两个数据;如果非selectMaps方式,则返回的结果,非id,name的字段会为null,而现在的没有此字段,更好看一点;
	List<Map<String.Object>> userList=userMapper.selectMaps(queryWrapper);
	userList.forEach(System.out::println);
  • 示例(图示):
    在这里插入图片描述
    在这里插入图片描述

  • selectObjs :只返回所有的第一列数据(第一个字段的值)
    在这里插入图片描述![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/e80ce16bfa93b88313587804946ddb59.jpeg)

  • selectCount : 查询总记录数 这里的就是count(1)
    在这里插入图片描述

  • selectOne: 查询返回一条信息(如果有多条会报错,只能容忍一条或者0条数据)
    在这里插入图片描述

2.4 Lambda条件过滤器

	//使用Lambda来写,会编译时检查User中的字段名是否正确
	@Test
	public void selectLambda(){
		//lambda的创建方式有三种,如下所示:
		//LambdaQueryWrapper<User> lambda =new QueryWrapper<User>().lambda;
		//LambdaQueryWrapper<User> lambdaQueryWrapper=new LambdaQueryWrapper<User>();
		//第三种:
		LambdaQueryWrapper<User> lambdaQuery=Wrappers.<User> lambdaQuery();
		lambdaQuery.like(User::getName,"雨").It(User::getAge,40);
		//where name like '%雨%'
		List<User> userList=userMapper.selectList(lambdaQuery);
		userList.forEach(System.out::println);
	}
  • 具体应用:
    在这里插入图片描述

  • 还有一种Lambda的创建方式

	@Test
	public void selectLambda3(){
		List<User> userList=new LambdaQueryChainWrapper<User>(userMapper)
		.like(User::getName,"雨").ge)(User::getAge,20).list();
		userList.forEach(System.out::println);
	}

2.5 使用条件构造器的自定义SQL 自定义方法

  • 版本必须大于等于3.0.7
  • 演示:
  • 在Mapper中进行修改 src/main/java/com/mp/dao/userMapper
	public interface UserMapper extends BaseMapper<User>{
	
		//使用SQL语句自定义条件    的方法
		@Select("select * from user ${ew.customSqlSegment}")
		List<User> selectAll(@Param(Constants.WRAPPER)Wrapper<User> wrapper);
	}
  • 对上面写的方法进行测试使用:
	@Test
	public void selectMy(){
		LambdaQueryWrapper<User> lambdaQuery =Wrappers<User> lambdaQuery();
		lambdaQuery.likeRight(User::getName,"王")
		.and(lqw->lqw.It(User::getAge,40).or().isNotNull(User::getEmail));
		List<User> userList=userMapper.selectAll(lambdaQuery);
		userList.forEach(System.out::println);
	}

生成的语句如下:
在这里插入图片描述

2.6 另外一种方式,写入XML的方式

  1. 在application.yml添加数据:
	mybatis-plus:
		mapper-locations:
			- com/mp/mapper/*		# 存放路径
  • 在src/main/java/com/mp/mapper/UserMapper.xml创建此xml并添加如下内容:
    在这里插入图片描述

  • 执行:
    在这里插入图片描述

三. 分页

3.1 基础分页

  • 原有分页弊端: 使用PageHelper 分页,会先查询出所有数据再返回分页的数据,当数据量很大的时候,会造成查询数据很慢,对服务器性能也有一定影响;
  • MP分页插件实现物理分页,操作如下:
    1. 添加插件:在src/main/java/com/mp/configuration/MybatisPlusConfig.java:
	@Configuration
	public class MyBatisPlusConfig{
		@Bean
		public PaginationInterceptor paginationInterceptor(){
			return new PaginationInterceptor();
		}
	}
2. 执行查询操作:
	@Test
	public void selectPage(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.ge("age",26);
		Page<User> page=new Page<User>(1,2);
		IPage<User> page= userMapper.selectPage(page,queryWrapper);
		System.out.println("总页数"+iPage.getPages());
		System.out.println("总记录数"+iPage.getTotal());
		List<User> userList=iPage.getRecords();
		userList.forEach(System.out::println);
	}
  • 查询语句图示效果:
    在这里插入图片描述

上面的返回是直接是数据,还有一种方法是返回Map类型的,返回的key为字段名,value为字段值,图示如下:

	@Test
	public void selectPage(){
		QueryWrapper<User> queryWrapper=new QueryWrapper<User>();
		queryWrapper.ge("age",26);
		Page<User> page=new Page<User>(1,2);
		IPag<Map<String,Object>> iPage=userMapper.selectMapsPage(page,queryWrapper);
		System.out.println("总页数"+iPage.getPages());
		System.out.println("总记录数"+iPage.getTotal());
	)}

需要用哪种根据需求而定; 有些场景中只需要查询记录不需要查询总记录数的,我们可以设置Page参数实现只查询一条语句; (平时是两条SQL语句,一条是查询总记录数,一条是查询具体数据的); 下面图示中的Page(long current,long size,boolean isSerchCount) 这个方法中第三个参数如果为false则不查询总记录数

在这里插入图片描述

3.2 注解类型的自定义分页和xml形式的自定义分页

  • 自定义分页操作流程:
    1. 在UserMapper中:
	public interface UserMapper extends BaseMapper<User>{
		IPage<User> selectUserPage(Page<User> page,@Param(Constants.WRAPPER)Wrapper<User> wrapper);
	}
2. XML的形式图示:

在这里插入图片描述

3. 测试:

在这里插入图片描述

里面演示的是单表的数据,如果需要多表查询的话,则sql语句进行对应的改变即可;

三. 更新update

3.1 根据Id进行更新

  • 代码图示:
    在这里插入图片描述
  • 生成语句:
    在这里插入图片描述

上面是根据ById来进行修改的,如果通过其他的条件来,我们可以使用下面的方式

在这里插入图片描述

  • 生成语句:
    在这里插入图片描述

如果在实体类参数和条件参数都有对一个属性进行定义,那么这两个地方的定义都生效; 在更新少量字段的时候,可以使用set 比如将年龄29改为30 ,图示如下:
在这里插入图片描述

3.2 Lambda方式

  • 图示:
    在这里插入图片描述

  • 链式Lambda条件构造器
    在这里插入图片描述

链式写法,返回的结果是影响记录数,如果为0则返回false;

四. 删除

4.1 内容:

- 根据id删除的方法
- 其他普通删除方法
- 以条件构造器为参数的删除方法

4.2 根据Id删除,图示:

在这里插入图片描述

4.3根据Map数据删除,图示:

在这里插入图片描述

4.4 删除一个或多个记录,

  • 图示效果:
    在这里插入图片描述
  • 图示操作:
    在这里插入图片描述

4.5 Lambda方式删除

在这里插入图片描述

五. AR模式、主键菜单和基本配置

5.1 AR探索

  • AR模式就是建立实体类与表之间的映射关联关系:
  1. 实体类必须继承Model
    在这里插入图片描述

  2. Mapper必须继承BaseMapper
    在这里插入图片描述

  3. 简单插入示例
    在这里插入图片描述

  4. 简单查询示例:
    在这里插入图片描述

  5. 查询和修改示例:
    在这里插入图片描述

  6. 删除示例:
    在这里插入图片描述

  7. 增加或者修改
    在这里插入图片描述

这条语句的含义是会先去查询数据库中是否有已经存在的记录,如果有的话则进行修改update操作,如果没有记录则进行insert 增加操作;

5.2 主键策略

  • 在新增数据的时候,如果该表的主键是自增策略,我们则可以在实体类中的id属性上添加@TablleId(type=IdType.AUTO) 自增,这样在添加的时候就不需要再手动给主键值了;同时MP里面内置了UUID,IdWorker 等全局主键Id生成方法,设置即可;ID_WORKER_STR则为String 类型 ,图示如下:
    在这里插入图片描述

5.3 全局主键策略设置

在这里插入图片描述

如果全局策略和局部策略都设置了,那么局部策略生效,它是优先于全局策略的;设置什么样的策略更为合适则最好是依据实际情况来进行判定;

5.4 配置

  • 内容:

    • 基本配置
    • 进阶配置
    • DB策略配置
  • 基本配置:

  • ConfigLocation:

  • 图示:
    在这里插入图片描述

  • 实际操作:

    1. 首先在application.yml中配置mybatis-config.xml文件路径
    2. 创建mybatis-config.xml文件
      在这里插入图片描述
  • mapperLocations

  • 图示:
    在这里插入图片描述

  • 实际操作:
    在这里插入图片描述

  • 注意:
    在这里插入图片描述

Maven 多模块项目的扫描路径需以classpath*: 开头(即加载多个jar包下的XML文件)
其他的配置可以找官网上有,这里提到的是经常用的;

5.5 进阶配置:

config-location与map-underscore-to-camel-case不能同时出现
在这里插入图片描述

  • dbType 数据库类型配置
  • 图示:
    在这里插入图片描述

这个可以不用配置,它可以根据url获取数据库的类型

  • fieldStrategy
  • 图示:
    在这里插入图片描述

这里有几种策略,比如忽略"" 空字符串,null,等;也可以对给默认null值等;需要使用的请单独详细了解;

  • table-prefix 表名前缀
    在这里插入图片描述
  • 在实体类中与数据库表名对应的注解可以不用加前缀,会默认加上

六. 通用Service

6.1 内容:

  • 基本方法
  • 批量操作方法
  • 链式调用方法

6.2 概述:

  • 使用通用Service,直接就可以使用查询方法,因为它里面已经写好了很多方法;
    在这里插入图片描述
  • 接口Service通过继承Iservice获得上面的方法,impl实现类通过继承ServiceImpl<Mapper参数,要操作的实体类> 并实现接口即可进行IService的方法调用,图示如下:

在这里插入图片描述

它里面的一些方法和通用Mapper的方法有些事不一样的,具体请直接进入源码查看

6.3 实际测试

在这里插入图片描述

  • 链式编程: 查询
    在这里插入图片描述
  • 链式编程: 修改
    在这里插入图片描述
  • 链式编程: 删除
    在这里插入图片描述
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暗余

码字来之不易,您的鼓励我的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值