免费视频淫片aa毛片_日韩高清在线亚洲专区vr_日韩大片免费观看视频播放_亚洲欧美国产精品完整版

打開(kāi)APP
userphoto
未登錄

開(kāi)通VIP,暢享免費(fèi)電子書(shū)等14項(xiàng)超值服

開(kāi)通VIP
MyBatis-Plus配置日志與CRUD

一、配置日志

mybatis-plus:
  configuration:
    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

二、CRUD

Mapper

Service

1、插入操作

Mapper

Insert 插入

// 插入一條記錄
int insert(T entity);

Service

Save

// 插入一條記錄(選擇字段,策略插入)
boolean save(T entity);
// 插入(批量)
boolean saveBatch(Collection<T> entityList);
// 插入(批量)
boolean saveBatch(Collection<T> entityList, int batchSize);

測(cè)試:

@Test
	public void test2(){
		User user = new User();
		user.setName("latteit");
		user.setAge(10);
		user.setEmail("xxx@qq.com");
		int insert = usermapper.insert(user);// 幫我們自動(dòng)生成id
	   System.out.println(insert); // 受影響的行數(shù)
       System.out.println(user); // 發(fā)現(xiàn),id會(huì)自動(dòng)回填 
	}

數(shù)據(jù)庫(kù)插入的id的默認(rèn)值為:全局的唯一id

主鍵生成策略

默認(rèn) ID_WORKER 全局唯一id

雪花算法:
snow?ake是Twitter開(kāi)源的分布式ID生成算法,結(jié)果是一個(gè)long型的ID。其核心思想是:使用41bit作為 毫秒數(shù),10bit作為機(jī)器的ID(5個(gè)bit是數(shù)據(jù)中心,5個(gè)bit的機(jī)器ID),12bit作為毫秒內(nèi)的流水號(hào)(意味 著每個(gè)節(jié)點(diǎn)在每毫秒可以產(chǎn)生 4096 個(gè) ID),后還有一個(gè)符號(hào)位,永遠(yuǎn)是0??梢员WC幾乎全球唯 一!

主鍵自增

我們需要配置主鍵自增:

1、實(shí)體類(lèi)字段上 @TableId(type = IdType.AUTO)

2、數(shù)據(jù)庫(kù)字段一定要是自增!

public enum IdType {
    AUTO(0),   //數(shù)據(jù)可id自增
    NONE(1),   //未設(shè)置主鍵
    INPUT(2),   //手動(dòng)輸入
    ID_WORKER(3), //默認(rèn)的全局唯一id
    UUID(4),  //全局唯一id uuid
    ID_WORKER_STR(5); // ID_WORKEK 字符串表示法
   }

2、更新操作

Mapper

update

// 根據(jù) whereEntity 條件,更新記錄
int update(@Param(Constants.ENTITY) T entity, @Param(Constants.WRAPPER) Wrapper<T> updateWrapper);
// 根據(jù) ID 修改
int updateById(@Param(Constants.ENTITY) T entity);

Service

Update

// 根據(jù) UpdateWrapper 條件,更新記錄 需要設(shè)置sqlset
boolean update(Wrapper<T> updateWrapper);
// 根據(jù) whereEntity 條件,更新記錄
boolean update(T entity, Wrapper<T> updateWrapper);
// 根據(jù) ID 選擇修改
boolean updateById(T entity);
// 根據(jù)ID 批量更新
boolean updateBatchById(Collection<T> entityList);
// 根據(jù)ID 批量更新
boolean updateBatchById(Collection<T> entityList, int batchSize);

SaveOrUpdate 修改插入

// TableId 注解存在更新記錄,否插入一條記錄
boolean saveOrUpdate(T entity);
// 根據(jù)updateWrapper嘗試更新,否繼續(xù)執(zhí)行saveOrUpdate(T)方法
boolean saveOrUpdate(T entity, Wrapper<T> updateWrapper);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList);
// 批量修改插入
boolean saveOrUpdateBatch(Collection<T> entityList, int batchSize);


測(cè)試:

@Test
	public void test4(){
		User user = new User();
		 // 通過(guò)條件自動(dòng)拼接動(dòng)態(tài)sql 
		user.setAge(6);
		user.setEmail("asghagsghas@com");
		user.setName("jack");
		user.setId(1L);
		// 注意:updateById 但是參數(shù)是一個(gè) 對(duì)象
		//更新滿(mǎn)足條件的
		int i = usermapper.updateById(user);
		//更新全部
		usermapper.update(user,null);
		System.out.println(i);
	}

自動(dòng)填充

