主頁 > 後端開發 > MyBatis常見問題

MyBatis常見問題

2023-04-08 07:26:11 後端開發

Mybatis常見問題

1,大于號、小于號在sql陳述句中的轉換

使用 mybatis 時 sql 陳述句是寫在 xml 檔案中,如果 sql 中有一些特殊的字符的話,比如< ,<=,>,>=等符號,會引起 xml 格式的錯誤,需要替換掉,或者不被轉義, 有兩種方法可以解決:轉義字符和標記 CDATA 塊,

方式一:轉義字符

<select id="searchByPrice" parameterType="Map" resultType="Product">
    <!-- 方式1、轉義字符 -->
    select * from Product where price &gt;= #{minPrice} and price &lt;= #{maxPrice}
 </select>

方式二:標記CDATA

<select id="searchByPrice" parameterType="Map" resultType="Product">
   <!-- 方式2、CDATA -->
  <![CDATA[select * from Product where price >= #{minPrice} and price <= #{maxPrice} ]]> </select>

轉義字符表

2.傳入引數時引數為0查詢條件失效

場景案例

場景是這樣的,需要做一個對賬單查詢,可以按金額范圍進行查詢,頁面引數寫完之后進行條件,輸入0測驗了無數次均失效,

原因決議

當頁面引數為0,傳入到mybatis的xml中后,如果不是字串,需指定資料型別,否則會被誤認為null

<if test="data.tatalAmount != null and data.totalAmount !='' ">
and total_Amount=#{data.totalAmount}
</if>

這種情況如果totalAmount為0時將被誤認為是null,里面的條件不會被執行,

解決方案

1,添加0判斷

<if test="data.tatalAmount != null and data.totalAmount !='' or tatalAmount==0 ">
and total_Amount=#{data.totalAmount}
</if>

2,規定傳入引數的型別

<if test="data.tatalAmount != null and data.totalAmount !='' ">
and total_Amount=#{data.totalAmount,jdbc.Type=DECIMAL}
</if>

3,Mybatis中#{}和${}區別

#{}是預編譯處理,像傳進來的資料會加個" "(#將傳入的資料都當成一個字串,會對自動傳入的資料加一個雙引號)

${}就是字串拼接,直接替換掉占位符,$方式一般用于傳入資料庫物件,例如傳入表名,

使用${}的話會導致sql注入,什么是sql注入呢?比如select * from user where id = #{value}

value本應該是一個數值,然后如果對方傳過來的是 001 and name = tom.這樣不就相當于多加了一條sql陳述句進去,

把SQL陳述句直接寫進來了,如果是攻擊性的陳述句呢?001;drop table user,直接把表給刪了

所以為了防止 SQL 注入,能用 #{} 的不要去用 ${}

 

如果非要用 ${} 的話,那要注意防止 SQL 注入問題,可以手動判定傳入的變數,進行過濾,一般 SQL 注入會輸入很長的一條 SQL 陳述句

4,Mybatis動態sql陳述句(OGNL語法)

1、if

解決當要查詢的多個條件有一個為空而導致的查詢結果為空的情況

<select id="select" resultType="Blog">
  SELECT * FROM BLOG
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like #{title}
  </if>
  <if test="name!= null">
    AND name like #{title}
  </if>
</select>

2、where

像上面的那種情況,如果where后面沒有條件,然后需要直接寫if判斷(開頭如果是 and / or 的話,會去除掉)

<select id="select" resultType="Blog">
  SELECT * FROM BLOG
  <where>
      <if test="title != null">
        AND title like #{title}
      </if>
      <if test="name!= null">
        AND name like #{title}
      </if>
  <where>
</select>

3、choose(when、otherwise)

choose 相當于 java 里面的 switch 陳述句,otherwise(其他情況)

<select id="findActiveBlogLike" resultType="Blog">
  SELECT * FROM BLOG WHERE state = ‘ACTIVE’
  <choose>
    <when test="title != null">
      AND title like #{title}
    </when>
    <when test="author != null and author.name != null">
      AND author_name like #{author.name}
    </when>
    <otherwise>
      AND featured = 1
    </otherwise>
  </choose>
</select>

4、trim

prefix:前綴prefixoverride:去掉第一個and或者是or

select * from test
<trim prefix="WHERE" prefixoverride="AND丨OR">
      <if test="a!=null and a!=' '">AND a=#{a}<if>
      <if test="b!=null and b!=' '">AND a=#{a}<if>
</trim>

 

5、set

set 元素主要是用在更新操作的時候,如果包含的陳述句是以逗號結束的話將會把該逗號忽略,如果set包含的內容為空的話則會出錯,

<update id="dynamicSetTest" parameterType="Blog">  
    update t_blog  
    <set>  
        <if test="title != null">  
            title = #{title},  
        </if>  
        <if test="content != null">  
            content = #{content},  
        </if>  
        <if test="owner != null">  
            owner = #{owner}  
        </if>  
    </set>  
    where id = #{id}  
</update> 

6、foreach

foreach主要用在構建in條件中

<select id="dynamicForeachTest" resultType="Blog">  
        select * from t_blog where id in  
        <foreach collection="list" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  

open separator close

相當于是in (?,?,?)

如果是個map怎么辦

<select id="dynamicForeach3Test" resultType="Blog">  
        select * from t_blog where title like "%"#{title}"%" and id in  
        <foreach collection="ids" index="index" item="item" open="(" separator="," close=")">  
            #{item}  
        </foreach>  
    </select>  

collection對應map的鍵,像這樣

List<Integer> ids = new ArrayList<Integer>();  
        ids.add(1);  
        ids.add(2);  
        ids.add(3);  
        ids.add(6);  
        ids.add(7);  
        ids.add(9);  
        Map<String, Object> params = new HashMap<String, Object>();  
        params.put("ids", ids);  

5,Like模糊查詢

方式一

$ 這種方式,簡單,但是無法防止SQL注入,所以不推薦使用

LIKE '%${name}%'

方式二

LIKE "%"#{name}"%"

方式三:字串拼接

AND name LIKE CONCAT(CONCAT('%',#{name},'%'))

方式四:bind標簽

 

<select id="searchStudents" resultType="com.example.entity.StudentEntity"
  parameterType="com.example.entity.StudentEntity">
  <bind name="pattern1" value="'%' + _parameter.name + '%'" />
  <bind name="pattern2" value="'%' + _parameter.address + '%'" />
  SELECT * FROM test_student
  <where>
   <if test="age != null and age != '' and compare != null and compare != ''">
    age
    ${compare}
    #{age}
   </if>
   <if test="name != null and name != ''">
    AND name LIKE #{pattern1}
   </if>
   <if test="address != null and address != ''">
    AND address LIKE #{pattern2}
   </if>
  </where>
  ORDER BY id
 </select>

6,傳遞多個引數

方法一:使用map介面傳遞引數

嚴格來說,map適用幾乎所有場景,但是我們用得不多,原因有兩個:首先,map是一個鍵值對應的集合,使用者要通過閱讀它的鍵,才能明了其作用;其次,使用map不能限定其傳遞的資料型別,因此業務性質不強,可讀性差,使用者要讀懂代碼才能知道需要傳遞什么引數給它,所以不推薦用這種方式傳遞多個引數,

public List<Role> findRolesByMap(Map<String, Object> parameterMap);
<select id="findRolesByMap" parameterType="map" resultType="role">
    select id, role_name as roleName, note from t_role where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note}, '%')
</select>

方法二:使用注解傳遞多個引數  

MyBatis為開發者提供了一個注解@Param(org.apache.ibatis.annotations.Param),可以通過它去定義映射器的引數名稱,使用它可以得到更好的可讀性  這個時候需要修改映射檔案的代碼,此時并不需要給出parameterType屬性,讓MyBatis自動探索便可以了  使可讀性大大提高,使用者也方便了,但是這會帶來一個麻煩,如果SQL很復雜,擁有大于10個引數,那么介面方法的引數個數就多了,使用起來就很不容易,不過不必擔心,MyBatis還提供傳遞Java Bean的形式,

public List<Role> findRolesByAnnotation(@Param("roleName") String rolename, @Param("note") String note);
<select id="findRolesByAnnotation" resultType="role">
    select id, role_name as roleName, note from t_role where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note}, '%')
