MyBaits(單獨使用,與整合無關)小白版

文章目錄

  • 概述
  • 比較
  • 配置
    • 寫xml
    • 加載上面配置并執行
      • 加載配置的方法
        • 方式一
      • 執行方法
        • 方式一
        • 方式二(MyBatis映射器)
    • 寫配置文件的映射文件
    • 設置對象的別名(簡寫)
    • 獲取自動生成的主鍵
  • 查詢結果和java的映射規則
    • 基本類型映射:
    • 簡單對象映射:
    • 嵌套對象映射:
      • 忽略大小寫:
      • 下劃線轉駝峰:
    • 構造器映射:
    • 注解映射:
      • 方式一
      • 方式二
  • 三個關鍵類的生命周期
    • 1.1.SqlSessionFactoryBuilder
    • 1.2.SqlSessionFactory
    • 1.3.SqlSession
  • 日志
    • 日志等級
    • 配置
    • 打印入參
  • #{}與${}比較
    • 使用的場景
  • 動態SQL
    • if
    • choose、when、otherwise
    • trim、where、set
    • foreach(批量操作)
    • bind
  • java API_MyBatis
    • SqlSessionFactoryBuilder
    • Resources 工具類
    • SqlSessionFactory
    • SqlSession
  • SQL類
  • 踩坑

概述

前生IBatis,現在很多包都是IBatis。

比較

MyBatis與JPA
MyBatis更加靈活,自己寫sql,可以Sql優化,
JPA不行,因為自己生成SQL

配置

寫xml

取名mybatis-config.xml,連接數據庫

<?xml version="1.0" encoding="UTF-8" ?>  聲明
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">  約束
<!--根元素,里面就是Mybatis配置-->
<configuration>
<!--    環境配置:數據庫的配置環境(怎么連接數據庫) ,可以配置多個環境對象 environment,多個數據庫的連接配置,可以通過  default="development" 來切換默認的環境
--><environments default="development"><environment id="development">
<!--            事務管理器,type="JDBC"使用JDBC的事務管理 "JdbcTransaction"  --><transactionManager type="JDBC"/>
<!--            數據源配置 POOLED 連接池,對應 PooledDataSource--><dataSource type="POOLED"><property name="driver" value="com.mysql.jdbc.Driver"/><property name="url" value="jdbc:mysql:///mybatis"/><property name="username" value="root"/><property name="password" value="123456"/></dataSource></environment><!--        <environment id="test">-->
<!--  		...	-->
<!--        </environment>--></environments>
<!--映射配置,標注清楚sql語句寫在哪里--><mappers><mapper resource="自己映射文件的目錄,xml文件"/></mappers>
</configuration>
  1. 環境可以設置多個,連接不同的數據庫,起不同的作用,可以將不同的用途設置給id,如測試,開發,生產環境等。
  2. 事務簡稱tx。

改進一下
數據庫的連接配置可以提出來
寫成一個jdbc.properties配置,配置加一個

<!--    加載properties--><properties resource="jdbc.properties" /><transactionManager type="JDBC"/><dataSource type="POOLED"><!--通過k取value--><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment>

再改進一下 3.5.2開始之后可用
如果屬性 ‘username’ 沒有被配置,‘username’ 屬性的值將為 ‘ut_user’
原理: ${tableName != null ? tableName : ‘global_constants’})

 <dataSource type="POOLED"><property name="username" value="${username:ut_user}"/> </dataSource><properties resource="org/mybatis/example/config.properties"><!-- 開啟上面的功能 ,可在value中自定義修改分隔符,寫了就換--><property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- 啟用默認值特性 -->
</properties>

加載上面配置并執行

會話工廠建造者建造會話工廠,會話工廠又生產會話,用會話去操作,
會話執行的方法,通過命名空間+id獲取。
執行的的各種方法都是在sqlSession類中

命名空間可以提出去,設置成常量
建造工廠可以提出去,創建一個utils
sqlSession用完要關掉,其他的不用
openSession()無參就需要手動提交 .commit(),如果傳了true那么就自動提交,不用commit()