創(chuàng)建時(shí)間、修改時(shí)間!這些個(gè)操作一遍都是自動(dòng)化完成的,我們不希望手動(dòng)更新!
阿里巴巴開(kāi)發(fā)手冊(cè):所有的數(shù)據(jù)庫(kù)表:gmt_create、gmt_modi?ed幾乎所有的表都要配置上!而且需 要自動(dòng)化!

方式一:數(shù)據(jù)庫(kù)級(jí)別

? 在表中新增字段 create_time 、update_time(默認(rèn)CURRENT_TIMESIAMP)

再次測(cè)試插入方法,我們需要先把實(shí)體類(lèi)同步!

    private Date  updateTime;
    private Date  createTime;

插入就行

方式二:代碼級(jí)別

1、刪除數(shù)據(jù)庫(kù)的默認(rèn)值、更新操作!

2、實(shí)體類(lèi)字段屬性上需要增加注解

    @TableField(fill = FieldFill.INSERT_UPDATE)// 字段添加填充內(nèi)容
    private Date  updateTime;
    @TableField(fill = FieldFill.INSERT)
    private Date  createTime;

3、編寫(xiě)處理器來(lái)處理這個(gè)注解即可


@Slf4j
@Component // 一定不要忘記把處理器加到IOC容器中! 
public class MyMetaObjectHandler implements MetaObjectHandler {
    @Override// 插入時(shí)的填充策略
    public void insertFill(MetaObject metaObject) {
        log.info("start insert fill ....");
       this.setFieldValByName("createTime",new Date(),metaObject);
       this.setFieldValByName("updateTime",new Date(),metaObject);
    }

    @Override // 更新時(shí)的填充策略
    public void updateFill(MetaObject metaObject) {
        log.info("start update fill ....");
      this.setFieldValByName("updateTime",new Date(),metaObject);
    }
}

4、測(cè)試插入

5、測(cè)試更新、觀察時(shí)間即可!

樂(lè)觀鎖

樂(lè)觀鎖:顧名思義十分樂(lè)觀,它總是被認(rèn)為不會(huì)出現(xiàn)問(wèn)題,無(wú)論干什么都不去上鎖!如果出現(xiàn)了問(wèn)題,再次更新測(cè)試

悲觀鎖:顧名思義十分悲觀,它總是出現(xiàn)問(wèn)題,無(wú)論干什么都會(huì)上鎖!再去操作!

樂(lè)觀鎖實(shí)現(xiàn)方式

  • 取出記錄是,獲取當(dāng)前version
  • 更新時(shí),帶上這個(gè)version
  • 執(zhí)行更新事,set version=newVersion where version =oldVersion
  • 如果version不對(duì),就更新失敗
樂(lè)觀鎖: 1、先查詢(xún),獲得版本號(hào) version=1
--A
update user set name ="shuishui" ,version =version+1
where id =2 and version=1

--B 如果線(xiàn)程搶先完成,這個(gè)時(shí)候version=2,會(huì)導(dǎo)致A修改失敗
update user set name ="shuishui" ,version =version+1
where id =2 and version=1

測(cè)試樂(lè)觀鎖
1、表中創(chuàng)建樂(lè)觀鎖字段version 默認(rèn)值為1


2、我們實(shí)體類(lèi)加對(duì)應(yīng)的字段

@Version //樂(lè)觀鎖Version注解
    private Integer version;

3、注冊(cè)組件
注意:3.4.0開(kāi)始插件的配置方式改變了,3.4.0之前的版本

// 掃描我們的 mapper 文件夾
@MapperScan("com.latte.mapper")
@EnableTransactionManagement
@Configuration // 配置類(lèi)
public class MyBatisPlusConfig {

    // 注冊(cè)樂(lè)觀鎖插件
    @Bean
    public OptimisticLockerInterceptor optimisticLockerInterceptor() {
        return new OptimisticLockerInterceptor();
    }
}

3.4.0之后的版本

@Configuration
@MapperScan("com.latte.mapper")
@EnableTransactionManagement
public class MybatisPlusConfig {

    // 注冊(cè)樂(lè)觀鎖插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //樂(lè)觀鎖插件
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
   
        return mybatisPlusInterceptor;
    }


}

4、測(cè)試一下!

// 測(cè)試樂(lè)觀鎖成功!
	@Test
	public void testOptimisticLocker(){
		// 1、查詢(xún)用戶(hù)信息
		User user = usermapper.selectById(1L);
		// 2、修改用戶(hù)信息
		user.setName("latte");
		user.setEmail("xxx@qq.com");
		// 3、執(zhí)行更新操作
		usermapper.updateById(user);
	}
