MyBatisPlus——入門到進階

?作者簡介:大家好,我是 Meteors., 向往著更加簡潔高效的代碼寫法與編程方式,持續分享Java技術內容。
🍎個人主頁:Meteors.的博客
💞當前專欄:知識分享、知識備份
?特色專欄: 知識分享
🥭本文內容:MyBatisPlus——入門到進階
📚 ** ps ** ?: 閱讀文章如果有問題或者疑惑,歡迎在評論區提問或指出。


目錄

01. 入門

1. 添加依賴

2. Mapper繼承BaseMapper接口

02. 常見注解

1. 說明

?2. 例子

03. 常見配置

03. 常見配置

04. 核心功能-條件構造器

1. 說明

2. 例子

05. 核心功能-自定義SQL

1. 說明

2. 步驟

a. 基于Wrapper構建where條件

b. 在mapper方法中用Param注解聲明wrapper變量名稱,必須是ew

c.定義SQL,并使用Wrapper條件

06. 核心功能-Service接口

1. 說明

2. 步驟

a. Service層繼承IService接口

b. Service實現類繼承(Impl)繼承ServiceImpl

c. 調用方法(以save為例,更多例子點擊這里)

3. 補充

07. 擴展功能-代碼生成?

方式一:使用代碼生成器代碼進行生成

方式二:使用MybatisX進行代碼生成(這個會少一個controller)

方式三:使用應用商店的MybatisPlus插件進行代碼生成

08. 擴展功能-靜態工具

1.說明

2. 例子

09. 擴展功能-邏輯刪除

1. 說明

2. 例子

3. 補充(引用自黑馬視頻)

10.? 擴展功能-枚舉處理器

1. 說明

2. 例子

11. 擴展功能-JSON處理器

1. 說明

2. 例子

?12. 插件功能-分頁插件

1. 說明

2. 例子


01. 入門

1. 添加依賴

<!--        <dependency>-->
<!--            <groupId>org.mybatis.spring.boot</groupId>-->
<!--            <artifactId>mybatis-spring-boot-starter</artifactId>-->
<!--            <version>2.3.1</version>-->
<!--        </dependency>--><!--    MyBatisPlus依賴    --><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.6</version></dependency>

2. Mapper繼承BaseMapper接口

// 類似于
public interface UserMapper extend BaeMapper<User>{}

02. 常見注解

1. 說明

mp通過掃描實體類,并基于反射獲取實體類信息作為數據庫表信息,比較常用的注解如下:

  • @TableName:指定表名
  • @TableId:用來指定表中的主鍵字段信息
    • idType枚舉說明:
      • ATUO:數據庫自增
      • INPUT:通過set方法自行輸入
      • ASSUGN_ID:分配ID(接口IdentifierGenerator的方法nextId來生成id,默認實現類為DefaultIdentifierGenerator雪花算法)
  • @TableField:用來指定表中的普通字段信息
    • 使用場景:
      • 成員變量名宇數據庫字段名不一致
      • 成員變量名以is開頭,且是布爾值
      • 成員變量名宇數據庫關鍵字沖突
      • 成員變量不是數據庫字段

?2. 例子

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.time.LocalDateTime;@Data
@TableName("tb_user")
public class User {/*** 用戶id*/@TableId(type = IdType.AUTO)private Long id;/*** 用戶名*/@TableField("`username`")private String username;/*** 密碼*/@TableField(exist = false)private String password;/*** 注冊手機號*/private String phone;/*** 詳細信息*/private String info;/*** 使用狀態(1正常 2凍結)*/private Integer status;/*** 賬戶余額*/private Integer balance;/*** 創建時間*/private LocalDateTime createTime;/*** 更新時間*/private LocalDateTime updateTime;
}

03. 常見配置

03. 常見配置

mybatis-plus:configuration:# MyBatis 配置map-underscore-to-camel-case: true# 掃描包global-config:# 全局配置db-config:# 數據庫配置id-type: auto# 包的位置type-aliases-package: com.itmeteors.mp.domain.po

04. 核心功能-條件構造器

1. 說明

mp為我們提供了的條件構造器方法,以便與我們進行查詢操作:

2. 例子

    // 01. 查詢出名字中帶o的,存款大于1000元人的id、userName、info、balance@Testvoid testQueryWrapper(){//    1. 構建查詢條件QueryWrapper<User> wrapper = new QueryWrapper<User>().select("id", "username", "info", "balance").like("username", "o").ge("balance", 1000);//    2. 查詢List<User> users = userMapper.selectList(wrapper);users.forEach(System.out::println);}// 02. 更新用戶名為jack的用戶的余額為2000@Testvoid testUpdateByQueryWrapper(){//    1. 要更新的數據User user = new User;user.setBalance(2000);//    2. 更新要的條件QueryWrapper<User> wrapper = new QueryWrapper<User>().eq("username", "jack");//    3. 執行更新userMapper.update(user,wrapper);}// 03. 更新id為1,2,4的用戶的余額,扣200@Testvoid testUpdateWrapper(){List<Long> ids = List.of(1L,2L,4L);UpdateWrapper<User> wrapper = new UpdateWrapper<User>().setSql("balance = balance - 200").in("id",ids);userMapper.update(null,wrapper);}// 04. 使用lambada方式更新id為1,2,4的用戶的余額,扣200@Testvoid testLambadaUpdateWrapper(){List<Long> ids = List.of(1L,2L,4L);LambdaUpdateWrapper<User> wrapper = new LambdaUpdateWrapper<User>().setSql("balance = balance - 200").in(User::getId,ids);userMapper.update(null,wrapper);}

05. 核心功能-自定義SQL

1. 說明

利用mp來構建復雜的Where條件,然后自己定義SQL語句中剩下的部分。

2. 步驟