加載配置的方法

方式一

在這里插入圖片描述

執行方法

方式一

在這里插入圖片描述
注意:方式一,namespace和Xxxmapper可以不同,但是在sqlssion.xxx,中和xml文件一致就可以了

方式二(MyBatis映射器)

加一個接口和命名空間一樣,與xml文件相連

public interface CustomerMapper {List<Customer>  selectCustomer();
}

或者注解

public interface CustomerMapper {@Select(" SELECT id,user_name,age,pwd,money  from users")List<Customer>  selectCustomer();
}
    //selectList = sqlSession.selectList(NAMESPACE + "selectCustomer");//替換成下面的這個語句CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);selectList = mapper.selectCustomer();

原理 :動態代理,用cglib動態代理實現的。
在這里插入圖片描述
service層中的改變
在這里插入圖片描述

寫配置文件的映射文件

寫了這個還需要寫一個命名空間接口,其中的方法對應id的值,那個接口也可以不用寫,寫是為了和service結合,這里不用結合,就可以不用寫,這個命名空間在這里可以寫此個xml文件名,
還需要寫一個實體類,對應查詢回來的數據對應resultType的值
沒有配置簡寫,就要寫完全。

Mapper文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:命名空間 ,sql坐標(SQL在哪兒)規范寫法:一般寫這個mapper.xml所在的包的路徑
-->
<mapper namespace="接口,需要實現的方法的接口MxxMapper,">
<!-- 查詢語句 id是sql的id,在同一個mapper.xml中必須唯一如何精準的找到一個SQL     namespace+idresultType:返回的結果的實體類
--><select id="唯一標識符,對應的是命名空間接口中的某個方法"       resultType="返回的實體類路徑" ParameterType="參數類型"></select></mapper>

設置對象的別名(簡寫)

自己寫的類配置別名
在MyBatis-Config.xml配置

<!--    加載properties--><properties resource="jdbc.properties" /><typeAliases><!--給單個類設置別名 alias的值可以任意寫--><typeAlias type="com.ronghuanet.mybatis.domain.Product" alias="Product" /><!--掃描包,這個包下面的所有類都設置一個別名-->
<!--        <package name="com.ronghuanet.mybatis.domain"/>--></typeAliases>.........

框架含有的
在這里插入圖片描述

獲取自動生成的主鍵

先設置這個

   <!--自動生成主鍵賦值給對象的對應的成員變量,再插入進去--><insert ...... useGeneratedKeys="true" 開啟自動生成主鍵  keyColumn="id" 數據庫主鍵列,告訴框架id列  keyProperty="id" 與數據庫對應主鍵的成員變量></insert>

再插入之后,在獲取主鍵,就可以獲取到。
在這里插入圖片描述

查詢結果和java的映射規則

注意:查詢返回的類型必須要有無參構造。

可以映射的東西: Java 基本數據類型、自定義的 Java 類,以及 java.util.Map(HashMap)等

基本類型映射:

當查詢的結果只有一個列時,MyBatis 可以將該列的值直接映射到一個基本數據類型或包裝類(如 int、String、Long 等)。

簡單對象映射:

當查詢的結果包含多個列時,可以通過在映射文件中使用 標簽來定義對象映射規則。通過指定結果列和 Java 對象屬性的對應關系,MyBatis 將查詢結果映射到一個簡單對象(POJO)中。

 <resultMap id="baseResultMap(唯一表示符)" type="映射的java類型"><id column="id" 數據庫列  property="id" 對象屬性 /><result column="product_name" 數據庫列 property="productName" 對象屬性/></resultMap>

將resultType改成resultMap

嵌套對象映射:

如果查詢的結果包含多個表的數據,可以使用 和 標簽來進行嵌套對象映射。通過在映射文件中定義關聯關系,MyBatis 可以將查詢結果映射到一個復雜的對象圖中,包含多個對象之間的關聯關系。
注意: 最好逐步建立結果映射。單元測試可以在這個過程中起到很大幫助。 從最簡單的形態開始,逐步迭代。而且別忘了單元測試! 有時候,框架的行為像是一個黑盒子(無論是否開源)。因此,為了確保實現的行為與你的期望相一致,最好編寫單元測試。 并且單元測試在提交 bug 時也能起到很大的作用。

使用時避免使用 n+1
原理:list肯很大,list是主要 需要展示的對象
在這里插入圖片描述

忽略大小寫:

MyBatis 在進行列名和屬性名的匹配時,默認是忽略大小寫的。這意味著列名和屬性名在大小寫上不區分,可以自動匹配成功。
原理:MyBatis 在進行自動映射時,會根據 Java 對象中的 Setter 方法(即屬性的設置方法)來確定屬性名,并將查詢結果集中的列值賦給該屬性。具體來說,MyBatis 會按照以下規則生成屬性名:
setName(去掉set)->Name(N變小寫)->name 與數據庫的字段列一樣就好了

下劃線轉駝峰:

MyBatis 支持將下劃線分隔的列名轉換為駝峰式命名的屬性名。例如,如果查詢結果的列名是 user_name,而對象中的屬性名是 userName,
則 MyBatis 可以自動將其映射起來。這個需要開啟

<settings><setting name="mapUnderscoreToCamelCase" value="true"/></settings>
  1. 類型處理器:在自動映射時,如果數據庫中的數據類型和 Java 對象屬性的類型不匹配,MyBatis 會嘗試使用類型處理器進行轉換。

構造器映射:

除了使用默認的無參構造器來創建對象,MyBatis 還支持使用帶參構造器來創建對象,并通過列值來調用相應的構造器。

  1. Java 對象必須具有帶參構造器:要使用構造器映射,Java 對象必須定義了帶參數的構造器。

  2. 構造器的參數順序和類型要與查詢結果的列對應:構造器的參數順序和類型必須和查詢結果的列一一對應。MyBatis 會根據列名和構造器參數名的匹配關系來確定調用哪個構造器。

<resultMap id="userResultMap" type="User"><constructor><idArg column="id" javaType="Long" /><arg column="username" javaType="String" /><arg column="age" javaType="Integer" /></constructor>
</resultMap>

注解映射:

方式一

除了 XML 配置文件外,MyBatis 還支持使用注解來定義對象映射規則。通過在 Java 對象上添加 @Results 和 @Result 注解,可以實現對象與查詢結果的映射。

public class User {@Result(column = "user_id", property = "userId")private Long userId;@Result(column = "username", property = "username")private String username;// 省略 getter 和 setter 方法
}或者
@Results({@Result(column = "user_id", property = "userId"),@Result(column = "username", property = "username")
})
@Select("SELECT user_id, username FROM users")
List<User> getUsers();

方式二

在注解映射中,我們可以使用注解來描述實體類(Java 對象)與數據庫表的對應關系,以及實體類的屬性與表字段的對應關系。通過這些注解的配置,框架可以自動完成數據庫的增刪改查操作,并將查詢結果映射到對應的 Java 對象中。

  1. @Entity:用于標識實體類,表示該類與數據庫表對應。
  2. @Table:用于指定實體類與數據庫表的映射關系,可以指定表名、schema 等信息。
  3. @Column:用于指定實體類的屬性與數據庫表字段的映射關系,可以指定字段名、長度、默認值等信息。
  4. @Id:用于指定實體類的主鍵屬性,表示該屬性是數據庫表的主鍵。
  5. @GeneratedValue:用于指定主鍵的生成策略,如自增長、UUID 等。
  6. @Transient:用于指定實體類的屬性不與數據庫表字段進行映射,即忽略該屬性。
@Entity
@Table(name = "user")
public class User {@Id@GeneratedValue(strategy = GenerationType.IDENTITY)private Long id;@Column(name = "username")private String username;@Column(name = "age")private Integer age;// 省略 getter 和 setter 方法
}

