【JavaWeb后端開發04】java操作數據庫(JDBC + Mybatis+ yml格式)詳解

文章目錄

    • 1. 前言
    • 2. JDBC
      • 2.1 介紹
      • 2.2 入門程序
        • 2.2.1 DataGrip
        • 2.2.2 在IDEA執行sql語句
      • 2.3 查詢數據案例
        • 2.3.1 需求
        • 2.3.2 準備工作
        • 2.3.3 AI代碼實現
        • 2.3.4 代碼剖析
          • 2.3.4.1 ResultSet
          • 2.3.4.2 預編譯SQL
            • 2.3.4.2.1 SQL注入
            • 2.3.4.2.2 SQL注入解決
            • 2.3.4.2.3 性能更高
      • 2.4 增刪改數據
        • 2.4.1 需求
        • 2.4.2 代碼實現
    • 3. Mybatis
      • 3.1 介紹
        • 3.1.1 快速入門
        • 3.1.2 輔助配置
          • 3.1.2.1 配置SQL提示
          • 3.1.2.2 配置Mybatis日志輸出
        • 3.1.3 JDBC VS Mybatis
        • 3.1.4 數據庫連接池
          • 3.1.4.1 介紹
          • 3.1.4.2 產品
        • 3.1.5 增刪改查操作
          • 3.1.5.1 刪除
          • 3.1.5.2 新增
          • 3.1.5.3 修改
          • 3.1.5.4 查詢(帶條件)
        • 3.1.6 XML映射配置
          • 3.1.6.1 XML配置文件規范
          • 3.1.6.2 XML配置文件實現
          • 3.1.6.3 MybatisX的使用
    • 4. SpringBoot配置文件
      • 4.1 介紹
      • 4.2 語法
      • 4.3 案例


1. 前言

在前面我們學習MySQL數據庫時,都是利用圖形化客戶端工具(如:idea、datagrip),來操作數據庫的。

我們做為后端程序開發人員,通常會使用Java程序來完成對數據庫的操作。Java程序操作數據庫的技術呢,有很多啊,而最為底層、最為基礎的就是JDBC。

JDBC:(Java DataBase Connectivity),就是使用Java語言操作關系型數據庫的一套API。 【是操作數據庫最為基礎、底層的技術】

但是使用JDBC來操作數據庫,會比較繁瑣,所以現在在企業項目開發中呢,一般都會使用基于JDBC的封裝的高級框架,比如:Mybatis、MybatisPlus、Hibernate、SpringDataJPA。

而這些技術,目前的市場占有份額如下圖所示:

從上圖中,我們也可以看到,目前最為主流的就是Mybatis,其次是MybatisPlus。

內容:

  1. JDBC

  2. Mybatis

  3. SpringBoot配置文件

2. JDBC

2.1 介紹

JDBC:(Java DataBase Connectivity),就是使用Java語言操作關系型數據庫的一套API。

本質:

  • sun公司官方定義的一套操作所有關系型數據庫的規范,即接口

  • 各個數據庫廠商去實現這套接口,提供數據庫驅動jar包。

  • 我們可以使用這套接口(JDBC)編程,真正執行的代碼是驅動jar包中的實現類。

那有了JDBC之后,我們就可以直接在java代碼中來操作數據庫了,只需要編寫這樣一段java代碼,就可以來操作數據庫中的數據。 示例代碼如下:

2.2 入門程序

需求:基于JDBC,執行更新數據庫數據語句

image-20250421164903758

2.2.1 DataGrip

創建數據表

create table user(id int unsigned primary key auto_increment comment 'ID,主鍵',username varchar(20) comment '用戶名',password varchar(32) comment '密碼',name varchar(10) comment '姓名',age tinyint unsigned comment '年齡'
) comment '用戶表';insert into user(id, username, password, name, age) values (1, 'daqiao', '123456', '大喬', 22),(2, 'xiaoqiao', '123456', '小喬', 18),(3, 'diaochan', '123456', '貂蟬', 24),(4, 'lvbu', '123456', '呂布', 28),(5, 'zhaoyun', '12345678', '趙云', 27);

image-20250421171247331


2.2.2 在IDEA執行sql語句

導入依賴

    <dependencies><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>8.0.33</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.3</version><scope>test</scope></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.30</version></dependency></dependencies>
  1. mysql-connector-j (MySQL 連接器)

    用途:這是 MySQL 數據庫的 JDBC 驅動程序,它允許 Java 程序與 MySQL 數據庫進行連接和交互。

    功能:通過這個依賴,Java 程序可以使用 JDBC(Java Database Connectivity)接口與 MySQL 數據庫進行數據操作(如查詢、更新、刪除等)。

  2. junit-jupiter (JUnit 測試框架)

    用途:這是 JUnit 5 的核心庫,提供了用于編寫和執行單元測試的功能。junit-jupiter 是 JUnit 5 框架的一部分,包含了新的測試注解和斷言方法。

    功能:它允許開發人員編寫單元測試,以確保代碼的正確性。JUnit 5 允許使用如 @Test 注解標記測試方法,支持斷言(如 assertEquals()assertTrue())來驗證預期結果。

  3. lombok (Lombok 庫)

用途:Lombok 是一個 Java 庫,通過注解自動生成常見的 Java 代碼(如 getter、setter、toString 方法等),減少了代碼冗余。

功能:它通過注解(如 @Getter@Setter@ToString@EqualsAndHashCode)自動為類生成常見的方法,簡化了 Java 類的編寫。使用 Lombok,開發者不需要手動編寫大量樣板代碼,可以讓代碼更加簡潔、清晰。

更新代碼

