欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Mybatis-Plus最優(yōu)化持久層開發(fā)過程

 更新時間:2024年07月12日 09:37:52   作者:二價亞鐵  
Mybatis-plus(簡稱MP)是一個Mybatis的增強工具,在mybatis的基礎(chǔ)上只做增強不做改變,提高效率,自動生成單表的CRUD功能,這篇文章主要介紹了Mybatis-Plus最優(yōu)化持久層開發(fā),需要的朋友可以參考下

一:Mybatis-plus快速入門:

1.1:簡介:

Mybatis-plus(簡稱MP)是一個Mybatis的增強工具,在mybatis的基礎(chǔ)上只做增強不做改變; 提高效率;
 自動生成單表的CRUD功能;
提供了豐富的條件拼接方式;
全自動ORM類型持久層框架;(不僅提供數(shù)據(jù)庫操作的方法,還會提供sql語句的實現(xiàn))

1.2:Mybatis-plus快速入門:

?。。。。。。。。。。。。。。。。。。。。。。。。。?!
如果我們想要對User表的數(shù)據(jù)進行單表CRUD:
  我們使用Mybatis-plus之后:我們只需要:
   1.創(chuàng)建mapper接口
   2.繼承 BaseMapper<User> (<>:要操作的表/實體類):我們就會擁有CRUD方法+CURD的sql語句
 
   注意:
   繼承的BaseMapper(它里面有單表的增刪改查方法),就不用寫mapper.xml文件了,
   之后就可以直接使用mapper對象調(diào)用相應的CRUD方法即可進行數(shù)據(jù)庫的操作了?。?!

Mapper接口

public interface UserMapper extends BaseMapper<User>{
    /*
    原來Mybatis中:我們需要在mapper中自定義方法,然后在mapper.xml中使用sql實現(xiàn)方法
    但是使用了Mybatis-plus之后,我們直接繼承 “BaseMapper<>”:它里面有單表的增刪改查各種方法以及實現(xiàn)
    我們繼承它以后就擁有了這些方法,就不用寫mapper.xml文件了;
     */
}

SpringBoot測試類

@SpringBootTest  //這個注解:就會自動完成ioc容器初始化,我們想要誰直接拿即可?。。。。。。。。。。。。。。。?!
public class SpringBootMybatisPlusTest {
    @Autowired
    private UserMapper userMapper; //拿到對象?。?!
    public void test(){
        List<User> users = userMapper.selectList(null); //不傳參數(shù):直接寫null:代表查詢?nèi)繑?shù)據(jù);
                           直接調(diào)用baseMapper接口中相應的方法即可
    }
}

二:Mybatis-plus的核心功能

Mybatis-plus是如何增強的

Mybatis-plus可以對三層架構(gòu)的兩層進行增強:
1.MapperC層:只要繼承,就擁有了crud方法
2.Service層:繼承

原理:?。。。。。。。?br />mapper接口只要繼承BaseMapper<實體類> 接口:
  接下來我們就能使用通過mapper對象和BaseMapper接口中提供的CRUD方法來對  實體類表 進行操作;

2.1:基于Mapper接口的CRUD

(1)mapper接口
		如果我們想要對User表的數(shù)據(jù)進行單表CRUD:
		  我們使用Mybatis-plus之后:我們只需要:
		   1.創(chuàng)建mapper接口
		   2.繼承 BaseMapper<User> (要操作的表/實體類):我們就會擁有CRUD方法+CURD的sql語句
		 */
		public interface Use rMapper extends BaseMapper<User> {
			//繼承之后:下面就相當于有了方法
		}
(2)測試類:
	@SpringBootTest
public class MybatisPlusTest {
	@Autowired
	private UserMapper userMapper;
	//(1)insert:
	@Test
	public void test(){
	   User user=new User();
	   user.setName("kun");
	   user.setAge(88);
	   user.setEmail("xxx");
	   //baseMapper提供的數(shù)據(jù)庫insert方法
		int row = userMapper.insert(user);
	}
	//(2)delete:
	@Test
	public void test_delete(){
		//1.根據(jù)id刪除:()內(nèi)裝值
		int rows = userMapper.deleteById(1687124323556002889L);
		//2.根據(jù)id刪除:age=20  name=jack; ()內(nèi)裝條件: -->拼接條件
		Map param=new HashMap();
		param.put("age",20);     //-->刪除age=20 + name=jack
		param.put("name","jack");
		int i = userMapper.deleteByMap(param);
		System.out.println("i = " + i);
		//wrapper 條件封裝對象,無限封裝條件;
		//userMapper.delete(wrapper)
	}
	//(3)Update()
	@Test
	public void test_update(){
		//1.將主鍵userId為1的age改為30:  ()內(nèi)裝值
		  //update user set age=30 where id=1:就等同于下方
		User user=new User();
		user.setId(1L);
		user.setAge(30);
		int i = userMapper.updateById(user);
		//2.將所有人age改為20
		User user1=new User();
		user1.setAge(20); //
		int update = userMapper.update(user1, null);// null:代表沒條件,該所有
		System.out.println("update = " + update);
		/*
		TODO:update:當屬性為null時:代表不修改
			 updateById():實體類的id必須有值
			 update() :實體類可以沒有id值
		 */
	}
	//(4)select a:根據(jù)主鍵查詢  b:根據(jù)主鍵集合查詢
	public void test_select(){
		//a:根據(jù)id查詢
		User user = userMapper.selectById(1);
		//b:根據(jù)集合查詢:eg:根據(jù)ids查詢
		List<Long> ids=new ArrayList<>();
		ids.add(1L);
		ids.add(2L);
		List<User> users = userMapper.selectBatchIds(ids); //selectBatchIds:批量ids
		System.out.println("users = " + users);
	}
}