</select>

方法三:通過Java Bean傳遞多個引數

public List<Role> findRolesByBean(RoleParams roleParam);
<select id="findRolesByBean" parameterType="com.xc.pojo.RoleParams" resultType="role">
    select id, role_name as roleName, note from t_role where role_name like concat('%', #{roleName}, '%') and note like concat('%', #{note}, '%')
</select>

方法四:混合使用  

在某些情況下可能需要混合使用幾種方法來傳遞引數,舉個例子,查詢一個角色,可以通過角色名稱和備注進行查詢,與此同時還需要支持分頁

public List<Role> findByMix(@Param("params") RoleParams roleParams, @Param("page") PageParam PageParam);
<select id="findByMix" resultType="role">
    select id, role_name as roleName, note from t_role
    where role_name like concat('%', #{params.roleName}, '%') and note like concat('%', #{params.note}, '%') 
     limit #{page.start}, #{page.limit}
</select>

 

總結:

描述了4種傳遞多個引數的方法,對各種方法加以點評和總結,以利于我們在實際操作中的應用,

  ?使用 map 傳遞引數導致了業務可讀性的喪失,導致后續擴展和維護的困難,在實際的應用中要果斷廢棄這種方式,

  ?使用 @Param 注解傳遞多個引數,受到引數個數(n)的影響,當 n≤5 時,這是最佳的傳參方式,它比用 Java Bean 更好,因為它更加直觀;當 n>5 時,多個引數將給呼叫帶來困難,此時不推薦使用它,

  ?當引數個數多于5個時,建議使用 Java Bean 方式,

  ?對于使用混合引數的,要明確引數的合理性,

7,MyBatis快取機制

快取機制減輕資料庫壓力,提高資料庫性能

mybatis的快取分為兩級:一級快取、二級快取

一級快取:

一級快取為 SqlSession 快取,快取的資料只在 SqlSession 內有效,在操作資料庫的時候需要先創建 SqlSession 會話物件,在物件中有一個 HashMap 用于存盤快取資料,此 HashMap 是當前會話物件私有的,別的 SqlSession 會話物件無法訪問,

具體流程:

第一次執行 select 完畢會將查到的資料寫入 SqlSession 內的 HashMap 中快取起來

第二次執行 select 會從快取中查資料,如果 select 同傳引數一樣,那么就能從快取中回傳資料,不用去資料庫了,從而提高了效率

注意:

1、如果 SqlSession 執行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就會清空當前 SqlSession 快取中的所有快取資料,這樣可以保證快取中的存的資料永遠和資料庫中一致,避免出現差異

2、當一個 SqlSession 結束后那么他里面的一級快取也就不存在了, mybatis 默認是開啟一級快取,不需要配置

3、 mybatis 的快取是基于 [namespace:sql陳述句:引數] 來進行快取的,意思就是, SqlSession 的 HashMap 存盤快取資料時,是使用 [namespace:sql:引數] 作為 key ,查詢回傳的陳述句作為 value 保存的

二級快取:

二級快取是mapper 級別的快取,也就是同一個 namespace 的 mapper.xml ,當多個 SqlSession 使用同一個 Mapper 操作資料庫的時候,得到的資料會快取在同一個二級快取區域

二級快取默認是沒有開啟的,需要在 setting 全域引數中配置開啟二級快取

開啟二級快取步驟:

1、conf.xml 配置全域變數開啟二級快取

<settings>
    <setting name="cacheEnabled" value="https://www.cnblogs.com/yaomagician/archive/2023/04/07/true"/>默認是false:關閉二級快取
<settings>

2、在userMapper.xml中配置

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>當前mapper下所有陳述句開啟二級快取

這里配置了一個 FIFO快取,并每隔60秒重繪,最大存盤512個物件,而回傳的物件是只讀的,因此在不同執行緒中的呼叫者之間修改它們會導致沖突,可用的識訓策略有,默認的是LRU

 

  1. LRU- 最近最少使用的;移除最長時間不被使用的物件,

  2. FIFO- 先進先出;按物件進入快取的順序來移除它們,

  3. SOFT- 軟參考;移除基于垃圾回收器狀態和軟參考規則的物件

  4. WEAK- 弱參考;更積極地移除基干垃圾收集器狀態和弱參考規則的物件

 

若想禁用當前select陳述句的二級快取,添加 useCache="false"修改如下:

<select id="getCountByName" parameterType="java.util.Map" resultType="INTEGER" statementType="CALLABLE" useCache="false">

具體流程:

1.當一個sqlseesion執行了一次select 后,在關閉此session 的時候,會將查詢結果快取到二級快取

2.當另一個sqlsession執行select 時,首先會在他自己的一級快取中找,如果沒找到,就回去二級快取中找,找到了就回傳,就不用去資料庫了,從而減少了資料庫壓力提高了性能

注意:

1、如果 SqlSession 執行了 DML 操作(insert、update、delete),并 commit 了,那么 mybatis 就會清空當前mapper 快取中的所有快取資料,這樣可以保證快取中的存的資料永遠和資料庫中一致,避免出現差異

2、mybatis 的一級快取是基于[namespace:sql陳述句:引數]來進行快取的,意思就是,SqlSessionHashMap 存盤快取資料時,是使用 [namespace:sql:引數]作為 key ,查詢回傳的陳述句作為 value 保存的,

是否應該使用二級快取?

那么究竟應該不應該使用二級快取呢?先來看一下二級快取的注意事項:

  1. 快取是以namespace為單位的,不同namespace下的操作互不影響,

  2. insert,update,delete操作會清空所在namespace下的全部快取,

  3. 通常使用MyBatis Generator生成的代碼中,都是各個表獨立的,每個表都有自己的namespace

  4. 多表操作一定不要使用二級快取,因為多表操作進行更新操作,一定會產生臟資料,

如果你遵守二級快取的注意事項,那么你就可以使用二級快取,

但是,如果不能使用多表操作,二級快取不就可以用一級快取來替換掉嗎?而且二級快取是表級快取,開銷大,沒有一級快取直接使用 HashMap 來存盤的效率更高,所以二級快取并不推薦使用

8,MyBatis時間timestamp做條件進行查詢

首先要將條件 轉換為 時間戳

long startTime = TimeUtil.parseTimestamp(start);
long endTime = TimeUtil.parseTimestamp(end);
 
/*對應工具類*/
public static long parseTimestamp(String datetime){
    try{
    SimpleDateFormat dateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    Date date = dateformat.parse(datetime);
    return date.getTime()/1000;         
    }catch(Exception e){
        e.printStackTrace();
    }
    return 0;
}

然后Mapper.xml中 使用BETWEEN and 和 to_timestamp

<if test="startDate !=null and startDate !='' and endDate !=null and endDate !=''">
            AND tdnm.create_time BETWEEN to_timestamp(#{startDate}) AND to_timestamp(#{endDate})
</if>

9,mybatis 是否支持延遲加載?延遲加載的原理是什么?

1.MyBatis 支持延遲加載,

2.什么是延遲加載:延遲加載,也稱為懶加載,是指在進行關聯查詢時,按照設定延遲規則推遲對關聯物件的select查詢,延遲加載可以有效的減少資料庫壓力,MyBatis的延遲加載只是對關聯物件的查詢有延遲設定,對于主加載物件都是直接執行查詢陳述句的,

3.MyBatis 對關聯物件的加載型別

(1)直接加載:執行完對主加載物件的select陳述句,馬上執行對關聯物件的select查詢,

(2)侵入式延遲:執行對主加載物件的查詢時,不會執行對關聯物件的查詢,但當要訪問主加載物件的詳情時,就會馬上執行關聯物件的select查詢,(將關聯物件的詳情作為主加載物件的詳情的一部分出現)

(3)深度延遲:執行對主加載物件的查詢時,不會執行對關聯物件的查詢,訪問主加載物件的詳情時也不會執行關聯物件的select查詢,只有當真正訪問關聯物件的詳情時,才會執行對關聯物件的select查詢,

4.延遲加載的原理:呼叫的時候觸發加載,而不是在初始化的時候就加載資訊

例如:呼叫 a. getB(). getName(),這個時候發現 a. getB() 的值為 null,此時會單獨觸發事先保存好的關聯 B 物件的 SQL,先查詢出來 B,然后再呼叫 a. setB(b),而這時候再呼叫 a. getB(). getName() 就有值了

轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/549399.html

標籤:其他

上一篇:day05-SpringCloud Eureka-服務注冊與發現02

下一篇:odoo 開發入門教程系列-約束(Constraints)

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 【C++】Microsoft C++、C 和匯編程式檔案

    ......

    uj5u.com 2020-09-10 00:57:23 more
  • 例外宣告

    相比于斷言適用于排除邏輯上不可能存在的狀態,例外通常是用于邏輯上可能發生的錯誤。 例外宣告 Item 1:當函式不可能拋出例外或不能接受拋出例外時,使用noexcept 理由 如果不打算拋出例外的話,程式就會認為無法處理這種錯誤,并且應當盡早終止,如此可以有效地阻止例外的傳播與擴散。 示例 //不可 ......

    uj5u.com 2020-09-10 00:57:27 more
  • Codeforces 1400E Clear the Multiset(貪心 + 分治)

    鏈接:https://codeforces.com/problemset/problem/1400/E 來源:Codeforces 思路:給你一個陣列,現在你可以進行兩種操作,操作1:將一段沒有 0 的區間進行減一的操作,操作2:將 i 位置上的元素歸零。最終問:將這個陣列的全部元素歸零后操作的最少 ......

    uj5u.com 2020-09-10 00:57:30 more
  • UVA11610 【Reverse Prime】

    本人看到此題沒有翻譯,就附帶了一個自己的翻譯版本 思考 這一題,它的第一個要求是找出所有 $7$ 位反向質數及其質因數的個數。 我們應該需要質數篩篩選1~$10^{7}$的所有數,這里就不慢慢介紹了。但是,重讀題,我們突然發現反向質數都是 $7$ 位,而將它反過來后的數字卻是 $6$ 位數,這就說明 ......

    uj5u.com 2020-09-10 00:57:36 more
  • 統計區間素數數量

    1 #pragma GCC optimize(2) 2 #include <bits/stdc++.h> 3 using namespace std; 4 bool isprime[1000000010]; 5 vector<int> prime; 6 inline int getlist(int ......

    uj5u.com 2020-09-10 00:57:47 more
  • C/C++編程筆記:C++中的 const 變數詳解,教你正確認識const用法

    1、C中的const 1、區域const變數存放在堆疊區中,會分配記憶體(也就是說可以通過地址間接修改變數的值)。測驗代碼如下: 運行結果: 2、全域const變數存放在只讀資料段(不能通過地址修改,會發生寫入錯誤), 默認為外部聯編,可以給其他源檔案使用(需要用extern關鍵字修飾) 運行結果: ......

    uj5u.com 2020-09-10 00:58:04 more
  • 【C++犯錯記錄】VS2019 MFC添加資源不懂如何修改資源宏ID

    1. 首先在資源視圖中,添加資源 2. 點擊新添加的資源,復制自動生成的ID 3. 在解決方案資源管理器中找到Resource.h檔案,編輯,使用整個專案搜索和替換的方式快速替換 宏宣告 4. Ctrl+Shift+F 全域搜索,點擊查找全部,然后逐個替換 5. 為什么使用搜索替換而不使用屬性視窗直 ......

    uj5u.com 2020-09-10 00:59:11 more
  • 【C++犯錯記錄】VS2019 MFC不懂的批量添加資源

    1. 打開資源頭檔案Resource.h,在其中預先定義好宏 ID(不清楚其實ID值應該設定多少,可以先新建一個相同的資源項,再在這個資源的ID值的基礎上遞增即可) 2. 在資源視圖中選中專案資源,按F7編輯資源檔案,按 ID 型別 相對路徑的形式添加 資源。(別忘了先把檔案拷貝到專案中的res檔案 ......

    uj5u.com 2020-09-10 01:00:19 more
  • C/C++編程筆記:關于C++的參考型別,專供新手入門使用

    今天要講的是C++中我最喜歡的一個用法——參考,也叫別名。 參考就是給一個變數名取一個變數名,方便我們間接地使用這個變數。我們可以給一個變數創建N個參考,這N + 1個變數共享了同一塊記憶體區域。(參考型別的變數會占用記憶體空間,占用的記憶體空間的大小和指標型別的大小是相同的。雖然參考是一個物件的別名,但 ......

    uj5u.com 2020-09-10 01:00:22 more
  • 【C/C++編程筆記】從頭開始學習C ++:初學者完整指南

    眾所周知,C ++的學習曲線陡峭,但是花時間學習這種語言將為您的職業帶來奇跡,并使您與其他開發人員區分開。您會更輕松地學習新語言,形成真正的解決問題的技能,并在編程的基礎上打下堅實的基礎。 C ++將幫助您養成良好的編程習慣(即清晰一致的編碼風格,在撰寫代碼時注釋代碼,并限制類內部的可見性),并且由 ......

    uj5u.com 2020-09-10 01:00:41 more
最新发布
  • Rust中的智能指標:Box<T> Rc<T> Arc<T> Cell<T> RefCell<T> Weak

    Rust中的智能指標是什么 智能指標(smart pointers)是一類資料結構,是擁有資料所有權和額外功能的指標。是指標的進一步發展 指標(pointer)是一個包含記憶體地址的變數的通用概念。這個地址參考,或 ” 指向”(points at)一些其 他資料 。參考以 & 符號為標志并借用了他們所 ......

    uj5u.com 2023-04-20 07:24:10 more
  • Java的值傳遞和參考傳遞

    值傳遞不會改變本身,參考傳遞(如果傳遞的值需要實體化到堆里)如果發生修改了會改變本身。 1.基本資料型別都是值傳遞 package com.example.basic; public class Test { public static void main(String[] args) { int ......

    uj5u.com 2023-04-20 07:24:04 more
  • [2]SpinalHDL教程——Scala簡單入門

    第一個 Scala 程式 shell里面輸入 $ scala scala> 1 + 1 res0: Int = 2 scala> println("Hello World!") Hello World! 檔案形式 object HelloWorld { /* 這是我的第一個 Scala 程式 * 以 ......

    uj5u.com 2023-04-20 07:23:58 more
  • 理解函式指標和回呼函式

    理解 函式指標 指向函式的指標。比如: 理解函式指標的偽代碼 void (*p)(int type, char *data); // 定義一個函式指標p void func(int type, char *data); // 宣告一個函式func p = func; // 將指標p指向函式func ......

    uj5u.com 2023-04-20 07:23:52 more
  • Django筆記二十五之資料庫函式之日期函式

    本文首發于公眾號:Hunter后端 原文鏈接:Django筆記二十五之資料庫函式之日期函式 日期函式主要介紹兩個大類,Extract() 和 Trunc() Extract() 函式作用是提取日期,比如我們可以提取一個日期欄位的年份,月份,日等資料 Trunc() 的作用則是截取,比如 2022-0 ......

    uj5u.com 2023-04-20 07:23:45 more
  • 一天吃透JVM面試八股文

    什么是JVM? JVM,全稱Java Virtual Machine(Java虛擬機),是通過在實際的計算機上仿真模擬各種計算機功能來實作的。由一套位元組碼指令集、一組暫存器、一個堆疊、一個垃圾回收堆和一個存盤方法域等組成。JVM屏蔽了與作業系統平臺相關的資訊,使得Java程式只需要生成在Java虛擬機 ......

    uj5u.com 2023-04-20 07:23:31 more
  • 使用Java接入小程式訂閱訊息!

    更新完微信服務號的模板訊息之后,我又趕緊把微信小程式的訂閱訊息給實作了!之前我一直以為微信小程式也是要企業才能申請,沒想到小程式個人就能申請。 訊息推送平臺🔥推送下發【郵件】【短信】【微信服務號】【微信小程式】【企業微信】【釘釘】等訊息型別。 https://gitee.com/zhongfuch ......

    uj5u.com 2023-04-20 07:22:59 more
  • java -- 緩沖流、轉換流、序列化流

    緩沖流 緩沖流, 也叫高效流, 按照資料型別分類: 位元組緩沖流:BufferedInputStream,BufferedOutputStream 字符緩沖流:BufferedReader,BufferedWriter 緩沖流的基本原理,是在創建流物件時,會創建一個內置的默認大小的緩沖區陣列,通過緩沖 ......

    uj5u.com 2023-04-20 07:22:49 more
  • Java-SpringBoot-Range請求頭設定實作視頻分段傳輸

    老實說,人太懶了,現在基本都不喜歡寫筆記了,但是網上有關Range請求頭的文章都太水了 下面是抄的一段StackOverflow的代碼...自己大修改過的,寫的注釋挺全的,應該直接看得懂,就不解釋了 寫的不好...只是希望能給視頻網站開發的新手一點點幫助吧. 業務場景:視頻分段傳輸、視頻多段傳輸(理 ......

    uj5u.com 2023-04-20 07:22:42 more
  • Windows 10開發教程_編程入門自學教程_菜鳥教程-免費教程分享

    教程簡介 Windows 10開發入門教程 - 從簡單的步驟了解Windows 10開發,從基本到高級概念,包括簡介,UWP,第一個應用程式,商店,XAML控制元件,資料系結,XAML性能,自適應設計,自適應UI,自適應代碼,檔案管理,SQLite資料庫,應用程式到應用程式通信,應用程式本地化,應用程式 ......

    uj5u.com 2023-04-20 07:22:35 more