三個關鍵類的生命周期

1.1.SqlSessionFactoryBuilder

? 這個類可以被實例化,使用和丟棄。一旦你創建了 SqlSessionFactory 后,這個類就不需要存在了。(因為工廠創建了,工人就不需要了)

1.2.SqlSessionFactory

? 一旦被創建,SqlSessionFactory 應該在你的應用執行期間都存在,因為是工廠,需要不斷創建sqlsession,它應該是單例的也是線程安全的,并且隨著應用的創建而創建,隨著應用的銷毀而銷毀。SqlSessionFactory 中存儲了:1.xml基本信息,2.連接池對象, 3.二級緩存。SqlSession是通過SqlSessionFactory來創建的。

1.3.SqlSession

? 每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不能被共享,也是線程不安全的。因此最佳的范圍是請求或方法范圍。它內部存儲的東西**:1.連接對象 , 2.一級緩存。**

日志

日志等級

trace(最小,全部都要打印) ,debug(調試) , info(提示) , warn(警告) ,error(錯誤)

配置

創建一個log4j的配置文件
將配置文件放置在類路徑下:將創建好的 Log4j 配置文件放置在項目的類路徑下,MyBatis 會在初始化過程中自動加載類路徑下的 Log4j 配置文件,并根據配置文件中的設置來進行日志輸出
一部分配置配什么查什么

#全局日志配置
log4j.rootLogger = info,console#輸出局部的日志信息(自己的包中的日志打印方式)
log4j.logger.com.wj=TRACE  自己哪里的數據操作需要打印操作### 配置輸出到控制臺
log4j.appender.console = org.apache.log4j.ConsoleAppender
### 使用System.out打印日志
log4j.appender.console.Target = System.out
### 指定日志的格式布局(日志是有格式的)
log4j.appender.console.layout = org.apache.log4j.PatternLayout
### 日志的打印格式
log4j.appender.console.layout.ConversionPattern =  %d{ABSOLUTE} %5p %c{1}:%L - %m%n

打印入參

進入每一個方法時都可以寫,這樣可以更好的理解程序的執行過程和傳入的數據情況
在這里插入圖片描述

#{}與${}比較

實#{}的底層就是使用的 “?”占位符的方式來拼接SQL,而${}使用的是直接把拼接到SQL中

看看有什么不一樣

  <select id="selectById" parameterType="long" resultType="...Employee">select * from employee where id = #{id}</select>
-----------------------------------------------------------------------------------------------------<select id="selectById" parameterType="long" resultType="...Employee">select * from employee where id = ${id}</select>

直接拼接會調用 g e t t e r 方法去獲取值,會用屬性值用于 D D L 可以用再 {} 直接拼接 會調用getter方法去獲取值,會用屬性值 用于DDL 可以用再 直接拼接會調用getter方法去獲取值,會用屬性值用于DDL可以用再{group by}
#{} 占位符 不用要用getter方法獲取 DQL

使用的場景

${} 適用于靜態的表名、列名等,以及一些需要進行復雜表達式的參數替換,使用時需要注意 SQL 注入風險。

#{} 主要用于替換動態生成的參數值,通常在查詢條件、插入或更新的參數中使用。提高安全和速度。

@Select("select * from user where ${column} = #{value}")
User findByColumn(@Param("column") String column, @Param("value") String value);

動態SQL

if

可以匹配多個分支

 <if test="title != null">AND title like #{title}</if>

注意
如果用 < 這是一個標簽開始符號,
要改成 轉義符
在這里插入圖片描述
如果用要用where
解決一:
在第一個if標簽中加where
再在最開始的表名后面 1+1 但是這樣就不會用索引了
解決二:
直接用where標簽把他們嵌套進去

choose、when、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>

trim、where、set

where 元素只會在子元素返回任何內容的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除
trim:通過自定義 trim 元素來定制 where 和set元素的功能。
set 元素可以用于動態包含需要更新的列,忽略其它不更新的列。
例如:set