2.2:就Service接口的CRUD

service接口繼承:

2.3:分頁查詢實現(xiàn):

Mybatis-plus實現(xiàn)分頁查詢:?。。?!
    使用步驟:
    1.導入分頁插件
    2.使用分頁查詢

-04
@SpringBootApplication
@MapperScan("com.atguigu.mapper")
/*
啟動類也是配置類:所以我們可以聲明帶@Bean的方法
1.配置一個分頁的插件:Mybatis-plus提供的,我們直接加進來使用就行了;
  在配置類/啟動類:中使用@Bean返回
 */
public class Main {
	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}
		@Bean
		//1.將Mybatis-plus插件加到ioc容器
		public MybatisPlusInterceptor plusInterceptor(){
			//a:是所有Mybatis-plus的插件集合:我們想要使用任何插件都可以加到這個集合中去;eg:我們可以將分頁插件加到里面;
			MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
			//b:加入分頁插件:
			mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
																						//指定數(shù)據(jù)庫
			return mybatisPlusInterceptor;
		}
}
/*
測試類:
2.之后就可以使用分頁插件了:
 */
@SpringBootTest
public class MybatisPlusTest {
	@Autowired
	private UserMapper userMapper; //注入UserMapper對象:進行數(shù)據(jù)庫操作
	@Test
	public void testPage(){
		//a:創(chuàng)建Page對象: 參數(shù)解釋:(參數(shù)1:頁碼, 參數(shù)2:頁容量)
		Page<User> page=new Page<>(1,3);
		userMapper.selectPage(page,null); //需要放入Page對象
		//最后分頁的結(jié)果也會被封裝到page里面:-->所以直接通過page對象獲取結(jié)果即可
		long pages = page.getPages();
		long current = page.getCurrent(); //獲取當前頁碼、
		List<User> records = page.getRecords(); //獲取當前頁數(shù)據(jù)
		long total = page.getTotal();//獲取總條數(shù)
	}
}

自定義mapper方法使用分頁

上面:我們是使用Mybatis提供的方法:  userMapper.selectPage(page,null);
如果我們自定義的mapper方法想要使用分頁查詢:
   1.在mapper接口中定義方法:
       自定義方法想要分頁:在第一個參數(shù)加一個IPage對象,返回值也是IPage
   2.在mapper文件中實現(xiàn):使用sql語句實現(xiàn):不要加limit和;
   3.測試

public interface UserMapper extends BaseMapper<User> {
	//繼承BaseMapper接口:里面有單表的方法
	/*
	演示:自定義mapper方法實現(xiàn)分頁:
	  eg:查詢
	 */
	//1.在mapper接口中定義抽象方法:但是:方法的第一個參數(shù):要傳一個IPage,返回值要是IPage,里面寫查詢集合的泛型即可
   IPage<User> queryByAge(IPage<User>page, @Param("age") Integer age);
}
2.
	<!--2.使用sql語句實現(xiàn)UserMapper接口的方法:不用在最后加limit,!-->
	<select id="queryByAge" resultType="com.atguigu.pojo.User"> <!--resultType:泛型-->
		select * from user where age>#{age}
	</select>
 3.
		 /*
	 3.測試自定義方法分頁
	  */
	public void test_MyPage(){
		//a:傳一個分頁插件的值:
		Page<User> page=new Page<>(1,3);
		//b.
		userMapper.queryByAge(page,1);
		//c:
		//最后分頁的結(jié)果也會被封裝到page里面:-->所以直接通過page對象獲取結(jié)果即可
		long pages = page.getPages();
		long current = page.getCurrent(); //獲取當前頁碼、
		List<User> records = page.getRecords(); //獲取當前頁數(shù)據(jù)
		long total = page.getTotal();//獲取總條數(shù)
		System.out.println("total:"+total);
	}
}

2.4:條件構(gòu)造器使用:

2.4.1條件構(gòu)造器的作用:

warpper對象:動態(tài)進行 條件的拼接;

就相當于在sql語句后面加條件,只是使用java代碼的格式;

---->:就不用在mapper.xml文件中使用sql語句實現(xiàn)了,直接使用java代碼來代替sql語句;!?。。。。。?!

warpper對象:動態(tài)進行 條件的拼接;
就相當于在sql語句后面加條件,只是使用java代碼的格式;
---->:就不用在mapper.xml文件中使用sql語句實現(xiàn)了,直接使用java代碼來代替sql語句;?。。。。。。?!

2.4.2條件構(gòu)造器的類結(jié)構(gòu):