// 測(cè)試樂(lè)觀鎖失敗!多線(xiàn)程下
	@Test
	public void testOptimisticLocker2(){

		// 線(xiàn)程 1
		User user = usermapper.selectById(1L);
		user.setName("latte");
		user.setEmail("xxx@qq.com");

		// 模擬另外一個(gè)線(xiàn)程執(zhí)行了插隊(duì)操作
		User user2 = usermapper.selectById(1L);
		user2.setName("latte2");
		user2.setEmail("xxx@qq.com");
		usermapper.updateById(user2);

		// 自旋鎖來(lái)多次嘗試提交!
		usermapper.updateById(user); // 如果沒(méi)有樂(lè)觀鎖就會(huì)覆蓋插隊(duì)線(xiàn)程的值!
	}


說(shuō)明:

  • 支持的數(shù)據(jù)類(lèi)型只有:int,Integer,long,Long,Date,Timestamp,LocalDateTime
  • 整數(shù)類(lèi)型下 newVersion = oldVersion + 1
  • newVersion 會(huì)回寫(xiě)到 entity 中
  • 僅支持 updateById(id) 與 update(entity, wrapper) 方法
  • 在 update(entity, wrapper) 方法下, wrapper 不能復(fù)用!!!

3、查詢(xún)操作

Mapper

select

// 根據(jù) ID 查詢(xún)
T selectById(Serializable id);
// 根據(jù) entity 條件,查詢(xún)一條記錄
T selectOne(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 查詢(xún)(根據(jù)ID 批量查詢(xún))
List<T> selectBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根據(jù) entity 條件,查詢(xún)?nèi)坑涗?/span>
List<T> selectList(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 查詢(xún)(根據(jù) columnMap 條件)
List<T> selectByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);
// 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗?/span>
List<Map<String, Object>> selectMaps(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗?。注意?只返回第一個(gè)字段的值
List<Object> selectObjs(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

// 根據(jù) entity 條件,查詢(xún)?nèi)坑涗洠ú⒎?yè))
IPage<T> selectPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗洠ú⒎?yè))
IPage<Map<String, Object>> selectMapsPage(IPage<T> page, @Param(Constants.WRAPPER) Wrapper<T> queryWrapper);
// 根據(jù) Wrapper 條件,查詢(xún)總記錄數(shù)
Integer selectCount(@Param(Constants.WRAPPER) Wrapper<T> queryWrapper);

Service

Get 查詢(xún)單條記錄