import com.mysql.cj.jdbc.Driver;
import org.junit.jupiter.api.Test;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;public class JdbcTest {/*** Jdbc入門程序*/@Testpublic void testUpdate() throws Exception {//1.注冊驅動Class.forName("com.mysql.cj.jdbc.Driver");//2.獲取數據庫連接String url = "jdbc:mysql://localhost:3306/web01";String username = "root";String password = "0524";Connection connection = DriverManager.getConnection(url, username, password);//3.獲取sql語句的執行對象Statement statement = connection.createStatement();//4.執行SQLint i = statement.executeUpdate("update user set age = 25 where id = 1");System.out.println("SQL執行完畢影響記錄數為:" + i);//5.釋放資源statement.close();connection.close();}
}
  1. 注冊驅動

    Class.forName():是 Java 反射機制中的一個方法,作用是加載并初始化指定類。Class.forName() 會通過類的全限定名(包括包名)加載指定的類,并且會執行該類的靜態初始化塊。

    "com.mysql.cj.jdbc.Driver":是 MySQL JDBC 驅動類的全限定類名(包括包名)。它是 MySQL 的驅動程序類,負責將 Java 程序與 MySQL 數據庫之間的通信進行處理。獲取數據庫連接

    connection = DriverManager.getConnection使用connection進行數據庫連接,需要url地址、用戶、密碼

    "jdbc:mysql://localhost:3306/web01";:

    • jdbc:mysql://:這是 JDBC (Java Database Connectivity) 的協議部分,表示這是一個 MySQL 數據庫連接。
    • localhost:這是數據庫的主機名,表示數據庫在本地計算機上運行。
    • 3306:這是 MySQL 數據庫的默認端口號,表示數據庫服務監聽的端口。
    • web01:這是數據庫的名稱,表示要連接的數據庫是名為 web01 的數據庫。
  2. 獲取sql語句執行對象

    statement執行更新sql語句,并返回影響幾條記錄(int)

  3. 執行SQL語句

    • executeUpdate用于執行修改數據庫內容的 SQL 語句(如 INSERTUPDATEDELETE)。

    • executeQuery用于執行選擇SELECT語句,查詢數據庫并返回結果集ResultSet,下一節會用到

      ResultSet rs = statement.executeQuery("SELECT * FROM users");
    • execute():執行任何 SQL 語句,無論是否返回結果集。該方法適用于 SELECTINSERTUPDATEDELETE 等多種語句。

      返回值:返回一個布爾值,指示執行的 SQL 是否返回一個結果集。

  4. 執行完畢釋放資源

    statement.close();connection.close(); 用于關閉數據庫連接和聲明,以確保資源得到妥善釋放。

    • 如果不關閉 statement,可能會導致資源泄漏,特別是對于數據庫連接的聲明,可能會影響性能和穩定性。
    • 數據庫連接是寶貴的資源,如果不及時關閉connection,可能會耗盡數據庫連接池的可用連接,導致系統性能下降或連接異常。

最終結果

image-20250421171441217


2.3 查詢數據案例

2.3.1 需求

image-20250421174100658

需求:基于JDBC實現用戶登錄功能。用戶登錄就是你輸入的賬號名和密碼可以在數據庫中使用SELECT語句查詢到,能查到就放你登錄

本質:其本質呢,其實就是基于JDBC程序,執行如下select語句,并將查詢的結果輸出到控制臺。SQL語句:

select * from user where username = 'linchong' and password = '123456';
2.3.2 準備工作

1). 創建一個maven項目

2). 創建一個數據庫 web,并在該數據庫中創建user表

create table user(id int unsigned primary key auto_increment comment 'ID,主鍵',username varchar(20) comment '用戶名',password varchar(32) comment '密碼',name varchar(10) comment '姓名',age tinyint unsigned comment '年齡'
) comment '用戶表';insert into user(id, username, password, name, age) values (1, 'daqiao', '123456', '大喬', 22),(2, 'xiaoqiao', '123456', '小喬', 18),(3, 'diaochan', '123456', '貂蟬', 24),(4, 'lvbu', '123456', '呂布', 28),(5, 'zhaoyun', '12345678', '趙云', 27);
2.3.3 AI代碼實現

AI提示語句

你是一名java開發工程師,幫我基于JDBC程序來操作數據庫,執行如下SQL語句:select id,username,password,name,age from user where username = ‘daqiao’ and password = ‘123456’;
并將查詢的每一行記錄,都封裝到實體類User中,然后將User對象的數據輸出到控制臺中。
User 實體類屬性如下:
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
private Integer id; //ID
private String username; //用戶名
private String password; //密碼
private String name; //姓名
private Integer age; //年齡
}

具體的代碼為:

1). 在 pom.xml 文件中引入依賴

<dependencies><!-- MySQL JDBC driver --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.30</version></dependency><dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.9.3</version><scope>test</scope></dependency>
</dependencies>

2). 在 src/main/test/java 目錄下編寫測試類,定義測試方法

