<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Mybatis-Plus最優化持久層開發

      Mybatis-plus:最優化持久層開發

      一:Mybatis-plus快速入門:

      1.1:簡介:

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

      1.2:Mybatis-plus快速入門:

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

      Mapper接口

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

      SpringBoot測試類

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

      二:Mybatis-plus的核心功能

      Mybatis-plus是如何增強的

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

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

      2.1:基于Mapper接口的CRUD

      (1)mapper接口
      
      		如果我們想要對User表的數據進行單表CRUD:
      		  我們使用Mybatis-plus之后:我們只需要:
      		   1.創建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提供的數據庫insert方法
      		int row = userMapper.insert(user);
      	}
      
      	//(2)delete:
      	@Test
      	public void test_delete(){
      		//1.根據id刪除:()內裝值
      		int rows = userMapper.deleteById(1687124323556002889L);
      
      		//2.根據id刪除:age=20  name=jack; ()內裝條件: -->拼接條件
      		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:  ()內裝值
      		  //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:根據主鍵查詢  b:根據主鍵集合查詢
      	public void test_select(){
      		//a:根據id查詢
      		User user = userMapper.selectById(1);
      		//b:根據集合查詢:eg:根據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:分頁查詢實現:

      Mybatis-plus實現分頁查詢:!!!!
      	使用步驟:
      	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));
      																						//指定數據庫
      			return mybatisPlusInterceptor;
      		}
      }
      
      
      
      /*
      測試類:
      2.之后就可以使用分頁插件了:
       */
      @SpringBootTest
      public class MybatisPlusTest {
      	@Autowired
      	private UserMapper userMapper; //注入UserMapper對象:進行數據庫操作
      
      	@Test
      	public void testPage(){
      
      		//a:創建Page對象: 參數解釋:(參數1:頁碼, 參數2:頁容量)
      		Page<User> page=new Page<>(1,3);
      
      		userMapper.selectPage(page,null); //需要放入Page對象
      
      		//最后分頁的結果也會被封裝到page里面:-->所以直接通過page對象獲取結果即可
      		long pages = page.getPages();
      		long current = page.getCurrent(); //獲取當前頁碼、
      		List<User> records = page.getRecords(); //獲取當前頁數據
      		long total = page.getTotal();//獲取總條數
      
      	}
      
      }
      

      自定義mapper方法使用分頁

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

      1.
      
      public interface UserMapper extends BaseMapper<User> {
      	//繼承BaseMapper接口:里面有單表的方法
      
      	/*
      	演示:自定義mapper方法實現分頁:
      	  eg:查詢
      
      	 */
      	//1.在mapper接口中定義抽象方法:但是:方法的第一個參數:要傳一個IPage,返回值要是IPage,里面寫查詢集合的泛型即可
         IPage<User> queryByAge(IPage<User>page, @Param("age") Integer age);
      }
      
      2.
      	<!--2.使用sql語句實現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:
      		//最后分頁的結果也會被封裝到page里面:-->所以直接通過page對象獲取結果即可
      		long pages = page.getPages();
      		long current = page.getCurrent(); //獲取當前頁碼、
      		List<User> records = page.getRecords(); //獲取當前頁數據
      		long total = page.getTotal();//獲取總條數
      		System.out.println("total:"+total);
      
      	}
      
      }
      

      2.4:條件構造器使用:

      2.4.1條件構造器的作用:

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

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

      2.4.2條件構造器的類結構:

      一般使用:
         第一種: UpdateWrapper(修改)、QueryWrapper(刪除、查詢、修改)
         第二種: LambdaUpdateWrapper(修改)、 LambdaQueryWrapper(刪除、查詢、修改)
      
      • (1)第一種:基于queryWrapper組裝條件:增/刪/改

          使用方法:
             1.在mapper接口中定義方法,并繼承base接口(提供了各種方法的實現)
             2.直接使用java代碼實現:不需要在mapper.xml文件中實現了
             //a:創建QueryWrapper
          	QueryWrapper<實體類>queryWrapper=new QueryWrapper<>();
          	//b:條件拼接:調用queryWrapper方法
          	//c:使用mappper對象:調用CRUD方法,傳入對象即可
        

      1.mapper接口:
      
      
      public interface UserMapper extends BaseMapper<User> {
      	//繼承BaseMapper接口:里面有單表的方法
      
      	/*
      	演示:自定義mapper方法實現分頁:
      	  eg:查詢
      	 */
      	//1.在mapper接口中定義抽象方法:但是:方法的第一個參數:要傳一個IPage,返回值要是IPage,里面寫查詢集合的泛型即可
         IPage<User> queryByAge(IPage<User>page, @Param("age") Integer age);
      }
      
      
      2.
      
      /*
      演示條件構造器使用:進行條件的動態拼接:
      
      (1)QueryWrapper測試:
       */
      @SpringBootTest
      public class MybatisPlusQueryWrapper {
      
      	@Autowired
      	private UserMapper userMapper; //拿到對象:操作數據庫
      
      	@Test
      	public void test_01(){
      		//查詢用戶名包含 a,age在20到30之間的,且郵箱不為空的用戶;
      		 //分析:查詢:返回的是集合List-->selectList
      
      		//a:創建一個QueryWrapper集合:相當于容器來裝條件
      		QueryWrapper<User> queryWrapper=new QueryWrapper<>();
      		//b:之后sql語句的條件:直接使用queryWrapper動態調用wrapper的方法來完成動態拼接;
      		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接口,所以單表直接調用方法即可!
      		//queryWrapper就是sql條件,將它·傳進去!!!
      		//之后這個就會變成sql語句; !!!!!!!!!!!
      		//就相當于:select  * from user where name(like %a% and age>=20 and age<=30 and email is not null)
      
      		/*
      		!!!一個個調用麻煩,可以使用鏈式調用:!!!!
      		 queryWrapper.like("name","a").between("age",20,30).isNotNull("email");
      		 */
      
      	}
      }
      

      (2)queryWrapper實戰使用:

      	@SpringBootTest
      	public class MybatisPlusQueryWrapper {
      
      		@Autowired
      		private UserMapper userMapper; //拿到對象:操作數據庫按照年齡降序查詢用戶,如果年齡age相同則按id升序排列
      
      		 //(2)queryWrapper:按年齡降序查詢用戶,如果年齡相同則按id升序排列
      		@Test
      		public void test_02(){
      
      			//a:創建QueryMapper集合:裝條件
      			QueryWrapper<User> queryWrapper=new QueryWrapper<>();
      			//b:使用條件構造器進行條件的拼接:
      			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調用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,--->:條件直接調用時:默認自動使用and進行拼接;!!!!!
      				  //queryWrapper.gt("age",20).like("name","a") == where age>20 and ..      
      			   //2.如果想要在條件之后追加or關鍵字:可以使用: “or().條件”;
      
      			//c:創建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);
      			//!!!查詢時:默認是查詢全部???!!!!!,但可以使用select指定
      			queryWrapper.select("name","age");
      
      			userMapper.selectList(queryWrapper);
      		}
      
      		//(6)前端傳入兩個參數,name,age:---->:動態條件組織判斷!!!!
      		// 只要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)){  //調用isNotBlank進行判斷
      				//動態條件判斷:如果name不為null,就進行條件的拼接
      				queryWrapper.eq("name",name); //使用queryWrapper進行拼接
      			}
      
      			  //b.2:如果age>18 進行動態拼接:
      			if (age>18 && age!=null){
      				queryWrapper.eq("age",age);
      
      			}
      
      			userMapper.selectList(queryWrapper);
      
      
      			 /*
      		注意:!!!!!!!!!!!!!!!!
      		  Wrapper每個方法都有:一個boolean類型的condition,允許我們第一個參數放一個比較表達式,
      		  :如果condition為true-->整個條件為true,就執行下面代碼
      		  :如果condition為false-->整個條件為false,就失效,不執行下面代碼
      		  -->condition里面有動態判斷,就不用我們在外部寫判斷了
      		  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區別:

      (參數1:條件; 參數2:修改的數據)
      queryWrapper修改:參數1只能放條件,且列名不能為null
      updateWrapper修改:參數1可以放條件, 且列名可以設置為null;
      				   且可以直接調用set方法進行修改
      
      • (2)第二種:

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

      LambdaQueryWrapper:增/刪/改

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

      LambdaupdateWrapper:改

      eg:
      		LambdaUpdateWrapper<User>lambdaUpdateWrapper=new LambdaUpdateWrapper<>();
      
      		//即只要將原來的列名,變為Lambda方法引用即可,其余不變!!!!!!!!!!
      		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)總結:

      Wrapper:里面:完成了動態條件封裝
      最終推薦使用Lambda;(不用寫列名,只需類名::方法即可)
      
      如果復雜的sql:qg:嵌套、子查詢 不會使用Wrapper怎么辦:
       我們仍然使用原來的:定義mapper
      	  如果為單表的話:直接使用mapper對象調用CRUD方法即可;
      	  如果為多表的話:在mapper.xml文件中實現;
      

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

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

      1.@TableName

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

      2.@TableId:

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

      type增長策略:

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

      3.@TableFiled

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

      三:Mybatis-plus高級擴展

      3.1邏輯刪除實現:

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

      代碼演示:

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

      3.2樂觀鎖的實現

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

      樂觀鎖測試:

      1.
       alter  table user add version int default 1;  #int 類型 樂觀鎖字段
      
      2.
      public class User {
      	@Version
      	private Integer version; //版本號字段
      }
      
      //注意:之后在數據修改時都會檢查樂觀鎖;
      
      
      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.
      /*
      測試樂觀鎖實現
       */
      @SpringBootTest
      public class MybatisPlusVersionTest {
      
      	private UserMapper userMapper;
      
      	@Test
      	public void testById(){
      
      		//步驟1:先查詢,再更新 獲取version數據
      		//同時查詢兩條,但是version唯一,最后更新的失敗、
      
      		User user=new User();  //user 版本號為:1
      		User user1=new User(); //user1 版本號為:1
      
      		user.setAge(20);
      		user.setAge(30);
      
      		userMapper.updateById(user); //20-->:此時數據庫的version ->2
      		//樂觀鎖生效:失敗
      		userMapper.updateById(user1);
      		//因為user1的版本號為1,但是數據庫的版本號為2,證明不是最新數據 -->1!=2,樂觀鎖生效,更新失敗
      		  //所以最終age為:20
      
      	}
      }
      

      3.3防止全表更新和刪除

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

      代碼測試:

      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對象,進行數據庫操作!!!;
      
      	 //a:全表刪除!
      	 mapper.delete(null); ----->:null,代表沒有寫條件,代表:全表刪除;
      	 //b:全表更新:
      	 mapper.update(null); ------>: null,代表沒有條件,代表全表更新!
      
      	 ----------->:之后就會拋出異常:不允許全表delete/update!!!!!!!
      
       }
      

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

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

      4.1Mybatis插件逆向工程

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

      4.2Mybatis-plus快速生成單表CRUD代碼(自定義sql)!!!!!!!!

      如果我們需要自己定義一些sql語句:
        eg:批量查詢、根據id查詢......
      
      //步驟:
      	  1.直接在mapper接口中書寫相應的 ” 方法名 “ (//按照mybatisX的方法命名規則)
      		eg:批量插入:insertBatch
      			根據條件查詢:selectByNameAndAgeAndAge
      
      	  2.然后鼠標放在方法名上,點擊MybatisX,
      		--->MybatisX 就會在mapper接口自動寫好 且 在mapper.xml文件中自動生成sql語句!!!!!!!!
      
      
      //之后有關單表的CRUD我們就不需要自己寫了!!!!!!!!!!
      
      //我們可以看mybatisX的官方文檔:介紹了如何寫
      
      posted @ 2024-07-11 23:00  二價亞鐵  閱讀(645)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 亚洲av成人网在线观看| 中文字幕日韩精品无码内射| 91久久偷偷做嫩草影院免费看| 四虎永久免费影库二三区| 国产超高清麻豆精品传媒麻豆精品| 日本免费观看mv免费版视频网站| 中日韩中文字幕一区二区| 狠狠躁天天躁中文字幕无码| 国产线播放免费人成视频播放| 蜜臀98精品国产免费观看 | 人妻久久久一区二区三区| 韩国 日本 亚洲 国产 不卡| 黑人巨大videos极度另类| 盐津县| 国产熟睡乱子伦午夜视频| 中文字幕亚洲综合小综合| 一本加勒比hezyo无码人妻| 这里只有精品在线播放| 精品自拍偷拍一区二区三区| 亚洲精品中文字幕尤物综合| 一出一进一爽一粗一大视频| 国产一国产看免费高清片| 亚洲夂夂婷婷色拍ww47| 亚洲色大成网站WWW永久麻豆 | 亚洲国产精品线观看不卡| 人妻系列无码专区69影院 | 亚洲国产精品成人无码区| 国产综合久久久久久鬼色| 黄页网站在线观看免费视频| 松滋市| 亚洲区综合区小说区激情区| 秋霞鲁丝片成人无码| 辽宁省| 99国产精品永久免费视频| 99久久无色码中文字幕| 玩弄丰满少妇人妻视频| 欧美一区二区三区成人久久片| 大地资源高清播放在线观看| 精品国产一区二区三区av性色| 天堂资源在线| 欧美日韩亚洲国产|