// 根據(jù) ID 查詢(xún)
T getById(Serializable id);
// 根據(jù) Wrapper,查詢(xún)一條記錄。結(jié)果集,如果是多個(gè)會(huì)拋出異常,隨機(jī)取一條加上限制條件 wrapper.last("LIMIT 1")
T getOne(Wrapper<T> queryWrapper);
// 根據(jù) Wrapper,查詢(xún)一條記錄
T getOne(Wrapper<T> queryWrapper, boolean throwEx);
// 根據(jù) Wrapper,查詢(xún)一條記錄
Map<String, Object> getMap(Wrapper<T> queryWrapper);
// 根據(jù) Wrapper,查詢(xún)一條記錄
<V> V getObj(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

List 查詢(xún)多條記錄

// 查詢(xún)所有
List<T> list();
// 查詢(xún)列表
List<T> list(Wrapper<T> queryWrapper);
// 查詢(xún)(根據(jù)ID 批量查詢(xún))
Collection<T> listByIds(Collection<? extends Serializable> idList);
// 查詢(xún)(根據(jù) columnMap 條件)
Collection<T> listByMap(Map<String, Object> columnMap);
// 查詢(xún)所有列表
List<Map<String, Object>> listMaps();
// 查詢(xún)列表
List<Map<String, Object>> listMaps(Wrapper<T> queryWrapper);
// 查詢(xún)?nèi)坑涗?/span>
List<Object> listObjs();
// 查詢(xún)?nèi)坑涗?/span>
<V> List<V> listObjs(Function<? super Object, V> mapper);
// 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗?/span>
List<Object> listObjs(Wrapper<T> queryWrapper);
// 根據(jù) Wrapper 條件,查詢(xún)?nèi)坑涗?/span>
<V> List<V> listObjs(Wrapper<T> queryWrapper, Function<? super Object, V> mapper);

Page 分頁(yè)查

// 無(wú)條件分頁(yè)查詢(xún)
IPage<T> page(IPage<T> page);
// 條件分頁(yè)查詢(xún)
IPage<T> page(IPage<T> page, Wrapper<T> queryWrapper);
// 無(wú)條件分頁(yè)查詢(xún)
IPage<Map<String, Object>> pageMaps(IPage<T> page);
// 條件分頁(yè)查詢(xún)
IPage<Map<String, Object>> pageMaps(IPage<T> page, Wrapper<T> queryWrapper);

Count

// 查詢(xún)總記錄數(shù)
int count();
// 根據(jù) Wrapper 條件,查詢(xún)總記錄數(shù)
int count(Wrapper<T> queryWrapper);

Chain

query

// 鏈?zhǔn)讲樵?xún) 普通
QueryChainWrapper<T> query();
// 鏈?zhǔn)讲樵?xún) lambda 式。注意:不支持 Kotlin
LambdaQueryChainWrapper<T> lambdaQuery(); 

// 示例:
query().eq("column", value).one();
lambdaQuery().eq(Entity::getId, value).list();

update

// 鏈?zhǔn)礁?普通
UpdateChainWrapper<T> update();
// 鏈?zhǔn)礁?lambda 式。注意:不支持 Kotlin 
LambdaUpdateChainWrapper<T> lambdaUpdate();

// 示例:
update().eq("column", value).remove();
lambdaUpdate().eq(Entity::getId, value).update(entity);

測(cè)試:

// 測(cè)試查詢(xún)
@Test
	public void testSelectById(){
		User user = usermapper.selectById(1368490321062813699L);
		System.out.println(user);

	}

	// 測(cè)試批量查詢(xún)!
	@Test
	public void testSelectByBatchId(){

		List<User> users = usermapper.selectBatchIds(Arrays.asList(1, 2, 3));
		for (User user : users) {

			System.out.println(user);
		}

	}

	// 按條件查詢(xún)之一使用map操作
	@Test
	public void testSelectByBatchIds(){
		HashMap<String, Object> map = new HashMap<>();
		map.put("name","jack");
		map.put("age",6);
		List<User> users = usermapper.selectByMap(map);
		for (User user : users) {
			System.out.println(user);
		}
	}

分頁(yè)查詢(xún)

分頁(yè)在網(wǎng)站使用的十分多

1、原始的limit進(jìn)行分頁(yè)

2、pageHelper 第三方插件

3、Mybatis-Plus中也內(nèi)置了分頁(yè)插件!

支持的數(shù)據(jù)庫(kù)

  • mysql 、mariadb 、oracle 、db2 、h2 、hsql 、sqlite 、postgresql 、sqlserver
    、presto 、Gauss 、Firebird
  • Phoenix 、clickhouse 、Sybase ASE 、 OceanBase 、達(dá)夢(mèng)數(shù)據(jù)庫(kù) 、虛谷數(shù)據(jù)庫(kù) 、人大金倉(cāng)數(shù)據(jù)庫(kù)
    、南大通用數(shù)據(jù)庫(kù)


自定義的 mapper#method 使用分頁(yè)

IPage<UserVo> selectPageVo(IPage<?> page, Integer state);
// or (class MyPage extends Ipage<UserVo>{ private Integer state; })
MyPage selectPageVo(MyPage page);
// or
List<UserVo> selectPageVo(IPage<UserVo> page, Integer state);
<select id="selectPageVo" resultType="xxx.xxx.xxx.UserVo">
    SELECT id,name FROM user WHERE state=#{state}
</select>
  • 如果返回類(lèi)型是 IPage 則入?yún)⒌?IPage 不能為null,因?yàn)?返回的IPage == 入?yún)⒌腎Page
  • 如果返回類(lèi)型是 List 則入?yún)⒌?IPage 可以為 null(為 null 則不分頁(yè)),但需要你手動(dòng)
    入?yún)⒌腎Page.setRecords(返回的 List);
  • 如果 xml 需要從 page 里取值,需要 page.屬性 獲取

其他:

生成 countSql 會(huì)在 left join 的表不參與 where 條件的情況下,把 left join 優(yōu)化掉
所以建議任何帶有 left join 的sql,都寫(xiě)標(biāo)準(zhǔn)sql既給于表一個(gè)別名,字段也要 別名.字段

如何使用

1、配置攔截器組件即可

3.4.0以前

 // 分頁(yè)插件
    @Bean
    public PaginationInterceptor paginationInterceptor() {
        return  new PaginationInterceptor();
    }

3.4.0以后

 // 注冊(cè)樂(lè)觀鎖插件與分頁(yè)插件
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor mybatisPlusInterceptor = new MybatisPlusInterceptor();
        //分頁(yè)插件  
        mybatisPlusInterceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
         //樂(lè)觀鎖插件
        mybatisPlusInterceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return mybatisPlusInterceptor;
    }