從 JDBC 4.0 開始,Java 對 JDBC 驅動程序進行了改進,允許驅動程序自動注冊。也就是說,只要你把適當的 JDBC 驅動 JAR 包(例如 mysql-connector-java)添加到項目的 classpath 中,JDBC 驅動會自動加載,無需顯式地調用 Class.forName() 來加載驅動。

    @Testpublic void testSelect() throws Exception {//獲取連接Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/web01","root","0524");//創建預編譯的PreparedStatement對象PreparedStatement pstmt = connection.prepareStatement("SELECT * FROM user WHERE username = ? and password = ?");//設置參數pstmt.setString(1,"daqiao");pstmt.setString(2,"123456");//執行查詢ResultSet rs = pstmt.executeQuery();//處理解析返回的數據while(rs.next()){int id = rs.getInt("id");String username = rs.getString("username");String password = rs.getString("password");String name = rs.getString("name");int age = rs.getInt("age");System.out.println(id + " " + username + " " + password + " " + name + " " + age);}//釋放資源rs.close();pstmt.close();connection.close();}}

下一節會講解返回值rs處理部分

輸出結果

image-20250421182848463

而上述的單元測試中,我們在SQL語句中,將將 用戶名 和密碼的值都寫死了,而這兩個值應該是動態的,是將來頁面傳遞到服務端的。 那么,我們可以基于前面所講解的JUnit中的參數化測試進行單元測試,代碼改造如下:

public class JDBCTest {/*** 編寫JDBC程序, 查詢數據*/@ParameterizedTest@CsvSource({"daqiao,123456"})public void testJdbc(String _username, String _password) throws Exception {// 獲取連接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234");// 創建預編譯的PreparedStatement對象PreparedStatement pstmt = conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");// 設置參數pstmt.setString(1, _username); // 第一個問號對應的參數pstmt.setString(2, _password); // 第二個問號對應的參數// 執行查詢ResultSet rs = pstmt.executeQuery();// 處理結果集while (rs.next()) {int id = rs.getInt("id");String uName = rs.getString("username");String pwd = rs.getString("password");String name = rs.getString("name");int age = rs.getInt("age");System.out.println("ID: " + id + ", Username: " + uName + ", Password: " + pwd + ", Name: " + name + ", Age: " + age);}// 關閉資源rs.close();pstmt.close();conn.close();}}

如果在測試時,需要傳遞一組參數,可以使用 @CsvSource 注解。

image-20250421174319825

2.3.4 代碼剖析
2.3.4.1 ResultSet

ResultSet(結果集對象):封裝了DQL查詢語句查詢的結果

  • next():將光標從當前位置向前移動一行,并判斷當前行是否為有效行,返回值為boolean。

    • true:有效行,當前行有數據

    • false:無效行,當前行沒有數據

    • 所以可以while循環逐行讀取數據,直到為空結束

  • getXxx(…):獲取數據,可以根據列的編號獲取,也可以根據列名獲取(推薦)。

結果解析步驟:

2.3.4.2 預編譯SQL

其實我們在編寫SQL語句的時候,有兩種風格:

  • 靜態SQL(參數硬編碼)
conn.prepareStatement("SELECT * FROM user WHERE username = 'daqiao' AND password = '123456'");
ResultSet resultSet = pstmt.executeQuery();

這種呢,就是參數值,直接拼接在SQL語句中,參數值是寫死的。

  • 預編譯SQL(參數動態傳遞)
conn.prepareStatement("SELECT * FROM user WHERE username = ? AND password = ?");
pstmt.setString(1, "daqiao");
pstmt.setString(2, "123456");
ResultSet resultSet = pstmt.executeQuery();

這種呢,并未將參數值在SQL語句中寫死,而是使用 ? 進行占位,然后再指定每一個占位符對應的值是多少,而最終在執行SQL語句的時候,程序會將SQL語句(SELECT * FROM user WHERE username = ? AND password = ?),以及參數值(“daqiao”, “123456”)都發送給數據庫,然后在執行的時候,會使用參數值,將?占位符替換掉。

那這種預編譯的SQL,也是在項目開發中推薦使用的SQL語句。主要的作用有兩個:

  • 防止SQL注入,更加安全

  • 性能更高

那接下來,我們就來介紹一下這兩點。

2.3.4.2.1 SQL注入
  • SQL注入:通過控制輸入來修改事先定義好的SQL語句,以達到執行代碼對服務器進行攻擊的方法。

SQL注入最典型的場景,就是用戶登錄功能。

注入演示:

1). 打開資料中的文件夾 資料/02. SQL注入演示,運行其中的jar包 sql_Injection_demo-0.0.1-SNAPSHOT.jar,進入該目錄后,執行命令:

java -jar sql_Injection_demo-0.0.1-SNAPSHOT.jar

2). 打開瀏覽器訪問 http://localhost:9090/ ,必須登錄后才能訪問到系統。我們先測試正常的用戶名和密碼

3). 接下來,我們再來測試一下錯誤的用戶名和密碼 。

我們看到,如果用戶名密碼錯誤,是不能進入到系統中進行訪問的,會提示 用戶名和密碼錯誤

4). 那接下來,我們就要演示一下SQL注入現象,我們可以通過控制表單輸入,來修改事先定義好的SQL語句的含義。 從而來攻擊服務器。

點擊登錄后,我們看到居然可以成功進入到系統中。

為什么會出現這種現象呢?

在進行登錄操作時,怎么樣才算登錄成功呢? 如果我們查詢到了數據,就說明用戶名密碼是對的。 如果沒有查詢到數據,就說明用戶名或密碼錯誤。

而出現上述現象,原因就是因為,我們我們編寫的SQL語句是基于字符串進行拼接的 。 我們輸入的用戶名無所謂,比如:shfhsjfhja ,而密碼呢,就是我們精心設計的,如:' or '1' = '1

那最終拼接的SQL語句,如下所示:

我們知道,or 連接的條件,是或的關系,兩者滿足其一就可以。 所以,雖然用戶名密碼輸入錯誤,也是可以查詢返回結果的,而只要查詢到了數據,就說明用戶名和密碼是正確的。

2.3.4.2.2 SQL注入解決

而通過預編譯SQL(select * from user where username = ? and password = ?),就可以直接解決上述SQL注入的問題。 接下來,我們再來演示一下,通過預編譯SQL是否能夠解決SQL注入問題。

1). 打開資料中的文件夾 資料/02. SQL注入演示,運行其中的jar包 sql_prepared_demo-0.0.1-SNAPSHOT.jar,進入該目錄后,執行命令:

java -jar sql_prepared_demo-0.0.1-SNAPSHOT.jar

2). 打開瀏覽器訪問 http://localhost:9090/ ,必須登錄后才能訪問到系統 。我們先測試正常的用戶名和密碼

3). 那接下來,我們就要演示一下是否可以基于上述的密碼 ' or '1' = '1,來完成SQL注入 。

通過控制臺,可以看到輸入的SQL語句,是預編譯SQL語句。

而在預編譯SQL語句中,當我們執行的時候,會把整個' or '1'='1作為一個完整的參數,賦值給第2個問號(' or '1'='1進行了轉義,只當做字符串使用)

那么此時再查詢時,就查詢不到對應的數據了,登錄失敗。

注意:在以后的項目開發中,我們使用的基本全部都是預編譯SQL語句。

2.3.4.2.3 性能更高

數據庫會把以前用過的sql語句直接到緩存里面拿(數據庫內存),不需要在重新進行語法檢查 — 編譯。

2.4 增刪改數據

2.4.1 需求
  • 需求:基于JDBC程序,執行如下update語句。

  • SQL:

update user set password = '123456', gender = 2 where id = 1;
2.4.2 代碼實現

AI提示詞(prompt):

你是一名java開發工程師,幫我基于JDBC程序來操作數據庫,執行如下SQL語句:

update user set password = ‘123456’, gender = 2 where id = 1;

代碼實現如下:

@ParameterizedTest
@CsvSource({"1,123456,25"})
public void testUpdate(int userId, String newPassword, int newAge) throws Exception {// 建立數據庫連接Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/web", "root", "1234");// SQL 更新語句String sql = "UPDATE user SET password = ?, age = ? WHERE id = ?";// 創建預編譯的PreparedStatement對象PreparedStatement pstmt = conn.prepareStatement(sql);// 設置參數pstmt.setString(1, newPassword); // 第一個問號對應的參數pstmt.setInt(2, newAge);      // 第二個問號對應的參數pstmt.setInt(3, userId);         // 第三個問號對應的參數// 執行更新int rowsUpdated = pstmt.executeUpdate();// 輸出結果System.out.println(rowsUpdated + " row(s) updated.");// 關閉資源pstmt.close();conn.close();
}
  • JDBC程序執行DML語句:int rowsUpdated = pstmt.executeUpdate(); //返回值是影響的記錄數

  • JDBC程序執行DQL語句:ResultSet resultSet = pstmt.executeQuery(); //返回值是查詢結果集

