主頁 > 後端開發 > MyBatis體系筆記(未完結)

MyBatis體系筆記(未完結)

2023-05-25 11:58:15 後端開發

MyBatis

什么是MyBatis

  • MyBatis是優秀的持久層框架

  • MyBatis使用XML將SQL與程式解耦,便于維護

  • MyBatis學習簡單,執行高效,是JDBC的延伸

1.MyBatis開發流程

  • 引入MyBatis依賴

  • 創建核心組態檔

  • 創建物體(Entity)類

  • 創建Mapper映射檔案

  • 初始化SessionFactory

  • 利用SqlSession物件操作資料

1.1引入MyBatis依賴

利用maven直接從倉庫匯入即可,有的小伙伴肯定不知道怎么去官網找,先來教一下好了,

官網鏈接:Maven Repository: maven (mvnrepository.com)

直接搜索mybatis然后點擊第一個就好了

image-20230521112100242

這里我們選擇3.5.1版本

image-20230521132339229

往下滑我們可以看到他的配置資訊,復制到pom.xml即可

image-20230521132504045

關于配置pom.xml時IDEA報錯解決方案

有時候我們的idea會抽風,復制過來之后會報紅或者顯示無法在中央倉庫中找到依賴,一般剪切掉它再貼一遍就好了,實在不行重啟一下idea

<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>Mybatis</artifactId>
  <version>3.5.1</version>
</dependency>
?
//mysql包順便也放這里了,如果使用mysql的同學記得加上
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.47</version>
</dependency>

1.2創建核心組態檔

差不多和Spring的組態檔差不多格式

<?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">
?
<!--核心組態檔-->
<configuration>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/com.mysql.jdbc.Driver"/>
                <property name="url" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/jdbc:mysql://localhost:3306/ajaxdb?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
                <property name="username" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/root"/>
                <property name="password" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/20030515"/>
            </dataSource>
        </environment>
    <!--    在這里可以配置多個環境,比如生產環境,只需要切換第8行的default為每個環境的id即可-->
        <environment id="produce">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/jdbc:mysql://localhost:3306/ajaxdb?useSSL=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai"/>
                <property name="username" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/root"/>
                <property name="password" value="https://www.cnblogs.com/hanlinyuan/archive/2023/05/25/20030515"/>
            </dataSource>
        </environment>
    </environments>
?
    <mappers>
        <!--用來配置mapper的xml配置文件,相當于告訴mybatis我的用于sql陳述句的組態檔放哪里-->
        <mapper resource="mapper/ajaxdb.xml"/>
    </mappers>
</configuration>
?

1.3創建物體(Entity)類

這里不再贅述,跟之前的JDBC連接資料庫時要創建出一個跟表中欄位相同的類是一樣的,韓順平Spring體系化筆記(內含ioc,aop,動態代理等底層原理) - 翰林猿 - 博客園 (cnblogs.com)

具體可以查看本文中第10小節,不過既然都學到了mybatis想必對此熟悉的不能再熟悉了,

1.4創建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陳述句,每種又有自己的id,
比如說到時候要使用select * from user時就直接填入user.selectAll即可-->
<mapper namespace="user">
    <!--id 相當于給這段用于select的sql陳述句取一個別名,到時候直接用selectAll代替 select * from user 這句話-->
    <!--resultType中填寫entity類的全路徑-->
    <select id="selectAll" resultType="entity.ajaxdbEntity">
        select * from user;
    </select>
</mapper>

1.5初始化SessionFactory

在這里我們順便撰寫一個工具類

package utils;
import entity.ajaxdbEntity;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Test;
?
import java.io.IOException;
import java.io.Reader;
import java.util.List;
?
/**
 * @Author: 翰林猿
 * @Description: TODO
 **/