這個set 元素會動態地在行首插入 SET 關鍵字,并會刪掉額外的逗號<set><if test="username != null">username=#{username},</if><if test="password != null">password=#{password},</if><if test="email != null">email=#{email},</if><if test="bio != null">bio=#{bio}</if></set>等價<trim prefix="SET" suffixOverrides=",">...
</trim>

例如:WHERE

 若子句的開頭為 “AND” 或 “OR”,where 元素也會將它們去除。<where><if test="state != null">state = #{state}</if><if test="title != null">AND title like #{title}</if><if test="author != null and author.name != null">AND author_name like #{author.name}</if></where>等價
<trim prefix="WHERE" prefixOverrides="AND |OR ">...
</trim>

foreach(批量操作)

數據最多不能超過4M
如 批量刪除

常見使用場景是對集合進行遍歷(尤其是在構建 IN 條件語句的時候)
注意當使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值。

它允許你指定一個集合,聲明可以在元素體內使用的集合項(集合里的對象)(item)和索引(index)變量
。它也允許你指定開頭與結尾的字符串以及集合項迭代之間的分隔符
WHERE ID in<foreach item="item" index="index" collection="list"open="(" separator="," close=")">#{item}</foreach>

在這里插入圖片描述

如 批量插入需求
在這里插入圖片描述
上下不匹配
在這里插入圖片描述

bind

給一段語句設置一個變量
bind 元素允許你在 OGNL 表達式以外創建一個變量,并將其綁定到當前的上下文
OGNL 表達式的作用:可以存取對象的屬性和調用對象的方法,通過OGNL 表達式可以迭代獲取對象的結構圖

<select id="selectBlogsLike" resultType="Blog"><bind name="pattern" value="'%' + _parameter.getTitle() + '%'" />SELECT * FROM BLOGWHERE title LIKE #{pattern}
</select>

java API_MyBatis

SqlSessionFactoryBuilder

自我感覺這個類不太重要
SqlSessionFactoryBuilder 有五個 build() 方法,每一種都允許你從不同的資源中創建一個 SqlSessionFactory 實例。
第一種方法是最常用的,它接受一個指向 XML 文件

SqlSessionFactory build(InputStream inputStream)
SqlSessionFactory build(InputStream inputStream, String environment)
SqlSessionFactory build(InputStream inputStream, Properties properties)
SqlSessionFactory build(InputStream inputStream, String env, Properties props)
SqlSessionFactory build(Configuration config)

Resources 工具類

URL getResourceURL(String resource)
URL getResourceURL(ClassLoader loader, String resource)
InputStream getResourceAsStream(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)
Properties getResourceAsProperties(String resource)
Properties getResourceAsProperties(ClassLoader loader, String resource)
Reader getResourceAsReader(String resource)
Reader getResourceAsReader(ClassLoader loader, String resource)
File getResourceAsFile(String resource)
File getResourceAsFile(ClassLoader loader, String resource)
InputStream getUrlAsStream(String urlString)
Reader getUrlAsReader(String urlString)
Properties getUrlAsProperties(String urlString)
Class classForName(String className)

SqlSessionFactory

SqlSessionFactory 有六個方法創建 SqlSession 實例。通常來說,當你選擇其中一個方法時,你需要考慮以下幾點:

  1. 事務處理:你希望在 session 作用域中使用事務作用域,還是使用自動提交(auto-commit)?(對很多數據庫和/或 JDBC 驅動來說,等同于關閉事務支持)
  2. 數據庫連接:你希望 MyBatis 幫你從已配置的數據源獲取連接,還是使用自己提供的連接?
  3. 語句執行:你希望 MyBatis 復用 PreparedStatement 和/或批量更新語句(包括插入語句和刪除語句)嗎?
SqlSession openSession()
SqlSession openSession(boolean autoCommit)
SqlSession openSession(Connection connection)
SqlSession openSession(TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level)
SqlSession openSession(ExecutorType execType)
SqlSession openSession(ExecutorType execType, boolean autoCommit)
SqlSession openSession(ExecutorType execType, Connection connection)
Configuration getConfiguration();