image-20250421175619256

3. Mybatis

3.1 介紹

什么是MyBatis?

  • MyBatis是一款優秀的 持久層 框架,用于簡化JDBC的開發。

  • MyBatis本是 Apache的一個開源項目iBatis,2010年這個項目由apache遷移到了google code,并且改名為MyBatis 。2013年11月遷移到Github。

  • 官網:https://mybatis.org/mybatis-3/zh/index.html

在上面我們提到了兩個詞:一個是持久層,另一個是框架。

  • 持久層:指的是就是數據訪問層(dao),是用來操作數據庫的。

  • 框架:是一個半成品軟件,是一套可重用的、通用的、軟件基礎代碼模型。在框架的基礎上進行軟件開發更加高效、規范、通用、可拓展。

通過Mybatis就可以大大簡化原生的JDBC程序的代碼編寫,比如 通過 select * from user 查詢所有的用戶數據,通過JDBC程序操作呢,需要大量的代碼實現,而如果通過Mybatis實現相同的功能,只需要簡單的三四行就可以搞定。

3.1.1 快速入門

需求:使用Mybatis查詢所有用戶數據 。

image-20250421213027553

1). 創建springboot工程,并導入 mybatis的起步依賴、mysql的驅動包、lombok。

項目工程創建完成后,自動在pom.xml文件中,導入Mybatis依賴和MySQL驅動依賴。如下所示:

2). 數據準備:創建用戶表user,并創建對應的實體類User。

image-20250421212934118

//User類
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {private Integer id;private String username;private String password;private String name;private Integer age;
}

3). 配置Mybatis

application.properties 中配置數據庫的連接信息,數據庫連接四要素,只需定義一次。

#數據庫訪問的url地址
spring.datasource.url=jdbc:mysql://localhost:3306/web01
#數據庫驅動類類名
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#訪問數據庫-用戶名
spring.datasource.username=root
#訪問數據庫-密碼
spring.datasource.password=root@0524

上述的配置,可以直接復制過去,不要敲錯了。 全部都是 spring.datasource.xxxx 開頭。

4). 編寫Mybatis程序:編寫Mybatis的持久層接口,定義SQL語句(注解)

在創建出來的springboot工程中,在引導類所在包下,在創建一個包 mapper 。在 mapper 包下創建一個接口 UserMapper ,這是一個持久層接口(Mybatis的持久層接口規范一般都叫 XxxMapper,也叫做Mapper接口)。

UserMapper接口的內容如下:

import com.cyanm.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper  // 應用程序在運行時,會自動的為該接口創建一個實現類對象(動態代理對象),并且會自動地將該實現類對象存入IOC容器中 - bean
public interface UserMapper {@Select("select * from user")public List<User> findAll();
}

注解說明:

  • @Mapper注解:表示是mybatis中的Mapper接口

程序運行時,框架會自動生成接口的實現類對象(代理對象),并給交Spring的IOC容器管理

  • @Select注解:代表的就是select查詢,用于書寫select查詢語句

5). 單元測試

在創建出來的SpringBoot工程中,在src下的test目錄下,已經自動幫我們創建好了測試類 ,并且在測試類上已經添加了注解 @SpringBootTest,代表該測試類已經與SpringBoot整合。

該測試類在運行時,會自動通過引導類加載Spring的環境(IOC容器)。我們要測試那個bean對象,就可以直接通過@Autowired注解直接將其注入進行,然后就可以測試了。

測試類代碼如下:

import com.cyanm.mapper.UserMapper;
import com.cyanm.pojo.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;@SpringBootTest // SpringBoot中單元測試的注解 - 當前測試類中的測試方法運行時,會啟動springboot項目 - IOC容器就創建好了
class SpringbootMybatisQuickstartApplicationTests {//注入UserMapper對象@Autowiredprivate UserMapper userMapper;@Testvoid contextLoads() {//調用方法List<User> userList = userMapper.findAll();userList.forEach(System.out::println);}
}

運行結果:

注意:測試類所在包,需要與引導類/啟動類所在包相同。

image-20250421215529711

image-20250421215025356

Spring Boot的包掃描機制

Spring Boot的核心特性之一是其自動配置和組件掃描機制。在應用啟動時,Spring Boot會根據引導類的位置進行包掃描。具體來說:

  • 掃描范圍:Spring Boot會從引導類所在的包開始,遞歸掃描該包及其所有子包。
  • 掃描目標:掃描過程中,Spring Boot會查找并注冊所有帶有特定注解的類,例如:
    • @Component(及其派生注解,如@Service@Repository@Controller等)
    • @Mapper(MyBatis中用于標記Mapper接口的注解)
    • 其他Spring支持的注解
  • 目的:通過這種機制,Spring Boot能夠自動將這些類注冊為Spring容器中的Bean,從而在應用運行時可以直接注入和使用。

例如,如果引導類位于com.example.demo包中,Spring Boot會掃描com.example.demo及其子包(如com.example.demo.mappercom.example.demo.service等),但不會掃描com.example.test這樣的外部包。


3.1.2 輔助配置
3.1.2.1 配置SQL提示

默認我們在UserMapper接口上加的 @Select 注解中編寫SQL語句是沒有提示的。 如果想讓idea給我們提示對應的SQL語句,我們需要在IDEA中配置與MySQL數據庫的鏈接。

默認我們在UserMapper接口上的 @Select 注解中編寫SQL語句是沒有提示的。如果想讓idea給出提示,可以做如下配置:

配置完成之后,發現SQL語句中的關鍵字有提示了,但還存在不識別表名(列名)的情況:

  • 產生原因:Idea和數據庫沒有建立連接,不識別表信息

  • 解決方案:在Idea中配置MySQL數據庫連接

按照如下方如下方式,來配置當前IDEA關聯的MySQL數據庫(必須要指定連接的是哪個數據庫)。