一般使用:
   第一種: UpdateWrapper(修改)、QueryWrapper(刪除、查詢、修改)
   第二種: LambdaUpdateWrapper(修改)、 LambdaQueryWrapper(刪除、查詢、修改)

(1)第一種:基于queryWrapper組裝條件:增/刪/改

使用方法:
     1.在mapper接口中定義方法,并繼承base接口(提供了各種方法的實現(xiàn))
     2.直接使用java代碼實現(xiàn):不需要在mapper.xml文件中實現(xiàn)了
     //a:創(chuàng)建QueryWrapper
  	QueryWrapper<實體類>queryWrapper=new QueryWrapper<>();
  	//b:條件拼接:調(diào)用queryWrapper方法
  	//c:使用mappper對象:調(diào)用CRUD方法,傳入對象即可
1.mapper接口:
public interface UserMapper extends BaseMapper<User> {
	//繼承BaseMapper接口:里面有單表的方法
	/*
	演示:自定義mapper方法實現(xiàn)分頁:
	  eg:查詢
	 */
	//1.在mapper接口中定義抽象方法:但是:方法的第一個參數(shù):要傳一個IPage,返回值要是IPage,里面寫查詢集合的泛型即可
   IPage<User> queryByAge(IPage<User>page, @Param("age") Integer age);
}
2.
/*
演示條件構(gòu)造器使用:進行條件的動態(tài)拼接:
(1)QueryWrapper測試:
 */
