【Java開發】 Springboot集成Mybatis-Flex

1 Mybatis-Flex 介紹


1.1簡介

????????Mybatis-Flex 是一個優雅的?Mybatis 增強框架,它非常輕量、同時擁有極高的性能與靈活性。我們可以輕松的使用 Mybaits-Flex 鏈接任何數據庫,其內置的 QueryWrapper 亮點幫助我們極大的減少了 SQL 編寫的工作的同時,減少出錯的可能性。

1.2特征

????????1.輕量:除了 MyBatis,沒有任何第三方依賴、沒有任何攔截器,在執行的過程中,沒有任何的 Sql 解析(Parse)。 這帶來了幾個好處:極高的性能、極易對代碼進行跟蹤和調試、把控性更高。
????????2.靈活:支持 Entity 的增刪改查、以及分頁查詢的同時,MyBatis-Flex 提供了 Db + Row 工具,可以無需實體類對數據庫進行增刪改查以及分頁查詢。 與此同時,MyBatis-Flex 內置的 QueryWrapper 可以輕易的幫助我們實現 多表查詢、鏈接查詢、子查詢 等等常見的 SQL 場景。
????????3.強大:支持任意關系型數據庫,還可以通過方言持續擴展,同時支持 多(復合)主鍵、邏輯刪除、樂觀鎖配置、數據脫敏、數據審計、 數據填充 等等功能。


簡單來說,Mybatis-Flex 相比 Mybatis-Plus 等框架 速度更快、功能更多、代碼更簡潔~

1.3Mybatis-Flex和同類框架對比

1)功能對比:

2)性能對比:
這里直接貼測試結果:

MyBatis-Flex 的查詢單條數據的速度,大概是 MyBatis-Plus 的 5 ~ 10+ 倍。
MyBatis-Flex 的查詢 10 條數據的速度,大概是 MyBatis-Plus 的 5~10 倍左右。
Mybatis-Flex 的分頁查詢速度,大概是 Mybatis-Plus 的 5~10 倍左右。
Mybatis-Flex 的數據更新速度,大概是 Mybatis-Plus 的 5~10+ 倍。

?

2 準備工作

官方文檔:快速開始 - MyBatis-Flex

以?Spring Boot + Maven +?Mysql?項目做演示

2.1?數據庫中創建表及插入數據

此處省略~

2.2 Spring Boot 項目初始化

此時需要創建?Spring Boot?項目,并添加?Maven?依賴;此處我通過?IDEA?使用?Spring Initializer?快速初始化一個?Spring Boot?工程。

項目創建省略~

2.3 添加?Maven 主要依賴

往?pom.xml?文件中添加以下依賴。

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId></dependency><dependency><groupId>com.mybatis-flex</groupId><artifactId>mybatis-flex-spring-boot-starter</artifactId><version>1.7.3</version></dependency><dependency><groupId>com.mybatis-flex</groupId><artifactId>mybatis-flex-processor</artifactId><version>1.7.3</version><scope>provided</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><!--++++++++++++++++++++++++++++++++++++++++++++++++++++--><!-- MyBatis分頁插件 --><!--++++++++++++++++++++++++++++++++++++++++++++++++++++--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version><optional>true</optional></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-lang3</artifactId><version>3.12.0</version></dependency>

2.4?配置數據源

在?application.properties?或?application.yml?中配置數據源:


server.port=8999spring.application.name=mybatisPlusspring.datasource.username=root
spring.datasource.password=root3306
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_plus?useSSL=false&useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT%2B8
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

3?Mybatis-Flex 實踐

3.1?編寫實體類和 Mapper 接口

📌?User?實體類

  • 使用?@Table("flex_user")?設置實體類與表名的映射關系
  • 使用?@Id(keyType = KeyType.Auto)?標識主鍵為自增