在配置的時候指定連接那個數據庫,如上圖所示連接的就是mybatis數據庫(自己的數據庫名是什么就指定什么)。

注意:該配置的目的,僅僅是為了在編寫SQL語句時,有語法提示(寫錯了會報錯),不會影響運行,即使不配置也是可以的。

3.1.2.2 配置Mybatis日志輸出

默認情況下,在Mybatis中,SQL語句執行時,我們并看不到SQL語句的執行日志。 在application.properties加入如下配置,即可查看日志:

#mybatis的配置
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

打開上述開關之后,再次運行單元測試,就可以看到控制臺輸出的SQL語句是什么樣子的。

3.1.3 JDBC VS Mybatis

JDBC程序的缺點

  • url、username、password 等相關參數全部硬編碼在java代碼中。

  • 查詢結果的解析、封裝比較繁瑣。

  • 每一次操作數據庫之前,先獲取連接,操作完畢之后,關閉連接。 頻繁的獲取連接、釋放連接造成資源浪費。

分析了JDBC的缺點之后,我們再來看一下在mybatis中,是如何解決這些問題的:

  • 數據庫連接四要素(驅動、鏈接、用戶名、密碼),都配置在springboot默認的配置文件 application.properties中,配置文件不用重新編譯

  • 查詢結果的解析及封裝,由mybatis自動完成映射封裝,我們無需關注

  • 在mybatis中使用了數據庫連接池技術,從而避免了頻繁的創建連接、銷毀連接而帶來的資源浪費。

使用SpringBoot+Mybatis的方式操作數據庫,能夠提升開發效率、降低資源浪費

而對于Mybatis來說,我們在開發持久層程序操作數據庫時,需要重點關注以下兩個方面:

  1. application.properties
#驅動類名稱
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#數據庫連接的url
spring.datasource.url=jdbc:mysql://localhost:3306/web01
#連接數據庫的用戶名
spring.datasource.username=root
#連接數據庫的密碼
spring.datasource.password=1234-
  • Mapper接口(編寫SQL語句)
@Mapper
public interface UserMapper {@Select("select * from user")public List<User> list();
}
3.1.4 數據庫連接池

在前面我們所講解的mybatis中,使用了數據庫連接池技術,避免頻繁的創建連接、銷毀連接而帶來的資源浪費。

下面我們就具體的了解下數據庫連接池。

3.1.4.1 介紹

1). 沒有數據庫連接池的情況

客戶端執行SQL語句:要先創建一個新的連接對象,然后執行SQL語句,SQL語句執行后又需要關閉連接對象從而釋放資源,每次執行SQL時都需要創建連接、銷毀鏈接,這種頻繁的重復創建銷毀的過程是比較耗費計算機的性能。

2). 有數據庫連接池的情況

數據庫連接池是個容器,負責分配、管理數據庫連接(Connection)

  • 程序在啟動時,會在數據庫連接池(容器)中,創建一定數量的Connection對象

允許應用程序重復使用一個現有的數據庫連接,而不是再重新建立一個

  • 客戶端在執行SQL時,先從連接池中獲取一個Connection對象,然后在執行SQL語句,SQL語句執行完之后,釋放Connection時就會把Connection對象歸還給連接池(Connection對象可以復用)

釋放空閑時間超過最大空閑時間的連接,來避免因為沒有釋放連接而引起的數據庫連接遺漏

  • 客戶端獲取到Connection對象了,但是Connection對象并沒有去訪問數據庫(處于空閑),數據庫連接池發現Connection對象的空閑時間 > 連接池中預設的最大空閑時間,此時數據庫連接池就會自動釋放掉這個連接對象

數據庫連接池的好處:

  • 資源重用

  • 提升系統響應速度

  • 避免數據庫連接遺漏

3.1.4.2 產品

要怎么樣實現數據庫連接池呢?

  • 官方(sun)提供了數據庫連接池標準(javax.sql.DataSource接口)

  • 功能:獲取連接

    public Connection getConnection() throws SQLException;
    
  • 第三方組織必須按照DataSource接口實現

常見的數據庫連接池:C3P0 、DBCP 、Druid 、Hikari (springboot默認)

現在使用更多的是:Hikari、Druid (性能更優越)

1). Hikari(追光者) [默認的連接池]

從控制臺輸出的日志,我們也可以看出,springboot底層默認使用的數據庫連接池就是 Hikari。

2). Druid(德魯伊)

  • Druid連接池是阿里巴巴開源的數據庫連接池項目

  • 功能強大,性能優秀,是Java語言最好的數據庫連接池之一

如果我們想把默認的數據庫連接池切換為Druid數據庫連接池,只需要完成以下兩步操作即可:

參考官方地址:https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter

①. 在pom.xml文件中引入依賴

<dependency><!-- Druid連接池依賴 --><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.19</version>
</dependency>

②. 在application.properties中引入數據庫連接配置

spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/web
spring.datasource.druid.username=root
spring.datasource.druid.password=1234

配置完畢之后,我們再次運行單元測試,大家會看到控制臺輸出的日志中,已經將連接池切換為了 Druid連接池。


3.1.5 增刪改查操作
3.1.5.1 刪除
  • 需求:根據ID刪除用戶信息

  • SQL:delete from user where id = 5;

  • Mapper接口方法:

    • 方式一:
    /*** 根據id刪除*/
    @Delete("delete from user where id = 5")
    public void deleteById();
    

這種方式執行刪除操作,調用deleteById方法只能刪除id為5的用戶信息,因為將id直接寫死在代碼中了,不可取。

在Mybatis中,我們可以通過參數占位符號 #{...} 來占位,在調用deleteById方法時,傳遞的參數值,最終會替換占位符。

@Delete("delete from user where id = #{id}")
public void deleteById(Integer id);
  • 編寫單元測試方法進行測試

    在單元測試類中,增加如下測試方法.

    @Test
    public void testDeleteById(){userMapper.deleteById(36);
    }
    

運行單元測試,結果如下:

運行之后,我們發現,#{...} 占位符,其實最終被替換成了**?占位符** ,生成的是預編譯的SQL語句。【推薦】

  • DML語句執行完畢,是有返回值的,我們可以為Mapper接口方法定義返回值來接收,如下:

    /*** 根據id刪除*/
    @Delete("delete from user where id = #{id}")
    public Integer deleteById(Integer id);
    