ExecutorType.SIMPLE:該類型的執行器沒有特別的行為。它為每個語句的執行創建一個新的預處理語句
ExecutorType.REUSE:該類型的執行器會復用預處理語句
ExecutorType.BATCH該類型的執行器會批量執行所有更新語句,如果 SELECT 在多個更新中間執行,將在必要時將多條更新語句分隔開來,以方便理解

SqlSession

游標(Cursor)與列表(List)返回的結果相同,不同的是,游標借助迭代器實現了數據的惰性加載。

try (SqlSession sqlSession = sqlSessionFactory.openSession()) {try (Cursor<User> cursor = sqlSession.selectCursor("com.example.UserMapper.getAllUsers")) {Iterator<User> iterator = cursor.iterator();while (iterator.hasNext()) {User user = iterator.next();// 處理 user 數據}}
}

游標:使用游標,查詢結果不會一次性全部加載到內存中,而是通過迭代器逐行獲取,這可以減少內存占用,尤其在處理大型結果集時更為有效。
列表:列表返回的方式是將查詢結果集全部加載到內存的 List 集合中,這使得你可以立即訪問整個結果集,但也可能導致內存占用較大,尤其是在處理大量數據時。列表方式適合于小規模的結果集,可以一次性加載并在內存中進行操作。

select 方法的三個高級版本,它們允許你限制返回行數的范圍,或是提供自定義結果處理邏輯,通常在數據集非常龐大的情形下使用

<E> List<E> selectList (String statement, Object parameter, RowBounds rowBounds)
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds)
<K,V> Map<K,V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowbounds)
void select (String statement, Object parameter, ResultHandler<T> handler)
void select (String statement, Object parameter, RowBounds rowBounds, ResultHandler<T> handler)

RowBounds 參數會告訴 MyBatis 略過指定數量的記錄,并限制返回結果的數量。RowBounds 類的 offset 和 limit 值**只有在構造函數**時才能傳入,其它時候是不能修改的。

int offset = 100;  開始的點
int limit = 25;		限制的行
RowBounds rowBounds = new RowBounds(offset, limit);

數據庫驅動決定了略過記錄時的查詢效率。為了獲得最佳的性能,建議將 ResultSet 類型設置為 SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE
SCROLL_SENSITIVE:滾動敏感,可以接收其他事務對數據的更改
SCROLL_INSENSITIVE:滾動不敏感

SQL類

JAVA生成代碼