@SpringBootTest
public class MybatisPlusQueryWrapper {
	@Autowired
	private UserMapper userMapper; //拿到對象:操作數(shù)據(jù)庫
	@Test
	public void test_01(){
		//查詢用戶名包含 a,age在20到30之間的,且郵箱不為空的用戶;
		 //分析:查詢:返回的是集合List-->selectList
		//a:創(chuàng)建一個QueryWrapper集合:相當于容器來裝條件
		QueryWrapper<User> queryWrapper=new QueryWrapper<>();
		//b:之后sql語句的條件:直接使用queryWrapper動態(tài)調(diào)用wrapper的方法來完成動態(tài)拼接;
		queryWrapper.like("name","a"); //條件1:name種包含a的
		queryWrapper.between("age",20,30); //條件2:age在20-30之間
		queryWrapper.isNotNull("email"); //第三個條件:email不為null
		List<User> users = userMapper.selectList(queryWrapper);  ----->:因為繼承了base接口,所以單表直接調(diào)用方法即可!
		//queryWrapper就是sql條件,將它·傳進去!?。?
		//之后這個就會變成sql語句; ?。。。。。。。。。。?
		//就相當于:select  * from user where name(like %a% and age>=20 and age<=30 and email is not null)
		/*
		!!!一個個調(diào)用麻煩,可以使用鏈式調(diào)用:?。。?!
		 queryWrapper.like("name","a").between("age",20,30).isNotNull("email");
		 */
	}
}
@SpringBootTest
	public class MybatisPlusQueryWrapper {
		@Autowired
		private UserMapper userMapper; //拿到對象:操作數(shù)據(jù)庫按照年齡降序查詢用戶,如果年齡age相同則按id升序排列
		 //(2)queryWrapper:按年齡降序查詢用戶,如果年齡相同則按id升序排列
		@Test
		public void test_02(){
			//a:創(chuàng)建QueryMapper集合:裝條件
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:使用條件構(gòu)造器進行條件的拼接:
			queryWrapper.orderByDesc("age").orderByAsc("id");
								//a:條件1:age降序排列; b:條件2:id增序
			//c:放到queryWrapper中,進行條件拼接; ==order by age desc,id asc
			List<User> users = userMapper.selectList(queryWrapper);
		}
		//(3)刪除email為null的用戶
		@Test
		public void test_03(){
			//a:
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:
			queryWrapper.isNotNull("email");
			//c:
			int delete = userMapper.delete(queryWrapper);
		}
		//(4):將age>20且用戶名中包含a或email為null的用戶信息修改:
		  //分析:修改:--update:所以usermapper調(diào)用update方法
				:相應的條件:age>20... 使用queryWrapper封裝,然后作為條件放入update方法形參中;!!!!!
		@Test
		public void test_04(){
			//a:
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:添加條件:
			queryWrapper.gt("age",20).like("name","a")                ---------->B:相當于:where .......
					.or().isNotNull("email");
			   //1.條件:age>20 name包含a,--->:條件直接調(diào)用時:默認自動使用and進行拼接;?。。。?!
				  //queryWrapper.gt("age",20).like("name","a") == where age>20 and ..      
			   //2.如果想要在條件之后追加or關(guān)鍵字:可以使用: “or().條件”;
			//c:創(chuàng)建User對象,進行update修改
			User user=new User();
			user.setAge(88);                ----->A:相當于update user  set name="" age= 
			user.setEmail("hehe");
			//d:如果要修改:第一位傳入要修改的對象
			 userMapper.update(user, queryWrapper); //放入對象 + queryWrapper
		}
		//(5):查詢用戶信息的name和age字段;  --->指定列查詢?。?!
		  //select name,age from t_user where id>1;
		public void test_05() {
			//a:
			QueryWrapper<User> queryWrapper = new QueryWrapper<>();
			//b:條件拼接:
			queryWrapper.gt("age",1);
			//!!!查詢時:默認是查詢?nèi)???!?。。?!,但可以使用select指定
			queryWrapper.select("name","age");
			userMapper.selectList(queryWrapper);
		}
		//(6)前端傳入兩個參數(shù),name,age:---->:動態(tài)條件組織判斷?。。?!
		// 只要name不為null,就作為條件 來查詢符合的
		//只要age>18作為條件,就作為條件 來查詢符合的
		@Test
		public void test_06(){
			String name="xx";
			Integer age=19;
			//a:
			QueryWrapper<User>queryWrapper=new QueryWrapper<>();
			//b:進行條件拼接:
			  //b.1:如果name!=null,就使用queryWrapper進行條件拼接
			if(StringUtils.isNotBlank(name)){  //調(diào)用isNotBlank進行判斷
				//動態(tài)條件判斷:如果name不為null,就進行條件的拼接
				queryWrapper.eq("name",name); //使用queryWrapper進行拼接
			}
			  //b.2:如果age>18 進行動態(tài)拼接:
			if (age>18 && age!=null){
				queryWrapper.eq("age",age);
			}
			userMapper.selectList(queryWrapper);
			 /*
		注意:!!!!!!!!!!!!!!!!
		  Wrapper每個方法都有:一個boolean類型的condition,允許我們第一個參數(shù)放一個比較表達式,
		  :如果condition為true-->整個條件為true,就執(zhí)行下面代碼
		  :如果condition為false-->整個條件為false,就失效,不執(zhí)行下面代碼
		  -->condition里面有動態(tài)判斷,就不用我們在外部寫判斷了
		  eg:
		 */
			queryWrapper.eq(StringUtils.isNotBlank(name),"name",name);
			queryWrapper.eq(age>18 && age!=null,"age",age);
		}

(2)queryWrapper實戰(zhàn)使用:

@SpringBootTest
	public class MybatisPlusQueryWrapper {
		@Autowired
		private UserMapper userMapper; //拿到對象:操作數(shù)據(jù)庫按照年齡降序查詢用戶,如果年齡age相同則按id升序排列
		 //(2)queryWrapper:按年齡降序查詢用戶,如果年齡相同則按id升序排列
		@Test
		public void test_02(){
			//a:創(chuàng)建QueryMapper集合:裝條件
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:使用條件構(gòu)造器進行條件的拼接:
			queryWrapper.orderByDesc("age").orderByAsc("id");
								//a:條件1:age降序排列; b:條件2:id增序
			//c:放到queryWrapper中,進行條件拼接; ==order by age desc,id asc
			List<User> users = userMapper.selectList(queryWrapper);
		}
		//(3)刪除email為null的用戶
		@Test
		public void test_03(){
			//a:
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:
			queryWrapper.isNotNull("email");
			//c:
			int delete = userMapper.delete(queryWrapper);
		}
		//(4):將age>20且用戶名中包含a或email為null的用戶信息修改:
		  //分析:修改:--update:所以usermapper調(diào)用update方法
				:相應的條件:age>20... 使用queryWrapper封裝,然后作為條件放入update方法形參中;!!!!!
		@Test
		public void test_04(){
			//a:
			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
			//b:添加條件:
			queryWrapper.gt("age",20).like("name","a")                ---------->B:相當于:where .......
					.or().isNotNull("email");
			   //1.條件:age>20 name包含a,--->:條件直接調(diào)用時:默認自動使用and進行拼接;!?。。?!
				  //queryWrapper.gt("age",20).like("name","a") == where age>20 and ..      
			   //2.如果想要在條件之后追加or關(guān)鍵字:可以使用: “or().條件”;
			//c:創(chuàng)建User對象,進行update修改
			User user=new User();
			user.setAge(88);                ----->A:相當于update user  set name="" age= 
			user.setEmail("hehe");
			//d:如果要修改:第一位傳入要修改的對象
			 userMapper.update(user, queryWrapper); //放入對象 + queryWrapper
		}
		//(5):查詢用戶信息的name和age字段;  --->指定列查詢?。?!
		  //select name,age from t_user where id>1;
		public void test_05() {
			//a:
			QueryWrapper<User> queryWrapper = new QueryWrapper<>();
			//b:條件拼接:
			queryWrapper.gt("age",1);
			//!!!查詢時:默認是查詢?nèi)????。。。?!,但可以使用select指定
			queryWrapper.select("name","age");
			userMapper.selectList(queryWrapper);
		}
		//(6)前端傳入兩個參數(shù),name,age:---->:動態(tài)條件組織判斷?。。?!
		// 只要name不為null,就作為條件 來查詢符合的
		//只要age>18作為條件,就作為條件 來查詢符合的
		@Test
		public void test_06(){
			String name="xx";
			Integer age=19;
			//a:
			QueryWrapper<User>queryWrapper=new QueryWrapper<>();
			//b:進行條件拼接:
			  //b.1:如果name!=null,就使用queryWrapper進行條件拼接
			if(StringUtils.isNotBlank(name)){  //調(diào)用isNotBlank進行判斷
				//動態(tài)條件判斷:如果name不為null,就進行條件的拼接
				queryWrapper.eq("name",name); //使用queryWrapper進行拼接
			}
			  //b.2:如果age>18 進行動態(tài)拼接:
			if (age>18 && age!=null){
				queryWrapper.eq("age",age);
			}
			userMapper.selectList(queryWrapper);
			 /*
		注意:!!!!!!!!!!!!!!!!
		  Wrapper每個方法都有:一個boolean類型的condition,允許我們第一個參數(shù)放一個比較表達式,
		  :如果condition為true-->整個條件為true,就執(zhí)行下面代碼
		  :如果condition為false-->整個條件為false,就失效,不執(zhí)行下面代碼
		  -->condition里面有動態(tài)判斷,就不用我們在外部寫判斷了
		  eg:
		 */
			queryWrapper.eq(StringUtils.isNotBlank(name),"name",name);
			queryWrapper.eq(age>18 && age!=null,"age",age);
		}

updateWrapper:改

進行修改時:使用updateWrapper:?。。?!

     //a:
    UpdateWrapper<User> queryWrapper=new UpdateWrapper<>();
     //b:
    queryWrapper.gt("age",20).like("name","a").isNotNull("email")
            .set("email",null).set("age",100);
     //c:
   userMapper.update(null,queryWrapper);

在修改時updateWrapper和queryWrapper區(qū)別:

(參數(shù)1:條件; 參數(shù)2:修改的數(shù)據(jù))
queryWrapper修改:參數(shù)1只能放條件,且列名不能為null
updateWrapper修改:參數(shù)1可以放條件, 且列名可以設(shè)置為null;
				   且可以直接調(diào)用set方法進行修改

(2)第二種:

  和第一種用法一樣,只是對第一種的增強
   eg:
    Lambda:避免列寫錯的機制:傳入的列名可以是” 方法引用的表達式 “:類名::getName -->相當于找方法對應的列名

LambdaQueryWrapper:增/刪/改

eg:
查詢用戶名包含 a like,年齡在20-30之間,并且郵箱不為null的用戶信息;
		LambdaQueryWrapper<User>lambdaQueryWrapper=new LambdaQueryWrapper<>();
		 //即只要將原來的列名,變?yōu)長ambda方法引用即可,其余不變?。。。。。。。。?!
		 lambdaQueryWrapper.like(User::getName,"a").between(User::getAge,20,30).isNotNull(User::getEmail);
		userMapper.selectList(queryWrapper);

LambdaupdateWrapper:改

eg:
		LambdaUpdateWrapper<User>lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
		//即只要將原來的列名,變?yōu)長ambda方法引用即可,其余不變?。。。。。。。。?!
		lambdaUpdateWrapper.gt(User::getAge,20).like(User::getName,"a").isNotNull(User::getEmail)
				.set(User::getEmail,null).set(User::getAge,100);
		userMapper.update(null,lambdaUpdateWrapper);

(3)總結(jié):

Wrapper:里面:完成了動態(tài)條件封裝
最終推薦使用Lambda;(不用寫列名,只需類名::方法即可)
 
如果復雜的sql:qg:嵌套、子查詢 不會使用Wrapper怎么辦:
 我們?nèi)匀皇褂迷瓉淼模憾xmapper
      如果為單表的話:直接使用mapper對象調(diào)用CRUD方法即可;
      如果為多表的話:在mapper.xml文件中實現(xiàn);

2.5Mybatis-plus核心注解的使用:

注解的作用:指定實體類和表之間的映射;

1.@TableName

作用:指定數(shù)據(jù)庫表名;(當【BaseMapper<實體類>】 實體類名 和 數(shù)據(jù)庫表名不同時);
使用:@TableName("數(shù)據(jù)庫表名")
 
a:位置:加到實體類上
b:可以不加,不加的話默認使用實體類的名字作為 表名! 忽略大小寫;  
   eg:BaseMapper<User>:默認將實體類名:User,作為表名 來進行操作;
 
c:使用@TableName注解場景:
   當數(shù)據(jù)庫的表名和實體類名稱不同時(忽略大小寫),需要使用@TableName來指定 表名:
    eg:數(shù)據(jù)庫名:t_user;  實體類名:User
        兩個名稱不同,此時我們需要在實體類上方使用: ”@TableName("t_user")“ 來指定表名;
d: 如果表名命名規(guī)范:eg:都以 "t_"開頭,且除了”t_“以外,實體類名=表名
   我們可以將前綴統(tǒng)一提取到配置文件中(application.yml),這樣就不需要每個實體類都加@TableName注解來指定表名了
   它會自動查找相應的表;
    mybatis-plus:
       global-config:
            db-config:
              table-prefix: t_ #表名前綴;
                            #加了這個之后,我們就不需要在每個實體類加@TableName注解了,它就會自己根據(jù)前綴"t_"進行查找;
                            #前提:數(shù)據(jù)庫的表都是以 “t_”開頭的

2.@TableId:

作用:描述主鍵的一些特性; 
   eg: value:指定表主鍵名;  type:設(shè)置主鍵type策略
使用:在實體類的主鍵屬性上:+@TableId(value="主鍵列名",type="主鍵策略");
 
b:位置:加到實體類的主鍵屬性上
c:使用@TableId的場景:
      場景1:
         表 主鍵的列名 和 實體類的屬性名 不一致時,使用這個注解來指定表的列名;!!!
              eg: 1:如果 實體類屬性名:id; 數(shù)據(jù)庫主鍵列名:x_id; --->兩個名稱不一樣,我們可以在實體類主鍵的屬性上方加
              @TableId(value="x_id") 
       場景2:
          設(shè)置表主鍵增長:
             type主鍵策略:

type增長策略:

@SpringBootTest
public class MybatisPlusTableIdTest {
	@Autowired
	private UserMapper userMapper;
	@Test
	public  void test_01(){
		//以插入數(shù)據(jù)舉例:
		User user=new User();
		user.setName("坤坤");
		user.setAge(20);
		user.setEmail("xxx@qq.com");
		//插入的時候:主鍵id不要賦值; 主鍵自增長 或者 type策略 進行賦值?。。。。。。。。。。?!
		/*
		1.默認主鍵的type(策略)是:雪花算法;--->:它會生成一個不重復的long類型的數(shù)字; eg:123456789
			雪花算法:
			  a:要求數(shù)據(jù)庫主鍵是 bigint / varchar(64) 類型;         -->:eg:varchar(64)/bigint money;!!!
			  b:要求實體類相應屬性:使用Long/String接值(int接不到)  -->:eg:Long/String  money;!!!
			  c:隨機生成一個數(shù)字,給予主鍵值(不重復)
		2.但我們想要把主鍵type(策略)變成auto自增長,
		   方式1:直接在實體類的主鍵上方加:@TableId(type= IdType.AUTO); 前提是mysql數(shù)據(jù)庫必須設(shè)置了主鍵自增長(auto_increment)
			auto:
			  a:要求mysql數(shù)據(jù)庫的 表主鍵 必須設(shè)置了 自增長
			  b:插入數(shù)據(jù)就是自增長了
		   方式2:全局設(shè)置主鍵自增長策略:如果每個表都設(shè)置為自增長(auto),在配置文件(application.yml)中配置
		 */
		userMapper.insert(user); //之間調(diào)用BaseMapper中的insert方法;
	}
}
User視圖類:
 public class User(){
	@TableId(type = IdType.AUTO)
	private Long id;   
 }

3.@TableFiled

作用:描述非主鍵字段
使用:在實體類的非主鍵字段上:+@TableFiled(value="",exist="")
 
a:使用場景1:value="" (不是必須指定的,String類型)
    :當實體類的屬性名 和 列名 不同的時候 使用@TableFiled指定數(shù)據(jù)庫表名;
   使用場景2:esist=ture/false; (默認為true)
     :eg:@TableFiled(value="name",exist=false):
           private String name;
         -->:false代表:認為name沒有數(shù)據(jù)庫對應的列,因此在查詢等時候不會對他進行操作;

三:Mybatis-plus高級擴展

3.1邏輯刪除實現(xiàn):

(1)邏輯刪除概念:
邏輯刪除:是 "假刪除數(shù)據(jù)":是將想要刪除數(shù)據(jù)的狀態(tài)修改為 "被刪除狀態(tài)",但是數(shù)據(jù)并沒有消失,之后在查詢時,查詢沒有 刪除狀態(tài) 的數(shù)據(jù),也是一種刪除;
物理刪除:delete from:刪除之后就沒有了相應的數(shù)據(jù);
(2)邏輯刪除的實現(xiàn):
    方式1:單個表邏輯刪除的實現(xiàn):
      a:在數(shù)據(jù)庫表中 插入一個邏輯刪除字段(int類型,有1/0狀態(tài)字段!):
         alert table User add deleted int default 1/0; -->: 1/0:邏輯刪除的狀態(tài)字段:1代表:邏輯刪除; 0代表:未邏輯刪        除;!!!!
      b:在實體類的對應屬性上加:@TableLogic
         eg:
                @TableLogic //代表這個屬性對應的列是 :邏輯刪除狀態(tài)字段
                //當我們刪除數(shù)據(jù)時候,自動變成修改此列的屬性值(即將deleted變?yōu)?);   默認:0是未刪除,1是刪除
                //當我們查詢數(shù)據(jù)時候:默認只查詢 deleted=0 的列的數(shù)據(jù)
                private Integer deleted;
   方式2:多個表邏輯刪除的實現(xiàn)(全局指定):
      a:同上
      b:在配置文件(application.yml)中:配置
        mybatis-plus:
          global-config:
            db-config:
              logic-delete-field: deleted # 全局邏輯刪除的實體屬性名

       注意:這種就不需要在類的屬性名上 + @TableLogic了
             但是仍然需要在實體類中創(chuàng)建一個和列名deleted 對應的屬性名;

代碼演示:

以單個表實現(xiàn)邏輯刪除為例:
 @TableLogic
 private Integer deleted;
@SpringBootTest
public class MybatisPlusTableLogicTest {
	@Autowired
	private UserMapper userMapper;
	public void test_01(){
		//a:之前是物理刪除:delete from user where id=5;
		//b:現(xiàn)在:邏輯刪除:相當于:update user set deleted=1 where id=5
		userMapper.deleteById(5);
		//eg:
		userMapper.selectList(null); -->之后在查詢時:就只會查詢deleted=0的了:?。。。。。ㄗ詣釉跅l件位置加上where deleted=0)
	}

3.2樂觀鎖的實現(xiàn)

1.樂觀鎖 和悲觀鎖 都是在 并發(fā)編程 中用于處理并發(fā)訪問和資源競爭的兩種不同機制;
2.(1)悲觀鎖:
	同步鎖/互斥鎖:線程在訪問共享資源之前會獲取到鎖,在數(shù)據(jù)訪問時只允許一個線程訪問資源,只有當前線程訪問完成只后,才會釋放鎖,讓其它線程繼續(xù)操作資源;
  (2)樂觀鎖:不需要提前加鎖,而是在數(shù)據(jù)更新階段進行檢測
   樂觀鎖和悲觀鎖是兩種解決并發(fā)數(shù)據(jù)問題的思路,不是技術(shù)?。?
3.具體的技術(shù)和方案:
	  1.樂觀鎖實現(xiàn)方案和技術(shù)
		版本號/時間戳
		CAS
		無鎖數(shù)據(jù)結(jié)構(gòu)
	  2.悲觀鎖的實現(xiàn)方案和技術(shù)
		 鎖機制
		 數(shù)據(jù)庫鎖
		 信號量
4. 現(xiàn)在主要學習如何使用樂觀鎖(版本號)解決并發(fā)問題?。。。。?!
	  (1)版本號:解決數(shù)據(jù)并發(fā)更新出現(xiàn)錯誤數(shù)據(jù)的問題;--->保證數(shù)據(jù)一致性;
	  (2)樂觀鎖技術(shù)的實現(xiàn)流程:
		  a:每條數(shù)據(jù)添加一個版本號字段version
		  b:取出記錄時,獲取當前version
		  c:更新時,檢查獲取版本號是不是數(shù)據(jù)庫當前最新版本號
		  d:如果是(代表沒人修改過數(shù)據(jù)),執(zhí)行更新:set數(shù)據(jù)更新,version=version+1
		  e:如果不是(證明已經(jīng)修改過了),更新失敗
5.使用mybatis-plus數(shù)據(jù)使用樂觀鎖
	   步驟: 
		  1.數(shù)據(jù)庫插入一個version字段:alert table user add version int default 1  (int類型 樂觀鎖字段)
		  2 實體類創(chuàng)建相應的屬性: private Integer version;  + 在屬性上方使用@Version注解
		  3.添加攔截器(添加版本號更新插件)
		   之后在更新的時候就會檢查版本,檢查數(shù)據(jù)錯誤的問題;

樂觀鎖測試:

1.
 alter  table user add version int default 1;  #int 類型 樂觀鎖字段
2.
public class User {
	@Version
	private Integer version; //版本號字段
}
//注意:之后在數(shù)據(jù)修改時都會檢查樂觀鎖;
3.在配置類/Main類中加入攔截器
public class Main {
	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}
		@Bean
		public MybatisPlusInterceptor plusInterceptor(){
			//攔截器2:樂觀鎖【版本號插件】 mybatis-plus在每次更新時候,每次幫我們對比版本號字段和增加版本號+1
			   mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
			return mybatisPlusInterceptor;
		}
4.
/*
測試樂觀鎖實現(xiàn)
 */
@SpringBootTest
public class MybatisPlusVersionTest {
	private UserMapper userMapper;
	@Test
	public void testById(){
		//步驟1:先查詢,再更新 獲取version數(shù)據(jù)
		//同時查詢兩條,但是version唯一,最后更新的失敗、
		User user=new User();  //user 版本號為:1
		User user1=new User(); //user1 版本號為:1
		user.setAge(20);
		user.setAge(30);
		userMapper.updateById(user); //20-->:此時數(shù)據(jù)庫的version ->2
		//樂觀鎖生效:失敗
		userMapper.updateById(user1);
		//因為user1的版本號為1,但是數(shù)據(jù)庫的版本號為2,證明不是最新數(shù)據(jù) -->1!=2,樂觀鎖生效,更新失敗
		  //所以最終age為:20
	}
}

3.3防止全表更新和刪除

在開發(fā)中一般不會出現(xiàn)全表的更新/刪除:
  Mybatis-plus提供一種防御插件:一旦檢測到是全表的update/delete:就會報異常;
實現(xiàn)方法:添加防止全表更新和刪除的攔截器:

代碼測試:

1.加入攔截器/插件:
public class Main {
	public static void main(String[] args) {
		SpringApplication.run(Main.class, args);
	}
		@Bean
		public MybatisPlusInterceptor plusInterceptor(){
		  //攔截器3:防止全表刪除和更新的攔截器
			mybatisPlusInterceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
			return mybatisPlusInterceptor;
		}
 2.測試類中:
	 public void test(){
	 @Au..
	 private UserMapper userMapper; //拿到mapper對象,進行數(shù)據(jù)庫操作?。?!;
	 //a:全表刪除!
	 mapper.delete(null); ----->:null,代表沒有寫條件,代表:全表刪除;
	 //b:全表更新:
	 mapper.update(null); ------>: null,代表沒有條件,代表全表更新!
	 ----------->:之后就會拋出異常:不允許全表delete/update?。。。。。?!
 }

四:Mybatis-Plus代碼生成器(MybatisX插件)!!!!!!!!!!!!!

學習目標:
1.如何使用MybatisX插件: 逆向工程 生成Mybatis-Plus代碼;
    //逆向工程:根據(jù)表自動生成實體類、mapper、service;!!!!!!!!!!!!!!!!!!!!!!
2. 使用MybatisX插件 動態(tài)生成自定義的sql語句

4.1Mybatis插件逆向工程

//逆向工程:根據(jù)表自動生成實體類、mapper、service;!!!!!!!!!!!!!!!!!!!!!!
步驟:
    連接數(shù)據(jù)庫;
    .....

4.2Mybatis-plus快速生成單表CRUD代碼(自定義sql)?。。。。。。。?/h3>
如果我們需要自己定義一些sql語句:
  eg:批量查詢、根據(jù)id查詢......
//步驟:
	  1.直接在mapper接口中書寫相應的 ” 方法名 “ (//按照mybatisX的方法命名規(guī)則)
		eg:批量插入:insertBatch
			根據(jù)條件查詢:selectByNameAndAgeAndAge
	  2.然后鼠標放在方法名上,點擊MybatisX,
		--->MybatisX 就會在mapper接口自動寫好 且 在mapper.xml文件中自動生成sql語句!?。。。。。?!
//之后有關(guān)單表的CRUD我們就不需要自己寫了!?。。。。。。。?!
//我們可以看mybatisX的官方文檔:介紹了如何寫

到此這篇關(guān)于Mybatis-Plus最優(yōu)化持久層開發(fā)的文章就介紹到這了,更多相關(guān)Mybatis-Plus持久層開發(fā)內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Springboot創(chuàng)建子父工程過程圖解

    Springboot創(chuàng)建子父工程過程圖解

    這篇文章主要介紹了Springboot創(chuàng)建子父工程過程圖解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2020-02-02
  • MyBatis中映射文件的使用案例代碼

    MyBatis中映射文件的使用案例代碼

    這篇文章主要介紹了MyBatis中映射文件的使用,本文結(jié)合實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2023-02-02
  • Java 淺談 高并發(fā) 處理方案詳解

    Java 淺談 高并發(fā) 處理方案詳解

    這篇文章主要介紹了淺談Java高并發(fā)解決方案以及高負載優(yōu)化方法,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2021-09-09
  • Java實現(xiàn)的傅里葉變化算法示例

    Java實現(xiàn)的傅里葉變化算法示例

    這篇文章主要介紹了Java實現(xiàn)的傅里葉變化算法,結(jié)合具體實例形式分析了基于Java的傅里葉變化算法定義與使用相關(guān)操作技巧,需要的朋友可以參考下
    2018-06-06
  • Java Fluent Mybatis實戰(zhàn)之構(gòu)建項目與代碼生成篇下

    Java Fluent Mybatis實戰(zhàn)之構(gòu)建項目與代碼生成篇下

    Java中常用的ORM框架主要是mybatis, hibernate, JPA等框架。國內(nèi)又以Mybatis用的多,基于mybatis上的增強框架,又有mybatis plus和TK mybatis等。今天我們介紹一個新的mybatis增強框架 fluent mybatis
    2021-10-10
  • SpringCloud超詳細講解負載均衡組件Ribbon源碼

    SpringCloud超詳細講解負載均衡組件Ribbon源碼

    在微服務中,對服務進行拆分之后,必然會帶來微服務之間的通信需求,而每個微服務為了保證高可用性,又會去部署集群,那么面對一個集群微服務進行通信的時候,如何進行負載均衡也是必然需要考慮的問題
    2022-07-07
  • 基于UDP協(xié)議實現(xiàn)聊天系統(tǒng)

    基于UDP協(xié)議實現(xiàn)聊天系統(tǒng)

    這篇文章主要為大家詳細介紹了基于UDP協(xié)議實現(xiàn)聊天系統(tǒng),文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • springboot 定時任務@Scheduled實現(xiàn)解析

    springboot 定時任務@Scheduled實現(xiàn)解析

    這篇文章主要介紹了springboot 定時任務@Scheduled實現(xiàn)解析,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-09-09
  • Springboot工具類FileCopyUtils使用教程

    Springboot工具類FileCopyUtils使用教程

    這篇文章主要介紹了Springboot內(nèi)置的工具類之FileCopyUtils的使用,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習吧
    2022-12-12
  • Java中Set與List的關(guān)系與區(qū)別介紹

    Java中Set與List的關(guān)系與區(qū)別介紹

    這篇文章主要介紹了Java中Set與List的關(guān)系與區(qū)別介紹,本文總結(jié)它們兩個接口都是繼承自Collection、它們之間的存儲方式不一樣,需要的朋友可以參考下
    2015-03-03

最新評論