Integer類型的返回值,表示DML語句執行完畢影響的記錄數。

  • Mybatis的提供的符號,有兩個,一個是 #{...},另一個是 ${...},區別如下:

    image-20250421224804148
符號作用用法說明安全性性能
#{...}預編譯參數占位符將參數值通過 JDBC 的 PreparedStatement 設置到 SQL 中,使用預編譯方式防止 SQL 注入。高(因為使用了預編譯)
${...}字符串替換占位符將參數值直接拼接到 SQL 字符串中,不進行預編譯,適用于動態表名、列名等場景,但容易引發 SQL 注入問題。低(不進行預編譯,直接拼接)

那在企業項目開發中,強烈建議使用 #{…} 。

預編譯原理:MyBatis 使用 #{...} 進行預編譯時,會將 SQL 語句和參數分開處理。這樣,MyBatis 會把參數值綁定到 SQL 語句中的占位符,而不會直接插入到 SQL 語句的結構中(例如表名、列名、運算符等)。這意味著,#{...} 只能用于動態值(如字符串、數字等),而不能修改 SQL 的結構。


3.1.5.2 新增
  • 需求:添加一個用戶

  • SQL:insert into user(username,password,name,age) values(‘zhouyu’,‘123456’,‘周瑜’,20);

  • Mapper接口:

/*** 添加用戶*/
@Insert("insert into user(username,password,name,age) values(#{username},#{password},#{name},#{age})")
public void insert(User user);

如果在SQL語句中,我們需要傳遞多個參數,我們可以把多個參數封裝到一個對象中。然后在SQL語句中,我們可以通過#{對象屬性名}的方式,獲取到對象中封裝的屬性值。注意不是字段名

  • 單元測試:

在測試類中添加測試方法,代碼如下:

@Test
public void testInsert(){User user = new User();user.setUsername("admin");user.setPassword("123456");user.setName("管理員");user.setAge(30);userMapper.insert(user);
}

運行結果如下:


3.1.5.3 修改
  • 需求:根據ID更新用戶信息

  • SQL:update user set username = ‘zhouyu’, password = ‘123456’, name = ‘周瑜’, age = 20 where id = 1;

  • Mapper接口方法:注意是屬性名!!!跟字段名沒關系

/*** 根據id更新用戶信息*/
@Update("update user set username = #{username},password = #{password},name = #{name},age = #{age} where id = #{id}")
public void update(User user);
  • 單元測試:

在測試類中添加測試方法,代碼如下:

@Test // 全參構造也可以
public void testUpdate(){User user = new User();user.setId(6);user.setUsername("admin666");user.setPassword("123456");user.setName("管理員");user.setAge(30);userMapper.update(user);
}

運行結果如下:


3.1.5.4 查詢(帶條件)
  • 需求:根據用戶名和密碼查詢用戶信息

  • SQL:select * from user where user name = ‘zhouyu’ and password = ‘123456’;

  • Mapper接口方法:

/*** 根據用戶名和密碼查詢用戶信息*/
@Select("select * from user where username = #{username} and password = #{password}") //注意這里是為形參起的名字而不是方法形參名稱
public User findByUsernameAndPassword(@Param("username") String username, @Param("password") String password);

@param注解的作用是為接口的方法形參起名字的。(由于用戶名唯一的,所以查詢返回的結果最多只有一個,可以直接封裝到一個對象中)

在默認的情況下,Java 編譯器會去除方法參數的名稱,只保留參數的類型。這意味著編譯后的字節碼中可能沒有方法參數的原始名字(例如 usernamepassword),因此 MyBatis 無法直接通過這些參數名稱來引用它們。之前增刪改只有一個形參,現在不止一個形參

  • 單元測試:

在測試類中添加測試方法,代碼如下:

@Test
public void testFindByUsernameAndPassword(){User user = userMapper.findByUsernameAndPassword("admin666", "123456");System.out.println(user);
}

運行結果如下:

image-20250421234601767