package com.mybatisflex.flex.domain;import com.mybatisflex.annotation.Column;
import com.mybatisflex.annotation.Table;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;import java.io.Serializable;
import java.util.Date;/** */
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
//使用 @Table("tb_account") 設置實體類與表名的映射關系
@Table("user")
public class User implements Serializable {private Integer id;@Column(value = "name")private String name;@Column(value = "age")private Integer age;@Column(value = "email")private String email;@Column(value = "create_time", onInsertValue = "now()")private Date createTime;@Column(value = "update_time", onUpdateValue = "now()")private Date updateTime;@Column(value = "del_flag")private int delFlag;@Column(value = "dept_code")private String deptCode;
}

📌?Mapper 接口繼承 BaseMapper 接口

package com.mybatisflex.flex.mapper;import com.mybatisflex.core.BaseMapper;
import com.mybatisflex.flex.domain.User;/*** */
public interface UserMapper extends BaseMapper<User> {
}

3.2?在主啟動類添加 @MapperScan 注解

用于掃描?Mapper?文件夾:

package com.mybatisflex.flex;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
@MapperScan("com.mybatisflex.flex.mapper")
public class FlexApplication {public static void main(String[] args) {SpringApplication.run(FlexApplication.class, args);}}

3.3?創建service

package com.mybatisflex.flex.service;import com.mybatisflex.core.query.QueryWrapper;
import com.mybatisflex.core.update.UpdateChain;
import com.mybatisflex.flex.domain.User;
import com.mybatisflex.flex.domain.UserDto;
import com.mybatisflex.flex.domain.table.SysDeptTableDef;
import com.mybatisflex.flex.domain.table.UserTableDef;
import com.mybatisflex.flex.mapper.UserMapper;
import com.mybatisflex.spring.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;import java.util.List;/*** @Description:* @Date Create in 10:39 2023/11/22* @Modified By:*/@Service
public class UserService extends ServiceImpl<UserMapper, User> {/*** 查詢全部* @return*/public List<User> selectAll(){return this.getMapper().selectAll();}public List<User> selectList(){QueryWrapper wrapper = QueryWrapper.create()// 這里可以指定查詢字段.select()// sql from表名.from(User.class).where(User::getName).like("徐").or(UserTableDef.USER.ID.in(2,3).and(UserTableDef.USER.NAME.like("o")));return this.getMapper().selectListByQuery(wrapper);}/*** 根據userId獲取User數據* @param userId* @return*/public User listById(Integer userId){QueryWrapper wrapper = QueryWrapper.create()// 這里可以指定查詢字段.select()// sql from表名.from(User.class).where(User::getId).eq(userId).and(User::getName).like("徐");return this.getMapper().selectOneByQuery(wrapper);}/*** 關聯查詢--鏈式查詢*/public List<UserDto> getInfo(Integer userId){QueryWrapper query = QueryWrapper.create().select(UserTableDef.USER.ALL_COLUMNS).select(SysDeptTableDef.SYS_DEPT.DEPT_NAME).from(UserTableDef.USER).as("u").leftJoin(SysDeptTableDef.SYS_DEPT).as("d").on(UserTableDef.USER.DEPT_CODE.eq(SysDeptTableDef.SYS_DEPT.DEPT_CODE)).where(UserTableDef.USER.ID.eq(userId));return this.getMapper().selectListByQueryAs(query,UserDto.class);}/*** 新增* @param user*/public void insert(User user){this.getMapper().insert(user);}/*** 更新User* @param user*/public void updateEntity(User user){this.getMapper().update(user);}/*** 局部更新* @param userId* @param userName*/public void updateRow(Integer userId, String userName){UpdateChain.of(User.class).set(User::getName, userName).where(User::getId).eq(userId).update();}/*** 刪除* @param userName*/public void deleteByWrapper(String userName){QueryWrapper queryWrapper = QueryWrapper.create().where(User::getName).eq(userName);this.getMapper().deleteByQuery(queryWrapper);}}

3.4創建Controller接口測試

package com.mybatisflex.flex.controller;import com.mybatisflex.flex.domain.User;
import com.mybatisflex.flex.domain.UserDto;
import com.mybatisflex.flex.page.TableDataInfo;
import com.mybatisflex.flex.service.UserService;
import com.mybatisflex.flex.utils.ResponseUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import javax.annotation.Resource;
import java.util.List;/*** @Author: best_liu* @Description:* @Date Create in 10:33 2023/11/22* @Modified By:*/
@RestController
@RequestMapping("/user")
public class SysUserController {@Resourceprivate UserService userService;/*** 查詢全部* @return*/@GetMapping("listall")public List<User> listall(){return userService.selectAll();}/*** 分頁查詢* @return**/@GetMapping("/page")public TableDataInfo findPage() {ResponseUtils.startPage();return ResponseUtils.getDataTable(userService.selectAll());}/*** 按條件查詢* @return*/@GetMapping("getList")public List<User> selectList(){return userService.selectList();}/*** 按userId查詢* @return*/@GetMapping("listById")public User listById(){return userService.listById(0);}/*** 按userId關聯查詢部門* @return*/@GetMapping("getInfo")public List<UserDto> getInfo(){return userService.getInfo(0);}/*** 新增* @return*/@GetMapping("insert")public Boolean insert(){User user = User.builder().id(10).name("張三").age(100).email("zhangsan@163.com").build();userService.insert(user);return Boolean.TRUE;}/*** 更新* @return*/@GetMapping("update")public Boolean update(){userService.updateRow(10, "張三三");return Boolean.TRUE;}/*** 刪除* @return*/@GetMapping("delete")public Boolean delete(){userService.deleteByWrapper("張三三");return Boolean.TRUE;}
}

4 鏈式查詢

若想使用鏈式查詢還得需要?APT?配置,MyBatis-Flex?使用了?APT(Annotation Processing Tool)技術,在項目編譯的時候,會自動根據?Entity/pojo?類定義的字段幫你生成 "USER" 類(可用于鏈式查詢)

通過開發工具構建項目(如下圖),或者執行?maven?編譯命令:?mvn clean package?都可以自動生成。

正常情況下,會在?target?包下生成如下資源

若生成該資源并導入成功,那么此時,可使用鏈式查詢

/*** 關聯查詢*/public List<UserDto> getInfo(Integer userId){QueryWrapper query = QueryWrapper.create().select(UserTableDef.USER.ALL_COLUMNS).select(SysDeptTableDef.SYS_DEPT.DEPT_NAME).from(UserTableDef.USER).as("u").leftJoin(SysDeptTableDef.SYS_DEPT).as("d").on(UserTableDef.USER.DEPT_CODE.eq(SysDeptTableDef.SYS_DEPT.DEPT_CODE)).where(UserTableDef.USER.ID.eq(userId));return this.getMapper().selectListByQueryAs(query,UserDto.class);}

總的來說,MyBatis-Flex?的鏈式查詢相比?MyBatis-Plus?多了一步配置環節,目前來看其他步驟類似。

5?MyBatis-Flex/Plus?代碼對比

接下來看一下MyBatis-Flex??MyBatis-Plus?各部分功能代碼的差別,Employee、Account、Article 都是實體類。

5.1?基礎查詢

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().where(EMPLOYEE.LAST_NAME.like(searchWord)) //條件為null時自動忽略.and(EMPLOYEE.GENDER.eq(1)).and(EMPLOYEE.AGE.gt(24));
List<Employee> employees = employeeMapper.selectListByQuery(query);

MyBatis-Plus:

QueryWrapper<Employee> queryWrapper = Wrappers.query().like(searchWord != null, "last_name", searchWord).eq("gender", 1).gt("age", 24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);//lambda 寫法:
LambdaQueryWrapper<Employee> queryWrapper = Wrappers.<Employee>lambdaQuery().like(StringUtils.isNotEmpty(searchWord), Employee::getUserName,"B").eq(Employee::getGender, 1).gt(Employee::getAge, 24);
List<Employee> employees = employeeMapper.selectList(queryWrapper);

5.2 集合查詢

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().select(ACCOUNT.ID,ACCOUNT.USER_NAME,max(ACCOUNT.BIRTHDAY),avg(ACCOUNT.SEX).as("sex_avg"));
List<Employee> employees = employeeMapper.selectListByQuery(query);

MyBatis-Plus:

QueryWrapper<Employee> queryWrapper = Wrappers.query().select("id","user_name","max(birthday)","avg(birthday) as sex_avg");
List<Employee> employees = employeeMapper.selectList(queryWrapper);

缺點:字段硬編碼,容易拼錯。無法使用 IDE 的字段進行重構,無法使用 IDE 自動提示,發生錯誤不能及時發現,不過MyBatis-Plus的?lambdawrapper?也是能解決這個問題。

5.3 and(...) 和 or(...)

假設我們要構建如下的 SQL 進行查詢(需要在 SQL 中添加括號)。

SELECT * FROM tb_account
WHERE id >= 100
AND (sex = 1 OR sex = 2)
OR (age IN (18,19,20) AND user_name LIKE "%michael%" )

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().where(ACCOUNT.ID.ge(100)).and(ACCOUNT.SEX.eq(1).or(ACCOUNT.SEX.eq(2))).or(ACCOUNT.AGE.in(18, 19, 20).and(ACCOUNT.USER_NAME.like("michael")));

MyBatis-Plus:

QueryWrapper<Employee> query = Wrappers.query().ge("id", 100).and(i -> i.eq("sex", 1).or(x -> x.eq("sex", 2))).or(i -> i.in("age", 18, 19, 20).like("user_name", "michael"));
// or lambda
LambdaQueryWrapper<Employee> query = Wrappers.<Employee>lambdaQuery().ge(Employee::getId, 100).and(i -> i.eq(Employee::getSex, 1).or(x -> x.eq(Employee::getSex, 2))).or(i -> i.in(Employee::getAge, 18, 19, 20).like(Employee::getUserName, "michael"));

5.4 多表查詢

MyBatis-Flex:

QueryWrapper query = QueryWrapper.create().select().from(ACCOUNT).leftJoin(ARTICLE).on(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID)).where(ACCOUNT.AGE.ge(10));List<Account> accounts = mapper.selectListByQuery(query);
QueryWrapper query = new QueryWrapper()
.select(ACCOUNT.ID, ACCOUNT.USER_NAME, ARTICLE.ID.as("articleId"), ARTICLE.TITLE)
.from(ACCOUNT.as("a"), ARTICLE.as("b"))
.where(ACCOUNT.ID.eq(ARTICLE.ACCOUNT_ID));

MyBatis-Plus:不支持

5.5?部分字段更新

假設一個實體類?Account?中,我們要更新其內容如下:

  • userName?為 "michael"
  • age?為 "18"
  • birthday?為 null

其他字段保持數據庫原有內容不變,要求執行的 SQL 如下:

update tb_account
set user_name = "michael", age = 18, birthday = null
where id = 100

MyBatis-Flex?代碼如下:

Account account = UpdateEntity.of(Account.class);
account.setId(100); //設置主鍵
account.setUserName("michael");
account.setAge(18);
account.setBirthday(null);accountMapper.update(account);

MyBatis-Plus?代碼如下(或可使用?MyBatis-Plus?的 LambdaUpdateWrapper,但性能沒有 UpdateWrapper 好):

UpdateWrapper<Account> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("id", 100);
updateWrapper.set("user_name", "michael");
updateWrapper.set("age", 18);
updateWrapper.set("birthday", null);accountMapper.update(null, updateWrapper);

如上,MyBatis-Flex?在代碼編寫來說更加靈活,編寫方式更多一些,還是有些優勢。

源碼地址:https://download.csdn.net/download/askuld/88561026?

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

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

相關文章

cocos2dx ??Animate3D(二)

Twirl 扭曲旋轉特效 // 持續時間(時間過后不會回到原來的樣子) // 整個屏幕被分成幾行幾列 // 扭曲中心位置 // 扭曲的數量 // 振幅 static Twirl* create(float duration, const Size& gridSize, const Vec2& position, unsigned int twirls, float amplitude)…

編程語言發展史:C語言的誕生及其影響

預計更新 第一部分&#xff1a;早期編程語言 1.1布爾代數和機器語言 1.2匯編語言的出現和發展 1.3高級語言的興起 第二部分&#xff1a;主流編程語言 1.1 C語言的誕生及其影響 1.2 C語言的發展和應用 1.3 Java語言的出現和發展 1.4 Python語言的興起和特點 1.5 JavaScript語言…

基于springboot實現攝影跟拍預定管理系統【項目源碼+論文說明】計算機畢業設計

基于springboot實現攝影跟拍預定管理系統演示 摘要 首先,論文一開始便是清楚的論述了系統的研究內容。其次,剖析系統需求分析,弄明白“做什么”,分析包括業務分析和業務流程的分析以及用例分析,更進一步明確系統的需求。然后在明白了系統的需求基礎上需要進一步地設計系統,主要…

【2018年數據結構真題】

方法一 給定一個含n(n>1)個整數的數組&#xff0c;請設計一個在時間上盡可能高效的算法&#xff0c;找出數組中未出現的最小正整數。例如&#xff0c;數組{-5&#xff0c;3&#xff0c;2&#xff0c;3}中未出現的最小正整數是1&#xff1b;數組{1&#xff0c;2&#xff0c;…

AIGC變革BI行業,永洪發布vividime全球化品牌

大數據產業創新服務媒體 ——聚焦數據 改變商業 國內BI商業智能市場&#xff0c;一直有著“內永洪&#xff0c;外Tableau”的說法。成立于2012年的永洪科技經過十多年的發展&#xff0c;早已崛起為國內大數據行業的一支勁旅。 ChatGPT火爆出圈之后&#xff0c;AIGC快速滲透&am…

每日一練 | 華為認證真題練習Day19

Day19 華為認證中級考試真題 1、DHCP協議運行過程中&#xff0c;客戶端從申請到IP地址時的流程是 A.1-2-3-4 B.1-4-3-2 C.3-2-1-4 D.3-4-1-2 2、VRRP報文的IP協議號是&#xff1a; A.112 B.114 C.116 D.118 3、MPLS的標簽字段共有多少bit? A.8 B.3 C.1 D.20 4…

【C++】vector的介紹與使用

&#x1f9d1;?&#x1f393;個人主頁&#xff1a;簡 料 &#x1f3c6;所屬專欄&#xff1a;C &#x1f3c6;個人社區&#xff1a;越努力越幸運社區 &#x1f3c6;簡 介&#xff1a;簡料簡料&#xff0c;簡單有料~在校大學生一枚&#xff0c;專注C/C/GO的干貨分…

2020年下半年試題一:論信息系統項目的成本管理

論文題目 1.概要敘述你參與過的信息系統項目&#xff08;項目的背景、項目規模、發起單位、目的、項目內容、組織結構、項目周期、交付的成果等&#xff09;&#xff0c;并說明你在其中承擔的工作&#xff08;項目背景要求本人真實經歷&#xff0c;不得抄襲及杜撰&#xff09;。…

編程語言發展史:匯編語言的出現和發展

一、匯編語言的出現 隨著計算機硬件的發展&#xff0c;機器語言變得越來越復雜&#xff0c;難以被人類程序員理解和編寫。因此&#xff0c;出現了更高級別的編程語言&#xff0c;這些語言使用類似英語的語法&#xff0c;使程序員能夠更容易地編寫和維護程序。 其中一種高級語…

web網頁滲透測試

web網頁滲透測試 流程 信息收集網站掃描訪問控制測試漏洞掃描嘗試注入攻擊驗證漏洞后滲透測試滲透測試報告 信息收集 收集目標網站的基本信息&#xff0c;包括域名、IP 地址、子域名等。使用 WHOIS 查詢、搜索引擎、子域名枚舉工具等進行信息收集。 網站掃描 使用端口掃描…

【Java 進階篇】Redis 數據結構:輕松駕馭多樣性

引言 Redis是一款強大的鍵值對存儲系統&#xff0c;其數據結構的多樣性是其引以為傲的特點之一。在這篇博客中&#xff0c;我們將深入探討Redis的主要數據結構&#xff0c;包括字符串、哈希表、列表、集合和有序集合&#xff0c;并通過實例代碼演示它們的用法。 1. 字符串&am…

在中國企業出海的大浪潮下,亞馬遜云科技提供遍及全球的基礎設施和技術支持

中國技術出海是中國企業更高層次更高質量的全球化。在人類文明發展史上&#xff0c;凝聚中國古人智慧結晶的造紙術、印刷術、火藥、指南針等&#xff0c;曾為中國技術出海寫下過濃墨重彩的一筆。在今天&#xff0c;如金山辦公、店匠科技、ADVANCE.AI等公司又以技術立業&#xf…

msvcp140.dll是什么?msvcp140.dll丟失的有哪些解決方法

在計算機使用過程中&#xff0c;我們經常會遇到一些錯誤提示&#xff0c;其中之一就是“msvcp140.dll丟失”。這個錯誤通常會導致某些應用程序無法正常運行。為了解決這個問題&#xff0c;我們需要采取一些措施來修復丟失的msvcp140.dll文件。本文將詳細介紹5個解決msvcp140.dl…

Day27|Leetcode 39. 組合總和 Leetcode 40. 組合總和 II Leetcode131. 分割回文串

Leetcode 39. 組合總和 題目鏈接 39 組合總和 本題目和前面的組合問題差不多&#xff0c;只不過這里能重復選取數字&#xff0c;還是要注意組合的定義&#xff0c;交換數字順序還是算一個組合&#xff0c;所以這里還是用我們的startIndex來記錄取的數字到哪里了&#xff0c;下…

阿里云發送短信

官方代碼如下&#xff1a; // This file is auto-generated, dont edit it. Thanks. package com.aliyun.sample;import com.aliyun.tea.*;public class Sample {/*** 使用AK&SK初始化賬號Client* param accessKeyId* param accessKeySecret* return Client* throws Excep…

【電子通識】USB3.0和USB2.0有什么區別?

版本 USB2.0是2000年4月27日由USB-IF組織提出了USB2.0總線協議規范。 USB3.0是2008年11月17日由USB-IF組織提出了超高速USB3.0規范。 圖標對比 USB2.0的標志就是和USB1.1的標志基本上沒啥區別&#xff0c;還是以前的那個樣子&#xff0c;使用黑色顏色用標識 USB3.0它有一個S…

計算機畢業設計 基于微信小程序的“共享書角”圖書借還管理系統的設計與實現 Java實戰項目 附源碼+文檔+視頻講解

博主介紹&#xff1a;?從事軟件開發10年之余&#xff0c;專注于Java技術領域、Python人工智能及數據挖掘、小程序項目開發和Android項目開發等。CSDN、掘金、華為云、InfoQ、阿里云等平臺優質作者? &#x1f345;文末獲取源碼聯系&#x1f345; &#x1f447;&#x1f3fb; 精…

pycurl>=7.43.0.5機器學習環境配置問題

去官網下載對應版本.whl文件&#xff0c;注意使用python --version提前查看 python版本信息和64bit還是32bit,下載對應版本。 cd 到該路徑下&#xff0c;并pip。6

opengl制作天空盒

首先創建頂點數組 unsigned int m_uiVaoBufferID; glGenVertexArrays(1, &m_uiVaoBufferID); 然后創建頂點緩沖區 float skyboxVertices[] {// positions-1.0f, 1.0f, -1.0f,-1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f,1.0f, -1.0f, -1.0f,1.0f, 1.0f, -1.0f,-1.0f, 1.…

當npm下載庫失敗時可以用cnpm替代

下載cnpm npm install -g cnpm --registryhttp://registry.npmmirror.com 然后使用cnpm代替npm下載即可 cnpm install