public class MyBatisUtils {
    /**
     * MyBatisUtils工具類,創建全域唯一的SqlSessionFactory物件
     */
?
    //利用static(靜態)屬于類不屬于物件,且全域唯一
    private static SqlSessionFactory sqlSessionFactory = null;
?
    //利用靜態塊在初始化類時實體化sqlSessionFactory
    static {
        Reader reader = null;
        try {
            這里的Resources
            reader = Resources.getResourceAsReader("mybatisConfig.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            //初始化錯誤時,通過拋出例外ExceptionInInitializerError通知呼叫者
            throw new ExceptionInInitializerError(e);
        }
    }
?
    /**
     * openSession 創建一個新的SqlSession物件
     * SqlSession物件類似于JDBC中的Connection
     * @return SqlSession物件
     */
    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }
?
    /**
     * 釋放一個有效的SqlSession物件
     *類似于JDBC中釋放獲取到的Connection
     * @param session 準備釋放SqlSession物件
     */
    public static void closeSession(SqlSession session) {
        if (session != null) {
            session.close();
        }
    }
    
    //簡單測驗一下
    @Test
    public void test(){ 
        //類似于獲取Connection
        SqlSession sqlSession = MyBatisUtils.openSession();
        List<ajaxdbEntity> ajaxdbDaoList = sqlSession.selectList("user.selectAll");
        for (ajaxdbEntity dao : ajaxdbDaoList) {
            System.out.println(dao.getId());
            System.out.println(dao.getUsername());
        }
    }
}
?

mybatis底層實作(造輪子)

image-20230522202933837

 

 

2.SQL

SQL傳參及查詢

回憶之前的JDBC中在組織sql陳述句時 使用問號動態傳入引數 進行查詢的操作,同樣我們mybatis也有,

<!--parameterType也就是傳入的引數的型別是什么-->
<select id="selectList" resultType="entity.ajaxdbEntity" parameterType="Map">
        select * from user 
        where id between #{min} and #{max}
        order by id;
    </select>

這里我們使用map的形式作為引數傳遞,那么怎么使用呢,修改一下我們的 Test 函式作為示例,

@Test
    public void test(){
        //類似于獲取Connection
        SqlSession sqlSession = MyBatisUtils.openSession();
        HashMap map = new HashMap();
        map.put("min",1);
        map.put("max",3);
        //mybatis底層會將傳入的map決議,找到#{key}對應的value填入sql陳述句中
        List<ajaxdbEntity> ajaxdbDaoList = sqlSession.selectList("user.selectList",map);
        for (ajaxdbEntity map : ajaxdbDaoList) {
            System.out.println(map);
        }
    }

多表查詢

多表查詢時我們不再需要填入parameterType,而且resultType使用Map或者LinkHashMap

使用Map的話,查詢出來的欄位順序是混亂的,具體看Map的底層原理,而LinkHashMap是按順序的,

但是這種查詢方式有一個很大的缺點,你應該也已經發現了,為什么我們的resultType不再是物體Entity類了?

這種查詢方式不需要經過驗證,他什么東西都可以直接查詢出來,所以在企業中開發大型專案還是一般不使用這種方式,

    <select id="selectTwice"  resultType="Map">
        select * from user,user2;
    </select>

所以我們使用ResultMap結果映射,來解決一下這個問題,

ResultMap結果映射查詢

作用:首先是完成資料庫欄位與物體類欄位的映射(類似之前為了解決資料庫欄位和物體類欄位不相同采用AS陳述句完成映射),其次就是解決上面所提到的問題,

說白了,還是Entity那套,再創建一個類,作為多表查詢的物體類,只不過這個類里有多個entity的欄位罷了,那么我們來寫一下這個欄位吧,

package entity;
?
/**
 * @Author: 翰林猿
 * @Description: 多表查詢物體類
 **/