說明:基于官方骨架創建的springboot項目中,接口編譯時會保留方法形參名,@Param注解可以省略 (#{形參名})。

這里直接寫形參名即可

如果用阿里框架還不給起名字,報錯如下

字節碼文件:形參名沒有被保留,只保留類型

image-20250421234736514

起了名字之后的字節碼文件

image-20250421234904963

注意報錯不要從上往下讀,直接找Caused by

image-20250421234721900

image-20250421234938104


3.1.6 XML映射配置

Mybatis的開發有兩種方式:

  1. 注解: 如@Select @Update等等

  2. XML

3.1.6.1 XML配置文件規范

使用Mybatis的注解方式,主要是來完成一些簡單的增刪改查功能。如果需要實現復雜的SQL功能,建議使用XML來配置映射語句,也就是將SQL語句寫在XML配置文件中。

image-20250421235320303

在Mybatis中使用XML映射文件方式開發,需要符合一定的規范:

  1. XML映射文件的名稱與Mapper接口名稱一致,并且將XML映射文件和Mapper接口放置在相同包下**(同包同名)**

  2. XML映射文件的namespace屬性為Mapper接口全限定名一致

  1. XML映射文件中sql語句的id與Mapper接口中的方法名一致,并保持返回類型一致(注意是單條返回類型)。

<select>標簽:就是用于編寫select查詢語句的。

  • resultType屬性,指的是查詢返回的單條記錄所封裝的類型。
  • id屬性:這個sql語句的唯一標識,且與方法名命名一致
3.1.6.2 XML配置文件實現

第1步: 創建XML映射文件

這里不要用 .

第2步:編寫XML映射文件

xml映射文件中的dtd約束,直接從mybatis官網復制即可; 或者直接AI生成。這個是固定的,不用記

官方:https://mybatis.net.cn/getting-started.html

image-20250421235646668

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=""></mapper>

第3步:配置

a. XML映射文件的namespace屬性為Mapper接口全限定名

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.UserMapper"></mapper>

b. XML映射文件中sql語句的id與Mapper接口中的方法名一致,并保持返回類型一致

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper"><!--查詢操作--><select id="findAll" resultType="com.itheima.pojo.User">select * from user</select></mapper>

resultType 屬性的值,與查詢返回的單條記錄封裝的類型一致。

運行測試類,執行結果:

image-20250422000924130

匹配規則

  1. 一旦調用了UserMapper中的方法,就會去查詢要執行的sql語句在哪個映射文件中定義,就回去查找哪份XML文件的namesapce屬性是我Mapper接口的全類名,進行匹配
  2. 一份XML文件中可以有多條sql語句,那我們怎么知道調用那條呢?
    根據方法名和id名匹配來調用,

注意:一個接口方法對應的SQL語句,要么使用注解配置,要么使用XML配置,切不可同時配置。

開發規范

image-20250422001134894


3.1.6.3 MybatisX的使用

1. 指定配置XML映射文件位置

mybatis.mapper-locations=classpath:mapper/*.xml

java目錄和resources目錄在編譯后都會放在class目錄下,所以先指定一下最后位置


2.MybatisX是一款基于IDEA的快速開發Mybatis的插件,為效率而生。

MybatisX的安裝:

可以通過MybatisX快速定位:

MybatisX的使用在后續學習中會繼續分享。

  • 學習了Mybatis中XML配置文件的開發方式了,大家可能會存在一個疑問:到底是使用注解方式開發還是使用XML方式開發?

官方說明:https://mybatis.net.cn/getting-started.html。下面是官方說明:

結論:使用Mybatis的注解,主要是來完成一些簡單的增刪改查功能。如果需要實現復雜的SQL功能,建議使用XML來配置映射語句。


4. SpringBoot配置文件

4.1 介紹

前面我們一直使用springboot項目創建完畢后自帶的application.properties進行屬性的配置,而如果在項目中,我們需要配置大量的屬性,采用properties配置文件這種 key=value 的配置形式,就會顯得配置文件的層級結構不清晰,也比較臃腫。

那其實呢,在springboot項目當中是支持多種配置方式的,除了支持properties配置文件以外,還支持另外一種類型的配置文件,就是我們接下來要講解的yml格式的配置文件。yml格式配置文件名字為:application.yaml , application.yml 這兩個配置文件的后綴名雖然不一樣,但是里面配置的內容形式都是一模一樣的。

我們可以來對比一下,采用 application.propertiesapplication.yml 來配置同一段信息(數據庫連接信息),兩者之間的配置對比:yml格式冗余部分簡潔化了

在項目開發中,我們推薦使用application.yml配置文件來配置信息,簡潔、明了、以數據為中心。

4.2 語法

簡單的了解過springboot所支持的配置文件,以及不同類型配置文件之間的優缺點之后,接下來我們就來了解下yml配置文件的基本語法:

  • 大小寫敏感
  • key和value用冒號分開,但value前必須有空格,作為分隔符
  • 使用縮進表示層級關系,縮進時,不允許使用Tab鍵,只能用空格(idea中會自動將Tab轉換為空格,所以正常用)
  • 縮進的空格數目不重要,只要相同層級的元素左側對齊即可
  • #表示注釋,從這個字符一直到行尾,都會被解析器忽略

了解完yml格式配置文件的基本語法之后,接下來我們再來看下yml文件中常見的數據格式。在這里我們主要介紹最為常見的兩類:

  1. 定義對象或Map集合

  2. 定義數組、list或set集合

  • 對象/Map集合
user:name: zhangsanage: 18password: 123456
  • 數組/List/Set集合 -后面加各個元素的值
hobby: - java #元素1- game #元素2- sport #元素3

在yml格式的配置文件中,如果配置項的值是以 0 開頭的,值需要使用 ‘’ 引起來,因為以0開頭在yml中表示8進制的數據。

4.3 案例

熟悉完了yml文件的基本語法后,我們修改下之前案例中使用的配置文件,變更為application.yml配置方式:

  1. 修改application.properties名字為:_application.properties(名字隨便更換,只要加載不到即可)

  2. 創建新的配置文件: application.yml

  • 原有的 application.properties 配置文件

  • 新建的 application.yml 配置文件

配置文件的內容如下:

#數據源配置
spring:datasource:driver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/web01username: rootpassword: root@1234
#mybatis配置
mybatis:configuration:log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

image-20250422003700963


求關注2

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

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

相關文章

力扣-240.搜索二維矩陣 II

題目描述 編寫一個高效的算法來搜索 m x n 矩陣 matrix 中的一個目標值 target 。該矩陣具有以下特性&#xff1a; 每行的元素從左到右升序排列。每列的元素從上到下升序排列。 class Solution { public:bool searchMatrix(vector<vector<int>>& matrix, in…

Spark-Streaming(三)

一. kafka和flume的整合 任務需求一:利用flume監控某目錄中新生成的文件&#xff0c;將監控到的變更數據發送給kafka&#xff0c;kafka將收到的數據打印到控制臺 1. 在flume/conf/目錄下添加flume-kafka.conf文件 配置文件如下 2. 啟動flume和kafka消費者 3. 傳入數據 查看fl…

Spring Boot 啟動生命周期詳解

Spring Boot 啟動生命周期詳解 1. 啟動階段劃分 Spring Boot 啟動過程分為 4個核心階段&#xff0c;每個階段涉及不同的核心類和執行邏輯&#xff1a; 階段 1&#xff1a;預初始化&#xff08;Pre-initialization&#xff09; 目標&#xff1a;準備啟動器和環境配置關鍵類&am…

《深入理解 AOP》

一、AOP 是什么 AOP&#xff08;Aspect Oriented Programming&#xff09;&#xff0c;即面向切面編程&#xff0c;是軟件開發中一種重要的編程范式。它通過橫向抽取機制&#xff0c;將那些與業務邏輯本身無關、卻為業務模塊所共同調用的邏輯或責任&#xff08;如事務處理、日…

Python【協程(Coroutine)和線程的關系】

協程(Coroutine)和線程都是實現并發編程的技術&#xff0c;但它們在實現方式、使用場景和性能上有顯著區別。理解它們的關系與差異有助于在實際應用中選擇合適的并發模型&#xff0c;以下是它們的核心關系與對比分析&#xff1a; 一、核心關系 互補關系 協程和線程可以結合使用…

Springboot——Redis的使用

在當今的軟件開發領域&#xff0c;緩存技術是提升應用性能的關鍵手段之一。Redis 作為一款高性能的鍵值對存儲數據庫&#xff0c;憑借其出色的讀寫速度和豐富的數據結構&#xff0c;在緩存場景中得到了廣泛應用。Spring Boot 作為一款簡化 Spring 應用開發的框架&#xff0c;與…

BEVPoolv2:A Cutting-edge Implementation of BEVDet Toward Deployment

背景 該論文是在BEVDet的基礎上進行了一個調整優化&#xff0c;傳統的方法是將特征圖與深度預測進行外積得到視椎特征圖&#xff0c;再將它與預處理好的體素索引結合&#xff0c;將每個視椎特征分類到每個voxel中進行累加和的操作。BEVFusion與BEVDepth等方法是避免了累加和&a…

藍橋杯常考的找規律題

目錄 靈感來源&#xff1a; B站視頻鏈接&#xff1a; 找規律題具有什么樣的特點&#xff1a; 報數游戲&#xff08;Java組&#xff09;&#xff1a; 題目描述&#xff1a; 題目鏈接&#xff1a; 思路詳解&#xff1a; 代碼詳解&#xff1a; 階乘求和&#xff08;Java組…

使用ffmpeg 將圖片合成為視頻,填充模糊背景,并添加兩段音樂

1.輸入3張圖片,每張播放一次,播放兩秒,視頻分辨率設置為1920:1080,每張圖片前0.3秒淡入,后0.3秒淡出,圖片寬高比不變,用白色填充空白區域 ffmpeg -loop 1 -t 2 -i "img1.jpg" \-loop 1 -t 2 -i "img2.jpg" \-loop 1 -t 2 -i "img3.jpg" \-filte…

PostgreSQL技術內幕29:事件觸發器tag原理解析

文章目錄 0.簡介1.概念說明2.tag的生成和存儲2.1 tag合法性校驗2.2 內存中存儲2.3 持久化存儲 3.tag的觸發 0.簡介 在上一篇文章中中&#xff0c;我們介紹了PG中的兩種觸發器&#xff0c;即適合于DML的普通觸發器和對于DDL的事件觸發器&#xff0c;其中事件觸發器與常規的 DML…

mysql 導入很慢,如何解決

精選 原創 碼出財富2025-04-14 17:35:14博主文章分類&#xff1a;數據庫©著作權 文章標簽mysql數據庫用戶名文章分類MySQL數據庫yyds干貨盤點閱讀數184 導入大型 SQL 文件到 MySQL 數據庫時&#xff0c;速度可能會受到影響。以下是一些優化方法和建議&#xff0c;幫助你…

多物理場耦合低溫等離子體裝置求解器PASSKEy2

文章目錄 PASSKEy2簡介PASSKEY2計算流程PASSKEy2 中求解的物理方程電路模型等離子體模型燃燒模型 PASSKEy2的使用 PASSKEy2簡介 PASSKEy2 是在 PASSKEy1 的基礎上重新編寫的等離子體數值模擬程序。 相較于 PASSKEy1&#xff0c; PASSKEy2 在具備解決低溫等離子體模擬問題的能力…

保姆級zabbix監控jmx、數據庫和網絡監控(SNMP)

前言 在當今數字化時代&#xff0c;企業IT基礎設施的穩定性與性能直接關系到業務連續性和用戶體驗。隨著系統復雜性的不斷增加&#xff0c;單一維度的監控已難以滿足全面運維需求。Zabbix作為一款功能強大的開源監控解決方案&#xff0c;通過整合JMX&#xff08;Java Manageme…

復雜地形越野機器人導航新突破!VERTIFORMER:數據高效多任務Transformer助力越野機器人移動導航

作者&#xff1a; Mohammad Nazeri 1 ^{1} 1, Anuj Pokhrel 1 ^{1} 1, Alexandyr Card 1 ^{1} 1, Aniket Datar 1 ^{1} 1, Garrett Warnell 2 , 3 ^{2,3} 2,3, Xuesu Xiao 1 ^{1} 1單位&#xff1a; 1 ^{1} 1喬治梅森大學計算機科學系&#xff0c; 2 ^{2} 2美國陸軍研究實驗室&…

SharpMap與TerraLib:C#與C++開源GIS庫

大家好&#xff0c;今天為大家介紹的軟件是SharpMap&#xff1a;一款專為了C#&#xff08;.NET&#xff09;環境設計的開源地圖和空間數據處理庫&#xff1b;TerraLib&#xff1a;一款由C編寫、支持多種數據庫的開源的GIS軟件庫。 下面&#xff0c;我們將從兩個開源軟件的主要…

音視頻學習 - MP3格式

環境 JDK 13 IDEA Build #IC-243.26053.27, built on March 16, 2025 Demo MP3Parser MP3 MP3全稱為MPEG Audio Layer 3&#xff0c;它是一種高效的計算機音頻編碼方案&#xff0c;它以較大的壓縮比將音頻文件轉換成較小的擴展名為.mp3的文件&#xff0c;基本保持源文件的音…

Unity中數據和資源加密(異或加密,AES加密,MD5加密)

在項目開發中&#xff0c;始終會涉及到的一個問題&#xff0c;就是信息安全&#xff0c;在調用接口&#xff0c;或者加載的資源&#xff0c;都會涉及安全問題&#xff0c;因此就出現了各種各樣的加密方式。 常見的也是目前用的最廣的加密方式&#xff0c;分別是&#xff1a;DE…

部署本地deepseek并在調用的詳細步驟以及解決一些可能出現的問題(Windows,Linux, WSL)

打開Ollama官網&#xff1a;https://ollama.com/ 直接下載Ollama并且安裝好Ollama、這時候就能看到app里多了個ollama&#xff0c;但是我們不用打開它 打開Windows Powershell&#xff1a; ollama run deepseek-r1:1.5b 7b 8b 14b 32b 70b 根據自己的電腦配置和需求更換不同的…

【KWDB 創作者計劃】_嵌入式硬件篇---寄存器與存儲器截斷與溢出

文章目錄 前言一、寄存器與存儲器1. 定義與基本概念寄存器(Register)位置功能特點存儲器(Memory)位置功能特點2. 關鍵區別3. 層級關系與協作存儲層次結構協作示例4. 為什么需要寄存器性能優化指令支持減少總線競爭5. 其他寄存器類型專用寄存器程序計數器(PC)棧指針(SP)…

小白自學python第二天

學習python的第二天 一、判斷語句 1、布爾類型和比較運算符 1、布爾類型 表示現實生活中的邏輯&#xff0c;真&#xff08;True&#xff0c;用數字1表示&#xff09;和假&#xff08;False&#xff0c;用數字0表示&#xff09; 2、布爾類型變量的定義 變量的名稱 布爾類…