public class UserSqlProvider {
public String getUsers(String username, String email) {return new SQL().SELECT("id, username, email").FROM("users").WHERE().<if test="username != null">AND username = #{username}</if>.<if test="email != null">AND email = #{email}</if>.toString();}
}//使用
@SelectProvider(type = UserSqlProvider.class, method = "getUsers")
List<User> getUsers(@Param("username") String username, @Param("email") String email);

踩坑

這樣寫IStudentService studentService = new StudentServiceImpl();static {try {SqlSession sqlSession = MyBatisUtils.getSqlSession();IDepartmentMapper departmentMapper = sqlSession.getMapper(IDepartmentMapper.class);} catch (Exception e) {e.printStackTrace();}}
不能
會報錯,excutor。。被關閉了IStudentService studentService = new StudentServiceImpl();static {try( SqlSession sqlSession = MyBatisUtils.getSqlSession()) {IDepartmentMapper departmentMapper = sqlSession.getMapper(IDepartmentMapper.class);} catch (Exception e) {e.printStackTrace();}}

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

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

相關文章

加鹽加密算法

MD5加密加鹽加密項目密碼升級 MD5加密 MD5一系列公式進行復雜數學運算&#xff1b;特點&#xff1a;&#xff08;用途校驗和、計算hash值方式、加密&#xff09; 1&#xff1a;定長&#xff1b;無論原始數據多長&#xff1b;算出的結果都是4或者8字節的版本。 2&#xff1a;沖…

Java多線程實戰

Java多線程實戰 java多線程&#xff08;超詳細&#xff09; java自定義線程池總結 Java創建線程方式 方法1&#xff0c;繼承Thread類 方法2&#xff0c;實現Runable接口 方法2-2&#xff0c;匿名內部類形式lambda表達式 方法3&#xff0c;實現Callable接口&#xff0c;允許…

【深入理解Linux內核鎖】三、原子操作

我的圈子: 高級工程師聚集地 我是董哥,高級嵌入式軟件開發工程師,從事嵌入式Linux驅動開發和系統開發,曾就職于世界500強企業! 創作理念:專注分享高質量嵌入式文章,讓大家讀有所得! 文章目錄 1、原子操作思想2、整型變量原子操作2.1 API接口2.2 API實現2.2.1 原子變量結…

Shell 函數

Shell 函數 linux shell 可以用戶定義函數&#xff0c;然后在shell腳本中可以隨便調用。 shell中函數的定義格式如下&#xff1a; [ function ] funname [()] { action; [return int;] } 說明&#xff1a; 1、可以帶function fun() 定義&#xff0c;也可以直接fun…

log4j:WARN No appenders could be found for logger問題

本文將idea場景下的使用。 IDEA中&#xff0c;將配置文件命名為log4j.properties&#xff08;該命名才會被自動加載&#xff09;&#xff0c; 并放到某個目錄下&#xff08;通常放到resources目錄&#xff09;&#xff0c;并在resources上右鍵&#xff0c;找到Mark Directory a…

微信程序 自定義遮罩層遮不住底部tabbar解決

一、先上效果 二 方法 1、自定義底部tabbar 實現&#xff1a; https://developers.weixin.qq.com/miniprogram/dev/framework/ability/custom-tabbar.html 官網去抄 簡單寫下&#xff1a;在代碼根目錄下添加入口文件 除了js 文件的list 需要調整 其他原封不動 代碼&#xf…

Hadoop數據遷移distcp

Hadoop數據遷移distcp 準備工作 確認源集群&#xff08;a&#xff09;,目標集群&#xff08;b&#xff09;確認a集群的主節點和b集群的主節點確認兩個集群的網絡相通確認遷移模式&#xff08;全量遷移還是增量遷移&#xff09;&#xff0c;這里選擇全量遷移 遷移文件 遷移t…

【路由協議】使用按需路由協議和數據包注入的即時網絡模擬傳遞率(PDR)、總消耗能量和節點消耗能量以及延遲研究(Matlab代碼實現)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;歡迎來到本博客????&#x1f4a5;&#x1f4a5; &#x1f3c6;博主優勢&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客內容盡量做到思維縝密&#xff0c;邏輯清晰&#xff0c;為了方便讀者。 ??座右銘&a…

斯坦福「小鎮」開源AI智能體;小米應用商店將要求AI應用符合資質標準

&#x1f989; AI新聞 &#x1f680; 斯坦福「小鎮」開源AI智能體 摘要:斯坦福研究人員開源了一個類似《西部世界》的數字化「小鎮」,里面有25個AI智能體可以生活、工作、社交。這項研究被視為AGI的重要開端,可能會改變游戲、企業應用領域。網友期待這項技術改善游戲NPC的交互…

PyMuPDF`庫實現PDF旋轉功能

本文介紹了一個簡單的Python應用程序&#xff0c;用于將PDF文件轉換為旋轉90度的PDF文件。主要用于csdn網站中導出的博客pdf是橫向的&#xff0c;看起來不是很方便&#xff0c;才想到用python編制一個將pdf從橫向轉為縱向的功能。 功能 該PDF轉換工具具有以下功能&#xff1a…

信息安全:防火墻技術原理與應用.

信息安全&#xff1a;防火墻技術原理與應用. 防火墻是網絡安全區域邊界保護的重要技術。為了應對網絡威脅&#xff0c;聯網的機構或公司將自己的網絡與公共的不可信任的網絡進行隔離&#xff0c;其方法是根據網絡的安全信任程度和需要保護的對象&#xff0c;人為地劃分若干安全…

C#工程建立后修改工程文件名與命名空間

使用之前的項目做二次開發&#xff0c;項目快結束的時候&#xff0c;需要把主項目的名稱修改成我們想要的。 之前從來沒有這么干過&#xff0c;記錄一下。 步驟如下&#xff1a; 1&#xff1a;打開vs2010項目解決方案&#xff0c;重命名&#xff0c;如下圖所示&#xff1a; …

SDP協議是什么,詳解SDP協議

一、SDP協議簡介 SDP&#xff08;Session Description Protocol&#xff09;是一種會話描述協議&#xff0c;用于描述多媒體會話的參數。它是一種文本協議&#xff0c;通常用于VoIP&#xff08;Voice over Internet Protocol&#xff09;和視頻會議等應用中。SDP協議定義了一種…

Vue項目(購物車)

目錄 購物車效果展示&#xff1a; 購物車代碼&#xff1a; 購物車效果展示&#xff1a; 此項目添加、修改、刪除數據的地方都寫了瀏覽器都會把它存儲起來 下次運行項目時會把瀏覽器數據拿出來并在頁面展示 Video_20230816145047 購物車代碼&#xff1a; 復制完代碼&#xff0…

leetcode每日一題_2682.找出轉圈游戲輸家

2682.找出轉圈游戲輸家 題目: n 個朋友在玩游戲。這些朋友坐成一個圈&#xff0c;按 順時針方向 從 1 到 n 編號。從第 i 個朋友的位置開始順時針移動 1 步會到達第 (i 1) 個朋友的位置&#xff08;1 < i < n&#xff09;&#xff0c;而從第 n 個朋友的位置開始順時針移…

設計模式之原型模式Prototype的C++實現

1、原型模式提出 在軟件功能設計中&#xff0c;經常面臨著“某些結構復雜的對象”的創建工作&#xff0c;且創建的對象想擁有其他對象在某一刻的狀態&#xff0c;則可以使用原型模型。原型模型是通過拷貝構造函數來創建對象&#xff0c;并且該對象擁有其他對象在某一刻的狀態。…

Docker基礎入門:鏡像、容器導入導出與私有倉庫搭建

Docker基礎入門&#xff1a;鏡像導入導出與私有倉庫搭建 一、 Docker鏡像、容器的導入和導出1.1、Docker鏡像的導出1.2、Docker鏡像的載入1.3、Docker容器的導出1.4、Docker容器的導入 二、 鏡像和容器導出和導入的區別:三、commit操作_本地鏡像發布到阿里云3.1、commit操作有關…

ppt中線材相交接的地方,如何繪畫

ppt中線材相交接的地方&#xff1a; 在ppt中繪畫線材相互交接的地方&#xff1a; 1.1繪圖工具中的“弧形” 1.2小技巧 “弧形”工具點一下&#xff0c;在ppt中如下 1.3拖動活動點進行調整圖形 1.4繪畫圓弧 1.5調整“圓弧”的大小&#xff0c;鼠標放在“黃色點”位置&#xf…

【JVM】垃圾回收算法

目錄 一、判斷對象已“死” 1.1、引用計數算法 1.2、可達性分析算法 1.3、引用的概念 二、垃圾收集算法理論 2.1、分代收集理論 三、垃圾收集算法 3.1、標記--清除算法 3.2、標記--復制算法 3.3、標記--整理算法 一、判斷對象已“死” 在堆里面存放著Java世界中幾乎所…

【數據結構】二叉搜索樹

&#x1f680; 作者簡介&#xff1a;一名在后端領域學習&#xff0c;并渴望能夠學有所成的追夢人。 &#x1f40c; 個人主頁&#xff1a;蝸牛牛啊 &#x1f525; 系列專欄&#xff1a;&#x1f6f9;數據結構、&#x1f6f4;C &#x1f4d5; 學習格言&#xff1a;博觀而約取&…