public class UserDTO {
    private user user = new user();     //user表
    private String cn;                 //user2表中的cn欄位(ChineseName的縮寫)
?
    @Override
    public String toString() {
        return "UserDTO{" +
                "user=" + user +
                ", cn='" + cn + '\'' +
                '}';
    }
?
    public user getUser() {
        return user;
    }
?
    public void setUser(user user) {
        this.user = user;
    }
?
    public String getCn() {
        return cn;
    }
?
    public void setCn(String cn) {
        this.cn = cn;
    }
?
    public UserDTO() {
    }
?
    public UserDTO(user ajaxdbEntity, String cn) {
        user = ajaxdbEntity;
        this.cn = cn;
    }
}
?

好,我們再來看看基本使用方法,我們要定義一個resultMap標簽,id值就是作為這段resultMap的別名,type是最后查詢回傳的類的全路徑,然而里面又有很多種標簽,這里我們就介紹2個,其他的請大家自己前往mybatis官網查看教程,

我們的id和result標簽中又包括兩個引數,property以及column

  • property :填寫的必須與上面的type中的類的欄位完全相同,(也就是UserDTO中的欄位),其中有一個欄位是user類的,那么為了拿到user類中的欄位直接使用 . 運算子即可,

  • column :資料庫中的列名,或者是列的別名,

    <resultMap id="selectDTO" type="entity.UserDTO">
        <id property="user.id" column="id"></id>
        <result property="user.username" column="username"/>
        <result property="user.pwd" column="pwd"/>
        <result property="user.email" column="email"/>
        <result property="cn" column="cn"/>
         property對應物體類的屬性 ,colum對應資料庫的欄位
    </resultMap>
?
    <select id="selectTwice"  resultMap="selectDTO">
        select user.* , cn from user,user2;
    </select>
/**
 * @Author: 翰林猿
 * @Description: 多表查詢物體類,測驗
 **/
@Test
    public void test(){
        //類似于獲取Connection
        SqlSession sqlSession = MyBatisUtils.openSession();
        List<UserDTO> ajaxdbDaoList = sqlSession.selectList("User.selectTwice");
        for (UserDTO map : ajaxdbDaoList) {
            System.out.println(map);
        }
    }

 

 

SQL插入

我們在寫sql插入陳述句的時候有時候要寫很多列名,真的是非常令人煩惱啊,很顯然,mybais開發人員也想到了這點,用foreach標簽節約開發時間,