2、直接使用Page對(duì)象即可!


	// 測(cè)試分頁(yè)查詢(xún)
	@Test
	public void testPage(){
		//  參數(shù)一:當(dāng)前頁(yè)
		//  參數(shù)二:頁(yè)面大小
		//  使用了分頁(yè)插件之后,所有的分頁(yè)操作也變得簡(jiǎn)單的!
		Page<User> page = new Page<>(1,2);
		usermapper.selectPage(page,null);

		page.getRecords().forEach(System.out::println);
		System.out.println(page.getTotal());

	}

4、刪除操作

Mapper

delete

// 根據(jù) entity 條件,刪除記錄
int delete(@Param(Constants.WRAPPER) Wrapper<T> wrapper);
// 刪除(根據(jù)ID 批量刪除)
int deleteBatchIds(@Param(Constants.COLLECTION) Collection<? extends Serializable> idList);
// 根據(jù) ID 刪除
int deleteById(Serializable id);
// 根據(jù) columnMap 條件,刪除記錄
int deleteByMap(@Param(Constants.COLUMN_MAP) Map<String, Object> columnMap);

Service

Remove

// 根據(jù) entity 條件,刪除記錄
boolean remove(Wrapper<T> queryWrapper);
// 根據(jù) ID 刪除
boolean removeById(Serializable id);
// 根據(jù) columnMap 條件,刪除記錄
boolean removeByMap(Map<String, Object> columnMap);
// 刪除(根據(jù)ID 批量刪除)
boolean removeByIds(Collection<? extends Serializable> idList);

測(cè)試:

1、根據(jù) id 刪除記錄

// 測(cè)試刪除
	@Test
	public void testDeleteById(){
		usermapper.deleteById(1368490321062813699L);
	}

	// 通過(guò)id批量刪除
	@Test
	public void testDeleteBatchId(){
		usermapper.deleteBatchIds(Arrays.asList(2,3,4));
	}

	// 通過(guò)map刪除
	@Test
	public void testDeleteMap(){
		HashMap<String, Object> map = new HashMap<>();
		map.put("name","jom");
		usermapper.deleteByMap(map);
	}

邏輯刪除

物理刪除 :從數(shù)據(jù)庫(kù)中直接移出

邏輯刪除:在數(shù)據(jù)庫(kù)中沒(méi)有被移出,而是通過(guò)一個(gè)變量來(lái)讓他失效!deleted=0 ==>deleted =1(失效)

管理員可以查看被刪除的記錄!防止數(shù)據(jù)的丟失,類(lèi)似于回收站!


測(cè)試一下:

1、在數(shù)據(jù)表中增加一個(gè) deleted 字段

2、實(shí)體類(lèi)中增加屬性

 @TableLogic //邏輯刪除
    private Integer deleted;

注冊(cè) Bean(3.1.1開(kāi)始不再需要這一步):

@Bean
    public ISqlInjector sqlInjector() {
        return new LogicSqlInjector();
    }

配置

mybatis-plus:
  global-config:
    db-config:
      logic-delete-field: flag  # 全局邏輯刪除的實(shí)體字段名(since 3.3.0,配置后可以忽略不配置步驟2)
      logic-delete-value: 1 # 邏輯已刪除值(默認(rèn)為 1)
      logic-not-delete-value: 0 # 邏輯未刪除值(默認(rèn)為 0)

測(cè)試一下刪除!


走的是更新,不是刪除了,記錄依舊在數(shù)據(jù)庫(kù),但是值確已經(jīng)變化了!

查詢(xún)的時(shí)候也會(huì)自動(dòng)過(guò)濾,就查詢(xún)不到之前邏輯刪除的值了


本站僅提供存儲(chǔ)服務(wù),所有內(nèi)容均由用戶(hù)發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊舉報(bào)。
打開(kāi)APP,閱讀全文并永久保存 查看更多類(lèi)似文章
猜你喜歡
類(lèi)似文章
SpringBoot MyBatis Plus 集成 【SpringBoot系列5】
5.mybatisPlus自定義SQL_mybatisplus 自定義sql
熟練掌握 mybatis-plus,一篇就夠!
MyBatisPlus學(xué)習(xí)整理
Mybatis-Plus3.0入門(mén)手冊(cè)
MyBatisPlus 入門(mén)教程,這篇很贊
更多類(lèi)似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長(zhǎng)圖 關(guān)注 下載文章
綁定賬號(hào)成功
后續(xù)可登錄賬號(hào)暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點(diǎn)擊這里聯(lián)系客服!

聯(lián)系客服