a. 基于Wrapper構建where條件

    @Testvoid testUpdateWrapper2(){//    1. 更新條件List<Long> ids = List.of(1L, 2L, 4L);int amount = 200;//    2. 定義條件QueryWrapper<User> wrapper = new QueryWrapper<User>().in("id", ids);//    3. 調用自定義SQL方法userMapper.updateBalanceByIds(wrapper,amount);}

b. 在mapper方法中用Param注解聲明wrapper變量名稱,必須是ew

    void updateBalanceByIds(@Param(Constants.WRAPPER) QueryWrapper<User> wrapper,@Param("amount") int amount);

c.定義SQL,并使用Wrapper條件

    <update id="updateBalanceByIds">UPDATE tb_user SET balance = balance - #{amount} ${ew.customSqlSegment}</update>

06. 核心功能-Service接口

1. 說明

mp的service接口為我們定義了很多增刪改查的方法,減少了在service層的代碼書寫量

2. 步驟

a. Service層繼承IService接口

public interface IUserService extends IService<User> {}

b. Service實現類繼承(Impl)繼承ServiceImpl

@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {}

c. 調用方法(以save為例,更多例子點擊這里)

@SpringBootTest
class IUserServiceTest {@Autowiredprivate IUserService userService;@Testvoid testSaveUser(){User user = new User();user.setUsername("tesst");user.setPassword("123");user.setPhone("15966666666");user.setBalance(200);user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");user.setCreateTime(LocalDateTime.now());user.setUpdateTime(LocalDateTime.now());userService.save(user);}
}

3. 補充

使用?saveBatch()方法?默認不生效:

原因:雖然執行了批量插入方法,但是語句未被合并并優化,然后還是多個請求單獨發送給MySQL服務器,網絡往返次數和服務器解析SQL語句的開銷未減少

解決方法:在yml的數據庫連接url最后加上:?rewriteBatchedStatements=true,允許驅動程序重寫批處理語句為單個字符串,并發送給服務器,從而提高插入、更新和刪除操作的速度。

當然,這樣可能也會有缺點:

  1. SQL注入風險:因為語句被重寫,所以可能會增加SQL注入的風險。務必確保你使用的SQL語句是安全的,避免直接拼接用戶輸入。
  2. 不支持所有SQL語法:某些復雜的SQL語法可能不支持重寫。
  3. 調試困難:由于語句被重寫,所以在調試時可能更難以確定問題所在。

07. 擴展功能-代碼生成?

方式一:使用代碼生成器代碼進行生成

步驟:

  1. 導入依賴
    <dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-generator</artifactId><version>3.5.6</version>
    </dependency>
  2. 配置生成器類
    public class CodeGenerator {public static void main(String[] args) {FastAutoGenerator.create("jdbc:mysql://127.0.0.1:3306/mp?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "****").globalConfig(builder -> {builder.author("Meteors") // 設置作者.enableSwagger() // 開啟 swagger 模式.outputDir("C:\\Users\\Meteors\\Desktop\\SpringCloud微服務—資料\\day01-MybatisPlus\\資料\\mp-demo\\src\\main\\java"); // 指定輸出目錄}).dataSourceConfig(builder ->builder.typeConvertHandler((globalConfig, typeRegistry, metaInfo) -> {int typeCode = metaInfo.getJdbcType().TYPE_CODE;if (typeCode == Types.SMALLINT) {// 自定義類型轉換return DbColumnType.INTEGER;}return typeRegistry.getColumnType(metaInfo);})).packageConfig(builder ->builder.parent("com.itheima.mp") // 設置父包名.entity("domain.po") // 設置實體類包名.pathInfo(Collections.singletonMap(OutputFile.xml, "C:\\Users\\Meteors\\Desktop\\SpringCloud微服務—資料\\day01-MybatisPlus\\資料\\mp-demo\\src\\main\\resources\\mapper")) // 設置mapperXml生成路徑).strategyConfig(builder ->builder.addInclude("address") // 設置需要生成的表名.addTablePrefix("t_", "c_") // 設置過濾表前綴.entityBuilder().enableLombok() // 啟用 Lombok.enableTableFieldAnnotation() // 啟用字段注解.controllerBuilder().enableRestStyle() // 啟用 REST 風格).templateEngine(new FreemarkerTemplateEngine()) // 使用Freemarker引擎模板,默認的是Velocity引擎模板.execute();}
    }
    

  3. 運行代碼

方式二:使用MybatisX進行代碼生成(這個會少一個controller)

步驟:

  1. 選擇MybatisX:
  2. 選擇

方式三:使用應用商店的MybatisPlus插件進行代碼生成

步驟:

  1. 下載插件
  2. 重啟idea,并配置數據庫
  3. 進行代碼生成

08. 擴展功能-靜態工具

1.說明

使用靜態工具可以避免循環依賴問題。

2. 例子

需求(如果普通方式進行實現,下面兩個需求可能會造成循環依賴)

  • 改造更具id查詢用戶的接口,查詢用戶的同時,查詢出用戶對應的所有地址
    //Controller@ApiOperation("根據id查詢用戶接口")@GetMapping("{id}")public UserVO queryUserById(@ApiParam("用戶id") @PathVariable("id") Long id) {return userService.queryUserAndAddressById(id);}
    //ServiceUserVO queryUserAndAddressById(Long id);
    //Impl@Overridepublic UserVO queryUserAndAddressById(Long id) {//    1. 查詢用戶User user = getById(id);if (user == null || user.getStatus() == 2) {throw new RuntimeException("用戶狀態異常!");}//    2. 查詢地址List<Address> addressList = Db.lambdaQuery(Address.class).eq(Address::getUserId, id).list();//  3. 封裝VOUserVO userVO = BeanUtil.copyProperties(user, UserVO.class);if (CollUtil.isNotEmpty(addressList)){userVO.setAddresses(BeanUtil.copyToList(addressList, AddressVO.class));}return userVO;}
  • 改造根據id批量查詢用戶的接口,查詢用戶的同時,查詢出用戶對應的所有地址
    // Controller@ApiOperation("根據id批量查詢用戶接口")@GetMappingpublic List<UserVO> queryUserByIds(@ApiParam("用戶id集合") @RequestParam("ids") List<Long> ids) {return userService.queryUserAndAddressByIds(ids);}
    // ServiceList<UserVO> queryUserAndAddressByIds(List<Long> ids);
    // Impl@Overridepublic List<UserVO> queryUserAndAddressByIds(List<Long> ids) {// 1. 查詢用戶List<User> users = listByIds(ids);if (CollUtil.isEmpty(users)) {return Collections.emptyList();}// 2. 查詢地址// 2.1 獲取用戶id集合List<Long> userIds = users.stream().map(User::getId).collect(Collectors.toList());// 2.2 根據用戶id查詢地址List<Address> addresses = Db.lambdaQuery(Address.class).in(Address::getUserId, userIds).list();// 2.3 轉換地址VOList<AddressVO> addressVOList = BeanUtil.copyToList(addresses, AddressVO.class);// 2.4 用戶地址集合分組處理,相同用戶的放入一個集合(組)中Map<Long, List<AddressVO>> addressMap = new HashMap<>(0);if (CollUtil.isNotEmpty(addressVOList)) {addressMap = addressVOList.stream().collect(Collectors.groupingBy(AddressVO::getUserId));}// 3. 轉換VO返回List<UserVO> list = new ArrayList<>(users.size());for (User user : users) {//    3.1 轉換User的PO為VOUserVO vo = BeanUtil.copyProperties(user, UserVO.class);//    3.2 轉換地址VOvo.setAddresses(addressMap.get(user.getId()));//    3.3 添加到集合list.add(vo);}return list;}

09. 擴展功能-邏輯刪除

1. 說明

邏輯刪除解釋基于代碼邏輯模擬刪除效果,但并不會真正刪除數據。思路:

  • 在表中添加一個字段標記數據是否被刪除
  • 當刪除數據時把標記置為1
  • 查詢時值查詢標記為0的數據

例如邏輯刪除字段為deleted:

  • 刪除操作:UPDATE user SET deleted = 1 WHERE id = 1 AND deleted = 0;
  • 查詢操作:SELECT * FROM? user WHERE?deleted = 0;?

mp提供了邏輯刪除功能,無需改變方法調用的方式,而是在底層幫我們自動修改CRUD的語句。我們要做的就是在application.yaml文件中配置邏輯刪除的字段名稱和值即可:

2. 例子

在使用mp的邏輯刪除功能之后,原有的查詢功能會默認在末尾添加查詢條件,刪除功能會自動變更為UPDATE,下面是具體的例子:

  • 代碼
@SpringBootTest
class IAddressServiceTest {@Autowiredprivate IAddressService addressService;@Testvoid testLogicDelete(){//    1. 刪除addressService.removeById(59L);//  2. 查詢Address address = addressService.getById(59L);System.out.println("address = " + address);}
}
  • 結果

3. 補充(引用自黑馬視頻)

邏輯刪除本身也有自己的問題,比如:

  • 會導致數據庫表垃圾數據越來越多,影響查詢效率
  • SQL中全部需要對邏輯刪除字段做判斷,影響查詢效率

因此,需要進行邏輯刪除時,可以考慮把數據遷移到其它表的方法進行替代

10.? 擴展功能-枚舉處理器

1. 說明

用戶狀態字段如果用例如private Integer status的方式進行表示,用這種類型表示不直觀且代碼且屬于硬編碼,可維護性差、靈活性低、可擴展性差、可讀性差、重用性受限、錯誤分險增加,而使用mp枚舉處理器,可以避免這些缺點。

2. 例子

將原有的狀態字段改為枚舉類型:

  1. 步驟1:在yaml文件中設置枚舉處理器
  2. 步驟2:新建枚舉類
    @Getter
    public enum UserStatus {NORMAL(1,"正常"),FROZEN(2,"凍結"),;@EnumValueprivate final int value;@JsonValueprivate final  String desc;UserStatus(int value, String desc) {this.value = value;this.desc = desc;}
    }
  3. 步驟3:將字段類型替換為枚舉類型
        /*** 使用狀態(1正常 2凍結)*/private UserStatus status;
  4. 結果:

11. 擴展功能-JSON處理器

1. 說明

當數據中的表中含有json類型的字段時,如果自己實現Java代碼實體類與之對應,比較麻煩,此時可以使用mp的json處理器進行實現,提高開發效率。

2. 例子

將一個數據庫中使用json類型的info屬性,使用 json處理讓Java實體類與之對應,步驟:

  1. 新建那個屬性的實體類
    @Data
    @NoArgsConstructor
    @AllArgsConstructor(staticName = "of")
    public class UserInfo {private Integer age;private String intro;private String gender;
    }
  2. 字段上定義處理器并在實體類上開啟autoResultMap

ps:

  • 賦值方式
//user.setInfo("{\"age\": 24, \"intro\": \"英文老師\", \"gender\": \"female\"}");
user.setInfo(UserInfo.of(24,"英語老師","female"));
  • 結果

?12. 插件功能-分頁插件

1. 說明

在mp3.4版本之后,mp已經默認集成了mp插件,但如果需要對分頁的功能(例如溢出總頁數后是否進行處理、單頁條數限制、數據庫類型設置、方言實現設置)等,仍需要新建分頁插件進行實現。

2. 例子

以新建一個的分頁插件和通過分頁實體實現分頁功能為例,步驟如下:

  1. 添加分頁插件
    package com.itheima.mp.config;import com.baomidou.mybatisplus.annotation.DbType;
    import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
    import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;@Configuration
    public class MyBatisConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();//  1. 創建分頁插件PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);paginationInnerInterceptor.setMaxLimit(1000L);//  2. 添加分頁插件interceptor.addInnerInterceptor(paginationInnerInterceptor);return interceptor;}
    }
    
  2. 新建分頁實體
    @Data
    public class PageQuery {private Integer pageNo;private Integer pageSize;private String sortBy;private Boolean isAsc;public <T>  Page<T> toMpPage(OrderItem ... orders){// 1.分頁條件Page<T> p = Page.of(pageNo, pageSize);// 2.排序條件// 2.1.先看前端有沒有傳排序字段if (sortBy != null) {p.addOrder(new OrderItem(sortBy, isAsc));return p;}// 2.2.再看有沒有手動指定排序字段if(orders != null){p.addOrder(orders);}return p;}public <T> Page<T> toMpPage(String defaultSortBy, boolean isAsc){return this.toMpPage(new OrderItem(defaultSortBy, isAsc));}public <T> Page<T> toMpPageDefaultSortByCreateTimeDesc() {return toMpPage("create_time", false);}public <T> Page<T> toMpPageDefaultSortByUpdateTimeDesc() {return toMpPage("update_time", false);}
    }
    
  3. 新建分頁返回實體
    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class PageDTO<V> {private Long total;private Long pages;private List<V> list;/*** 返回空分頁結果* @param p MybatisPlus的分頁結果* @param <V> 目標VO類型* @param <P> 原始PO類型* @return VO的分頁對象*/public static <V, P> PageDTO<V> empty(Page<P> p){return new PageDTO<>(p.getTotal(), p.getPages(), Collections.emptyList());}/*** 將MybatisPlus分頁結果轉為 VO分頁結果* @param p MybatisPlus的分頁結果* @param voClass 目標VO類型的字節碼* @param <V> 目標VO類型* @param <P> 原始PO類型* @return VO的分頁對象*/public static <V, P> PageDTO<V> of(Page<P> p, Class<V> voClass) {// 1.非空校驗List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 無數據,返回空結果return empty(p);}// 2.數據轉換List<V> vos = BeanUtil.copyToList(records, voClass);// 3.封裝返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}/*** 將MybatisPlus分頁結果轉為 VO分頁結果,允許用戶自定義PO到VO的轉換方式* @param p MybatisPlus的分頁結果* @param convertor PO到VO的轉換函數* @param <V> 目標VO類型* @param <P> 原始PO類型* @return VO的分頁對象*/public static <V, P> PageDTO<V> of(Page<P> p, Function<P, V> convertor) {// 1.非空校驗List<P> records = p.getRecords();if (records == null || records.size() <= 0) {// 無數據,返回空結果return empty(p);}// 2.數據轉換List<V> vos = records.stream().map(convertor).collect(Collectors.toList());// 3.封裝返回return new PageDTO<>(p.getTotal(), p.getPages(), vos);}
    }
    
  4. 查詢類繼承分頁實體類
    @EqualsAndHashCode(callSuper = true)
    @Data
    @ApiModel(description = "用戶查詢條件實體")
    public class UserQuery extends PageQuery{@ApiModelProperty("用戶名關鍵字")private String name;@ApiModelProperty("用戶狀態:1-正常,2-凍結")private Integer status;@ApiModelProperty("余額最小值")private Integer minBalance;@ApiModelProperty("余額最大值")private Integer maxBalance;
    }
    
  5. 實現查詢接口
    // Controller@ApiOperation("根據條件分頁查詢用戶接口")@GetMapping("/page")public PageDTO<UserVO> queryUserPage(UserQuery query){return userService.queryUsersPage(query);}
    // ServicePageDTO<UserVO> queryUsersPage(UserQuery query);
    // Impl@Overridepublic PageDTO<UserVO> queryUsersPage(UserQuery query) {String name = query.getName();Integer status = query.getStatus();//  1. 構建查詢條件//  1.1 分頁條件Page<User> page = query.toMpPageDefaultSortByUpdateTimeDesc();//  2. 分頁查詢Page<User> p = lambdaQuery().like(name!=null,User::getUsername,name).eq(status!=null,User::getStatus,status).page(page);//  3. 封裝VO結果return PageDTO.of(p,user -> {//    1. 拷貝基礎屬性UserVO vo = BeanUtil.copyProperties(user, UserVO.class);//    2. 處理特殊邏輯vo.setUsername(vo.getUsername() +"**");return vo;});}

    ?最后,

    ? ? ? ? 希望文章對你有所幫助!

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/23661.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/23661.shtml
英文地址,請注明出處:http://en.pswp.cn/web/23661.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【GIS教程】土地利用轉移矩陣

隨著科技社會的不斷進步&#xff0c;人類活動對地理環境的影響與塑造日益明顯&#xff0c;土地不斷的侵蝕與改變也導致一系列的環境問題日益突出。土地利用/覆蓋&#xff08;LUCC&#xff09;作為全球環境變化研究的重點問題為越來越多的國際研究機構所重視&#xff0c;研究它的…

Day25 首頁待辦事項及備忘錄添加功能

? 本章節,完成首頁待辦事項及備忘錄添加功能 一.修改待辦事項和備忘錄邏輯處理類,即AddMemoViewModel和AddTodoViewModel 在 AddMemoViewModel邏輯處理類中,為了支持與其關聯的View視圖文件的數據綁定,需要定義一個與視圖文件相匹配的實體類 Model。這個Model將包含 View中…

圖像算法---自動對焦AF

一&#xff0c;CDAF反差對焦原理 CDAF&#xff0c;全稱Contrast Detection Auto Focus&#xff0c;即反差式對焦或對比度檢測自動對焦&#xff0c;是一種廣泛應用于入門級數碼相機和相機模塊化智能手機上的自動對焦技術。以下是關于CDAF反差對焦的詳細介紹&#xff1a; 工作原…

測繪航空攝影乙級資質升級為甲級的過渡期規劃

升級測繪航空攝影乙級資質為甲級通常需要一個詳細的過渡期規劃&#xff0c;這個過程涉及提升技術力量、積累業績、完善管理體系等多個方面。以下是一個概括性的過渡期規劃框架&#xff0c;具體實施時需結合實際情況和最新的資質標準進行調整&#xff1a; 1. 了解最新資質標準 …

每日AI資訊-20240606

智普AI推出全新開源大模型GLM-4-9B 智譜AI日前推出全新開源模型GLM-4-9B&#xff0c;該尺寸模型首次具備多模態能力。據了解&#xff0c;GLM-4-9B&#xff0c;最高支持1M/約兩百萬字上下文輸入&#xff0c;相當于2本《紅樓夢》或125篇論文的長度。性能上&#xff0c;GLM-4-9B函…

《手把手教你》系列練習篇之13-python+ selenium自動化測試 -壓軸篇(詳細教程)

1. 簡介 “壓軸”原本是戲曲名詞&#xff0c;指一場折子戲演出的倒數第二個劇目。在現代社會中有很多應用&#xff0c;比如“壓軸戲”&#xff0c;但壓軸也是人們知識的一個盲區。“壓軸”本意是指倒數第二個節目&#xff0c;而不是人們常說的倒數第一個&#xff0c;倒數第一個…

苗情生態自動監測站

TH-MQ1在現代農業發展中&#xff0c;苗情生態自動監測站的應用已經變得日益重要。這種技術不僅為農業生產提供了實時的數據支持&#xff0c;還通過精準監測和科學決策&#xff0c;提高了農業生產的效率和質量。 首先&#xff0c;苗情生態自動監測站的優勢在于其能夠實現精準監…

Java并發編程:線程與并發工具

Java并發編程:線程與并發工具 引言 在現代計算機程序中,并發編程是一個不可避免的主題。無論是提升應用程序性能,還是處理多個任務并發執行,Java為開發者提供了豐富的并發編程工具。在本篇文章中,我們將深入探討Java的并發編程,包括線程的基礎知識、線程池的使用以及常…

全流程透明雙語大語言模型MAP-Neo,4.5T 高質量數據訓練

前言 近年來&#xff0c;大語言模型 (LLM) 已經成為人工智能領域最熱門的研究方向之一&#xff0c;并在各種任務中展現出前所未有的性能。然而&#xff0c;由于商業利益的驅動&#xff0c;許多最具競爭力的模型&#xff0c;例如 GPT、Gemini 和 Claude&#xff0c;其訓練細節和…

讀書筆記-《軟件定義安全》之一:SDN和NFV:下一代網絡的變革

第1章 SDN和NFV&#xff1a;下一代網絡的變革 1.什么是SDN和NFV 1.1 SDN/NFV的體系結構 SDN SDN的體系結構可以分為3層&#xff1a; 基礎設施層由經過資源抽象的網絡設備組成&#xff0c;僅實現網絡轉發等數據平面的功能&#xff0c;不包含或僅包含有限的控制平面的功能。…

Unity Magica Cloth2 使用教程

視頻教程 參考文章 前提&#xff1a; 找到角色的模型 模之屋&#xff0c;我這里準備了轉好FBX格式的吟霖模型點擊自取【源自 模之屋】 角色舞蹈動畫 點擊下載【源自 Mixamo】 導入Unity【如何將原神的角色導入Unity】 三渲二 (必須是2022.3LTS和URP項目) Magica Cloth2 頭…

深入探索Stage #13:CSS層疊樣式表的IE特性偽協議注入

在網絡安全領域&#xff0c;跨站腳本攻擊&#xff08;XSS&#xff09;是一種常見的攻擊手段。隨著Web技術的不斷發展&#xff0c;攻擊者也在不斷探索新的攻擊途徑。本文將詳細介紹如何利用IE瀏覽器的特性&#xff0c;通過CSS層疊樣式表進行XSS攻擊。 實驗環境搭建 為了模擬IE…

spring boot 白盒測試實戰

假設項目中存在以下代碼&#xff1a; 常量類&#xff1a;public final static String NUMBER_REGEX "\\d"; service&#xff1a;return ReUtil.getGroup0(Constants.NUMBER_REGEX, waybill); 代碼解析 解釋&#xff1a; return ReUtil.getGroup0(Constants.NUMB…

python學習 - 使用OpenCV庫(cv2)和imutils庫實現輔助答題卡判別

測試數據見文章頂部位置資源&#xff01;&#xff01;&#xff01; 使用了OpenCV庫&#xff08;cv2&#xff09;和imutils庫。代碼的主要目的是處理圖像中的問題&#xff0c;如識別圖像中的文字&#xff0c;并對其進行分析和排序。 輔助答題卡判別 # -*- coding:utf-8 -*- fr…

python實現郵箱轟炸機

最近在學計算機網絡看到套接字的練習 于是應用SMTP協議寫了個發送郵箱的玩玩 可以發一大堆垃圾郵件給對方 其中參考了 關于發郵件報錯535 Error&#xff1a;authentication failed解決方法http://t.csdnimg.cn/Bc0Dq 已經查詢如何獲取網易郵箱客戶端授權碼 base64編碼 i…

Mybatis05-一對多和多對一處理

多對一和一對多 多對一 多對一的理解&#xff1a; 多個學生對應一個老師 如果對于學生這邊&#xff0c;就是一個多對一的現象&#xff0c;即從學生這邊關聯一個老師&#xff01; 結果映射&#xff08;resultMap&#xff09;&#xff1a; association 一個復雜類型的關聯&…

在線Logo背景去除:pixian.ai

文章目錄 簡介特色 簡介 pixian.ai是一款智能圖片背景去除工具&#xff0c;進入網頁后&#xff0c;會非常醒目地提示你準備【Free】還是【Paid】&#xff0c;這點就非常好&#xff0c;不向有一些網站&#xff0c;主打免費使用&#xff0c;但時不時彈出“免費注冊”&#xff0c…

【微信小程序】連接藍牙設備

1、檢查小程序是否授權藍牙功能 initBluetooth() {const that thiswx.getSetting({success: (res) > {if (res.authSetting.hasOwnProperty(scope.bluetooth)) {//scope.bluetooth屬性存在&#xff0c;且為falseif (!res.authSetting[scope.bluetooth]) {wx.showModal({tit…

Python 連接 MySQL 及 SQL增刪改查(主要使用sqlalchemy)

目錄 一、環境 二、MySQL的連接和使用 2.1方式一&#xff1a;sql為主 2.1.1創建連接 2.1.2 表結構 2.1.3 新增數據 ?編輯 2.1.4 查看數據 ?編輯 2.1.5 修改數據 2.1.6 刪除數據 2.2方式二&#xff1a;orm對象關系映射 2.2.1 mysql連接 2.2.2 創建表 2.2.3 新增…

windows 安裝pnpm

安裝Node.js&#xff1a; 確保系統上已安裝Node.js。pnpm需要Node.js來運行。如果尚未安裝Node.js&#xff0c;請從其官方網站下載并安裝適用于Windows的最新版本。 安裝pnpm&#xff1a; 打開命令行工具&#xff08;如CMD、PowerShell或Git Bash&#xff09;。使用npm&…