foreach元素的屬性主要有 item,index,collection,open,separator,close,

  • item表示集合中每一個元素進行迭代時的別名,

  • index指 定一個名字,用于表示在迭代程序中,每次迭代到的位置,

  • open表示該陳述句以什么開始,

  • separator表示在每次進行迭代之間以什么符號作為分隔符,

  • close表示以什么結束,

    <!--INSERT INTO table-->
    <!--VALUES ("a" , "a1" , "a2"),("b" , "b1" , "b2"),(....)-->
    <insert id="batchInsert" parameterType="java.util.List">
        INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id)
        VALUES
        <foreach collection="list" item="item" index="index" separator=",">
            (#{item.title},#{item.subTitle}, #{item.originalCost}, #{item.currentPrice}, #{item.discount}, #{item.isFreeDelivery}, #{item.categoryId})
        </foreach>
    </insert>

注意新增資料之后,要記得提交事務

    /**
     * 新增資料,示范用例
     */
    @Test
    public void testInsert() throws Exception {
        SqlSession session = null;
        try{
            session = MyBatisUtils.openSession();
            Goods goods = new Goods();
            goods.setTitle("測驗商品");
            goods.setSubTitle("測驗子標題");
            goods.setOriginalCost(200f);
            goods.setCurrentPrice(100f);
            goods.setDiscount(0.5f);
            goods.setIsFreeDelivery(1);
            goods.setCategoryId(43);
            //insert()方法回傳值代表本次成功插入的記錄總數
            int num = session.insert("goods.insert", goods);
            session.commit();//提交事務資料
            System.out.println(goods.getGoodsId());
        }catch (Exception e){
            if(session != null){
                session.rollback();//回滾事務
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(session);
        }
    }

SQL洗掉

洗掉同理

<delete id="batchDelete" parameterType="java.util.List">
    DELETE FROM t_goods WHERE goods_id in
    <foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
        #{item}
    </foreach>
</delete>
/**
 * 洗掉資料
 */
@Test
public void testDelete() throws Exception {
    SqlSession session = null;
    try{
        session = MyBatisUtils.openSession();
        int num = session.delete("goods.delete" , 739);
        session.commit();//提交事務資料
    }catch (Exception e){
        if(session != null){
            session.rollback();//回滾事務
        }
        throw e;
    }finally {
        MyBatisUtils.closeSession(session);
    }
}

動態SQL

在我們逛淘寶的時候,是否有發現在搜索商品時有很多標簽可以選擇,比如說指定某個品牌,某種型別等等,其實從開發者的角度上來看,是不是還是一個SQL陳述句罷了,只不過多加了幾個引數,但是問題就在于,這些引數如何動態的加載進去,在想要的時候才用他呢?

這里引出mybatis的動態SQL陳述句技術,不過是加個標簽罷了,底層依舊是之前那套,dom4j+動態代理+反射完成的,

<select id="dynamicSQL" parameterType="java.util.Map" resultType="com.imooc.mybatis.entity.Goods">
    select * from t_goods
    <where>                                 //SQL種的where改成使用where標簽
      <if test="categoryId != null">          //如果map里有這個引數,就加上下面這句
          and category_id = #{categoryId}
      </if>
      <if test="currentPrice != null">
          and current_price &lt; #{currentPrice}
      </if>
    </where>
</select>
/**
 * 動態SQL陳述句
 */
@Test
public void testDynamicSQL() throws Exception {
    SqlSession session = null;
    try{
        session = MyBatisUtils.openSession();
        Map param = new HashMap();
        param.put("categoryId", 44);
        param.put("currentPrice", 500);
        //查詢條件
        List<Goods> list = session.selectList("goods.dynamicSQL", param);
        for(Goods g:list){
            System.out.println(g.getTitle() + ":" +
                    g.getCategoryId()  + ":" + g.getCurrentPrice());
?
        }
    }catch (Exception e){
        throw e;
    }finally {
        MyBatisUtils.closeSession(session);
    }
}

3.Mybatis二級快取機制

為了提高查詢效率,減少資料庫的訪問次數,Mybatis采用了兩層快取機制,并分為一級快取和二級快取

因為一級快取的命中率可能較低,所以還有一層二級快取

  • 一級快取默認開啟,快取范圍SqlSession

    • (換句話說就是,只在SqlSession session = MyBatisUtils.openSession()的這個session里有效,當我們寫了兩遍這個代碼,就是兩個不同的SqlSession物件)

    • 拿上面的代碼舉例,就是你使用這個session不管查詢多少次相同的陳述句,都是從快取里拿出來的一個結果

    session.selectList("goods.dynamicSQL", param);
    session.selectList("goods.dynamicSQL", param);
    session.selectList("goods.dynamicSQL", param);
    //最后都是相同的結果,記憶體地址都是一樣的
  • 二級快取手動開啟,屬于范圍Mapper Namespace

    • (換句話說,就是只要是使用了之前我們定義mapper的namespace中的SQL陳述句里都有效)

    <mapper namespace="goods">
    ....各種SQL....
    </mapper>

image-20230524152746106

注意:

當呼叫SqlSession的修改、添加、洗掉、commit()、close()等方法時,為了保證資料的一致性,mybatis會強制清空一級快取,

如何理解這句話?用代碼舉例一下

session = MyBatisUtils.openSession();
Goods goods = session.selectOne("goods.selectById" , 1603);
session.commit();       //commit提交時對該namespace快取強制清空
Goods goods2 = session.selectOne("goods.selectById" , 1603);

這個時候,因為提交過一次事務,所以第二次的查詢goods2時的hashcode與第一次的goods其實是不一樣的,本質上是2次查詢,而不是直接拿出goods已經查詢出來的內容賦給goods2

開啟二級快取

在xml中的mapper配置一句話即可

<mapper namespace="goods">
    <!--
        eviction是快取的清除策略,當快取物件數量達到上限后,自動觸發對應演算法對快取物件清除
            1.LRU – 最近最久未使用:移除最長時間不被使用的物件,
            O1 O2 O3 O4 .. O512     最多只有512個物件
            14 99 83 1     893(秒) 記錄物件上一次被訪問的時間,如果512個滿了,就會先把時間最長的893秒的那個物件移除
            2.FIFO – 先進先出:按物件進入快取的順序來移除它們,
            3.SOFT – 軟參考:移除基于垃圾收集器狀態和軟參考規則的物件,
            4.WEAK – 弱參考:更積極的移除基于垃圾收集器狀態和弱參考規則的物件,
?
        flushInterval屬性表示重繪快取的時間間隔ms
        size屬性表示快取的大小
        readOnly屬性表示快取是否只讀,可選值為true或false,true是回傳物件本身(效率高),false則是回傳物件的副本(安全好)
  -->
    <cache eviction="LRU" flushInterval="600000" size="512" readOnly="true"/>
    
    ....各種SQL....
    
    </mapper>

快取大量資料性能問題

既然我們開啟了快取,那么就要考慮一下如果快取了大量資料影響性能怎么辦,其實對于查詢大量資料的陳述句可以不使用快取,而且在實際程序中,這種大量的查詢也不會經常復用,

<!-- useCache="false"代表該陳述句不保存至快取 --> 
<select id="selectAll" resultType="com.imooc.mybatis.entity.Goods" useCache="false">
    select * from t_goods order by goods_id desc limit 10
</select>
<!-- flushCache="true"執行完這句話馬上重繪快取 = 一個commit操作 --> 
<!-- 并且這句話查詢出來的資料本身也不會放入快取 --> 
<select id="selectGoodsMap" resultType="java.util.LinkedHashMap" flushCache="true">
    select g.* , c.category_name,'1' as test from t_goods g , t_category c
    where g.category_id = c.category_id
</select>

4.物件關聯查詢(一對多、多對一)

我們知道,一個表內有很多個物體,可能有一個物體對應了很多個物件,有一些則是一對一,多對一,多對多等等,

image-20230524174033263

所以引出我們的關聯查詢

一對多查詢:

先來舉個例子:比如說我們要查詢一個商品,但是一個商品Goods又對應了很多個商品細節GoodsDetail(一對多)

所以我們的商品細節表GoodsDetail要持有我們的商品表Goods的主鍵 goodsId,那么除掉建表的程序,先寫一下對應的物體類吧

public class Goods {
    private Integer goodsId;//商品編號
    private String title;//標題
    private String subTitle;//子標題
    private Float originalCost;//原始價格
    private Float currentPrice;//當前價格
    private Float discount;//折扣率
    private Integer isFreeDelivery;//是否包郵 ,1-包郵 0-不包郵
    private Integer categoryId;//分類編號
    private List<GoodsDetail> goodsDetails;
}
//省略getter,setter,構造器等等
public class GoodsDetail {
    private Integer gdId;
    private Integer goodsId;
    private String gdPicUrl;
    private Integer gdOrder;
    private Goods goods;
}
//省略getter,setter,構造器等等

那么我們要如何實作一對多的查詢呢,我們來看看本質是什么,不過就是去Goods里面找GoodsDetail,再去GoodsDetail里面找具體的屬性罷了,

所以,還是使用我們的resultMap進行映射就好了,只要將goodsDetails的屬性映射到Goods里面,不就相當于Goods擁有了goodsDetails的屬性了嘛,可以理解為類似下面這個類,

public class GoodsAfterMapping {
    private Integer goodsId;//商品編號
    private String title;//標題
    private String subTitle;//子標題
    private Float originalCost;//原始價格
    private Float currentPrice;//當前價格
    private Float discount;//折扣率
    private Integer isFreeDelivery;//是否包郵 ,1-包郵 0-不包郵
    private Integer categoryId;//分類編號
        private Integer gdId;
        private Integer goodsId;
        private String gdPicUrl;
        private Integer gdOrder;
        private Goods goods;
}
//省略getter,setter,構造器等等

ok,有了思路,來具體實作一下吧,寫好查詢陳述句

<mapper namespace="goodsDetail">
<select id="selectOneToMany" resultMap="RmGoods1">
    select * from t_goods limit 0,10
</select>
</mapper>

想一想我們的思路,是不是要利用這句select陳述句查詢出來的ID,去我們的我們商品細節表GoodsDetail里把其他屬性也查出來,所以我們再寫一個select陳述句用于查詢商品細節表GoodsDetail

<mapper namespace="goodsDetail">
<select id="selectByGoodsId" parameterType="Integer"
        resultType="com.imooc.mybatis.entity.GoodsDetail">
    select * from t_goods_detail where goods_id = #{value}
</select>
</mapper>

然后開始配置我們的 resultMap 取名為 RmGoods1

<mapper namespace="goodsDetail">
<!--
    resultMap可用于說明一對多或者多對一的映射邏輯
    id 是resultMap屬性參考的標志
    type 指向我們所謂的一對多的一的物體(也就是Goods)
-->
<resultMap id="RmGoods1" type="com.imooc.mybatis.entity.Goods">
    <!-- 還是先確定主鍵id,把資料庫欄位和物體類同步一下 -->
    <id column="goods_id" property="goodsId"></id>
     <!--這里不需要像多表查詢那里大量配置result,因為資料庫欄位和POJO欄位符合駝峰命名規則,框架會自動轉換-->
    
    <!--collection的含義是,在select * from t_goods limit 0,1 得到結果后,
        將得到的goods_id值,
        代入到goodsDetail命名空間的selectByGoodsId的SQL中執行查詢,
        最后框架會自動將查詢得到的"商品細節"的結果(一個集合)
        賦值給 private List<GoodsDetail> goodsDetails 這個物件  -->
    <collection property="goodsDetails" select="goodsDetail.selectByGoodsId" column="goods_id"/>
</resultMap>
</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">
<mapper namespace="goodsDetail">
     查詢Goods表
    <select id="selectOneToMany" resultMap="rmGoods1">
        select * from t_goods limit 0,10
    </select>
    利用上句查詢出來的ID去GoodsDetail查詢
    <select id="selectByGoodsId" parameterType="Integer"
            resultType="com.imooc.mybatis.entity.GoodsDetail">
        select * from t_goods_detail where goods_id = #{value}
    </select>
    配置resultMap
  <resultMap id="RmGoods1" type="com.imooc.mybatis.entity.Goods">
    <id column="goods_id" property="goodsId"></id>
    <collection property="goodsDetails" select="goodsDetail.selectByGoodsId" column="goods_id"/>
  </resultMap>
</mapper>

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

標籤:其他

上一篇:springboot~統一處理日期請求引數java.utils.Date和java.time.LocalDate

下一篇:返回列表

標籤雲
其他(159675) Python(38169) JavaScript(25450) Java(18129) C(15231) 區塊鏈(8268) C#(7972) AI(7469) 爪哇(7425) MySQL(7211) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5873) 数组(5741) R(5409) Linux(5341) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4576) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2434) ASP.NET(2403) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) .NET技术(1976) 功能(1967) Web開發(1951) HtmlCss(1944) C++(1922) python-3.x(1918) 弹簧靴(1913) xml(1889) PostgreSQL(1878) .NETCore(1861) 谷歌表格(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
最新发布
  • MyBatis體系筆記(未完結)

    MyBatis 什么是MyBatis MyBatis是優秀的持久層框架 MyBatis使用XML將SQL與程式解耦,便于維護 MyBatis學習簡單,執行高效,是JDBC的延伸 1.MyBatis開發流程 引入MyBatis依賴 創建核心組態檔 創建物體(Entity)類 創建Mapper映射檔案 ......

    uj5u.com 2023-05-25 11:58:15 more
  • springboot~統一處理日期請求引數java.utils.Date和java.time.Lo

    日期型別的引數在從前端通過url引數傳遞到后端時,它會被進行格式化,如果格式化失敗會出現400的錯誤,像日期格式默認會使用yyyy/MM/dd的格式,如果希望自己去個性化配置,我們可以通過實作WebMvcConfigurer介面的addFormatters方法來完成。 # java.time.Loc ......

    uj5u.com 2023-05-25 11:38:09 more
  • JavaWeb編程面試題——導航

    面試題==知識點,這里所記錄的面試題并不針對于面試者,而是將這些面試題作為技能知識點來看待。不以刷題進大廠為目的,而是以學習為目的。這里的知識點會持續更新,目錄也會隨時進行調整。 ......

    uj5u.com 2023-05-25 11:37:48 more
  • spring-transaction原始碼分析(5)TransactionInterceptor事務攔

    spring-tx的事務攔截邏輯在TransactionInterceptor類,本文將詳細分析其實作方式。 # 事務攔截器TransactionInterceptor spring-tx的事務攔截邏輯在TransactionInterceptor類,它實作了MethodInterceptor介面。 ......

    uj5u.com 2023-05-25 11:37:32 more
  • JavaWeb編程面試題——Spring Framework

    面試題==知識點,這里所記錄的面試題并不針對于面試者,而是將這些面試題作為技能知識點來看待。不以刷題進大廠為目的,而是以學習為目的。這里的知識點會持續更新,目錄也會隨時進行調整。 ......

    uj5u.com 2023-05-25 11:37:13 more
  • Netty實戰(三)

    [toc](目錄) # 一、Channel、EventLoop 和 ChannelFuture 上一篇博文我們在構建服務端和客戶端中出現了一些新的類,可能有些同學還有些不了解它們的具體功能。沒關系,接下來我們對于 Channel、EventLoop 和 ChannelFuture 類進行的討論增添更 ......

    uj5u.com 2023-05-25 11:35:12 more
  • MyBatis體系筆記(未完結)

    MyBatis 什么是MyBatis MyBatis是優秀的持久層框架 MyBatis使用XML將SQL與程式解耦,便于維護 MyBatis學習簡單,執行高效,是JDBC的延伸 1.MyBatis開發流程 引入MyBatis依賴 創建核心組態檔 創建物體(Entity)類 創建Mapper映射檔案 ......

    uj5u.com 2023-05-25 11:22:01 more
  • springboot~統一處理日期請求引數java.utils.Date和java.time.Lo

    日期型別的引數在從前端通過url引數傳遞到后端時,它會被進行格式化,如果格式化失敗會出現400的錯誤,像日期格式默認會使用yyyy/MM/dd的格式,如果希望自己去個性化配置,我們可以通過實作WebMvcConfigurer介面的addFormatters方法來完成。 # java.time.Loc ......

    uj5u.com 2023-05-25 11:16:06 more
  • JavaWeb編程面試題——導航

    面試題==知識點,這里所記錄的面試題并不針對于面試者,而是將這些面試題作為技能知識點來看待。不以刷題進大廠為目的,而是以學習為目的。這里的知識點會持續更新,目錄也會隨時進行調整。 ......

    uj5u.com 2023-05-25 11:15:46 more
  • spring-transaction原始碼分析(5)TransactionInterceptor事務攔

    spring-tx的事務攔截邏輯在TransactionInterceptor類,本文將詳細分析其實作方式。 # 事務攔截器TransactionInterceptor spring-tx的事務攔截邏輯在TransactionInterceptor類,它實作了MethodInterceptor介面。 ......

    uj5u.com 2023-05-25 11:15:41 more