Spring Boot 中使用 tkMapper

来源:https://www.cnblogs.com/luisblog/archive/2022/11/10/16875672.html
-Advertisement-
Play Games

說明:基於 MyBatis 有很多第三方功能插件,這些插件可以完成數據操作方法的封裝、資料庫逆向工程的生成等。 tkMapper 和 MyBatis-plus 都是基於 MyBatis 提供的第三方插件,功能類似,下麵介紹 tkMapper 的使用。 簡介 tkMapper 就是一個 MyBatis ...


說明:基於 MyBatis 有很多第三方功能插件,這些插件可以完成數據操作方法的封裝、資料庫逆向工程的生成等。

tkMapperMyBatis-plus 都是基於 MyBatis 提供的第三方插件,功能類似,下麵介紹 tkMapper 的使用。

簡介

tkMapper 就是一個 MyBatis 插件,基於 MyBatis 提供很多工具,提高開發效率,主要有以下兩個功能。

  • 提供針對單表通用的資料庫操作方法
  • 逆向工程(根據數據表自動生成實體類、Dao 介面、Mapper 映射文件)

MyBatis 基礎環境

tkMapper 的使用需要基於 MyBatis。

  1. 創建 Spring Boot 項目,選中 Lombok、Spring Web、MyBatis Framework、MySQL Driver 依賴

  2. application.yml 配置文件中配置相關信息

    spring:
      datasource:
        driver-class-name: com.mysql.jdbc.Driver
        url: jdbc:mysql://localhost:3306/springdb?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=UTF-8
        username: root
        password: luis
    
    mybatis:
      type-aliases-package: com.luis.beans
      mapper-locations: classpath:mappers/*Mapper.xml
    

    註意:配置後,手動創建 beans 和 mappers 文件夾

  3. 創建 dao 文件夾,在啟動類上添加 dao 的包掃描器 @MapperScan(basePackages = {"com.luis.dao"})

tkMapper 環境搭建

  1. 添加依賴

    <!-- tkMapper -->
    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper-spring-boot-starter</artifactId>
        <version>2.1.5</version>
    </dependency>
    

    如果自己在 maven 倉庫中搜索,註意搜索關鍵詞:mapper starter

    image-20221109104950352

    PS:添加後,註意手動刷新 pom

  2. 更換啟動類上 dao 包的包掃描器來源,不使用原先的 @MapperScan,要使用新添加的 tkMapper 的 @MapperScan

    import tk.mybatis.spring.annotation.MapperScan;
    
    @SpringBootApplication
    @MapperScan(basePackages = {"com.luis.dao"}) //使用tkMapper的包掃描器註解
    public class SpringbootTkMapperDemoApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootTkMapperDemoApplication.class, args);
        }
    
    }
    

    PS:註意註解的包來源 import tk.mybatis.spring.annotation.MapperScan

  3. 以上,tkMapper 環境已經搭建完成

tkMapper 對數據的通用操作

tkMapper 提供針對單表通用的資料庫操作方法。

數據準備

1. 創建資料庫表
DROP TABLE IF EXISTS `users`;
CREATE TABLE `users`  (
  `user_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `user_pwd` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `user_realname` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  `user_img` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  PRIMARY KEY (`user_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;
2. 創建實體類
@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "users") //資料庫表名和實體類類名不一致需要指定映射關係!
public class User {

    @Id //指定主鍵
    private Integer userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private String userImg;

}
3. 創建 Dao 介面【重點】

註意:創建的 Dao 介面需要繼承 tkMapper 中提供的 MapperMySqlMapper 兩個介面,這兩個介面提供了對單表的通用操作。

public interface UserDao extends Mapper<User>, MySqlMapper<User> {
}

可選優化策略【建議使用】:

如果不想每次創建 dao 介面時都繼承 tkMapper 中的兩個介面,可以自己寫一個通用的介面模板,只需要讓這個通用的介面模板繼承 tkMapper 中的兩個介面,然後自己創建的 dao 介面只需要繼承這個通用的介面模板即可!

但是,需要註意的是,這個通用的介面模板千萬不能寫在 dao 目錄下!因為 dao 目錄下的介面會被掃描到,有固定的功能用處;而我們自定義的通用介面模板只是為了繼承,沒有其他特殊功能!

使用示例:

1、可在 dao 目錄同級創建 general 目錄,在 general 目錄下創建 GeneralDao 介面,並繼承 tkMapper 中的兩個介面。

package com.luis.general;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * @Author: Luis
 * @date: 2022/11/9 14:39
 * @description: 自定義的通用介面模板
 */
public interface GeneralDao<T> extends Mapper<T>, MySqlMapper<T> {
}

2、創建 dao 介面,繼承 GeneralDao 即可!

public interface UserDao extends GeneralDao<User> {
}
4. 測試

添加 Junit 和 springboot test 兩個測試依賴:

<!-- junit -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <scope>test</scope>
</dependency>
<!-- springboot test -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>

寫測試類進行測試:

@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //啟動類.class
public class UserDaoTest {

    @Autowired
    private UserDao userDao; //如果爆紅線不用管(或Dao介面上添加@Repository註解)

    @Test
    public void test() {

        User user = new User();
        user.setUserName("mike");
        user.setUserPwd("123");
        user.setUserRealname("zhangsan");
        user.setUserImg("user/default.jpg");

        int i = userDao.insert(user);
        System.out.println("========> i = " + i);
    }
}

tkMapper 常用方法之增刪改

  • insert:普通添加
  • insertUseGeneratedKeys:可返回自增 id 的添加
  • updateByPrimaryKey:根據主鍵修改
  • deleteByPrimaryKey:根據主鍵刪除
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //啟動類.class
public class UserDaoTest {

    @Autowired
    private UserDao userDao; //如果爆紅線不用管(或Dao介面上添加@Repository註解)

    @Test
    public void testInsert() {

        User user = new User();
        user.setUserName("juno4");
        user.setUserPwd("321");
        user.setUserRealname("lin");
        user.setUserImg("user/default.jpg");

        /**
         * insert: 添加(自增的id不會返回)
         */
        int i = userDao.insert(user);
        System.out.println("========> i = " + i);
        System.out.println(user.getUserId()); //null
    }

    @Test
    public void testInsertUseGeneratedKeys() {

        User user = new User();
        user.setUserName("juno3");
        user.setUserPwd("321");
        user.setUserRealname("lin");
        user.setUserImg("user/default.jpg");

        /**
         * insertUseGeneratedKeys: 添加(自增的id可以返回)
         * 註意:
         *  1. 資料庫中主鍵欄位需要設置為自增
         *  2. 實體類中主鍵屬性需要使用@Id註解指定;並且需要使用包裝類型Integer,不要使用int
         */
        int i = userDao.insertUseGeneratedKeys(user);
        System.out.println("========> i = " + i);
        System.out.println(user.getUserId()); //10
    }

    @Test
    public void testUpdateByPrimaryKey() {

        User user = new User();
        user.setUserId(10); //必須指定要修改的id
        user.setUserName("juno new");
        user.setUserPwd("000");
        user.setUserRealname("lin new");
        user.setUserImg("new.jpg");

        /**
         * updateByPrimaryKey:根據主鍵修改
         */
        int i = userDao.updateByPrimaryKey(user);
        System.out.println("========> i = " + i);
        System.out.println(user);
    }

    @Test
    public void testDeleteByPrimaryKey() {
        /**
         * deleteByPrimaryKey:根據主鍵刪除
         */
        int i = userDao.deleteByPrimaryKey(9);
        System.out.println("========> i = " + i);
    }
}

PS:其實還有根據自定義條件修改或刪除的方法(使用方法參考帶條件的查詢示例)

tkMapper 常用方法之查詢

  • selectAll:查所有
  • selectByPrimaryKey:根據主鍵查所有
  • selectByExample:根據條件查所有
  • selectByRowBounds:分頁查詢
  • selectByExampleAndRowBounds:帶條件的分頁查詢
  • selectCount:查總記錄數
  • selectCountByExample:根據條件查總記錄數
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //啟動類.class
public class UserDaoTest {

    @Autowired
    private UserDao userDao; //如果爆紅線不用管(或Dao介面上添加@Repository註解)

    @Test
    public void testSelectAll() {
        /**
         * selectAll:查詢所有
         */
        List<User> users = userDao.selectAll();
        for (User user : users) {
            System.out.println(user);
        }
    }

    @Test
    public void testSelectByPrimaryKey() {
        /**
         * selectByPrimaryKey:根據主鍵查詢
         */
        User user = userDao.selectByPrimaryKey(10);
        System.out.println(user);
    }

    @Test
    public void testSelectByExample() {

        //封裝查詢條件
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        //條件信息(根據Criteria對象的各種方法進行設置)
        criteria.andEqualTo("userRealname", "lin");
        // criteria.orEqualTo("userPwd", "123");
        // criteria.andLike("userName", "%i%");

        /**
         * selectByPrimaryKey:根據條件查詢(PS:根據條件修改或刪除與此類似)
         *      註意:需要設置查詢條件信息,並傳入條件對象
         */
        List<User> users = userDao.selectByExample(example);
        for (User user : users) {
            System.out.println("========> " + user);
        }
    }

    @Test
    public void testSelectByRowBounds() {

        //分頁查詢信息
        int pageNum = 2; //第幾頁
        int pageSize = 3; //每頁顯示多少行
        int start = (pageNum - 1) * pageSize; //起始顯示的下標
        RowBounds rowBounds = new RowBounds(start, pageSize);

        /**
         * selectByRowBounds:查所有的分頁查詢
         */
        List<User> users = userDao.selectByRowBounds(new User(), rowBounds);
        for (User user : users) {
            System.out.println("========> " + user);
        }

        /**
         * selectCount:查詢總記錄數
         */
        int count = userDao.selectCount(new User());
        System.out.println("========> count = " + count);
    }

    @Test
    public void testSelectByExampleAndRowBounds() {

        //封裝查詢條件
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userRealname", "lin");

        //分頁查詢信息
        int pageNum = 2; //第幾頁
        int pageSize = 2; //每頁顯示多少行
        int start = (pageNum - 1) * pageSize; //起始顯示的下標
        RowBounds rowBounds = new RowBounds(start, pageSize);

        /**
         * selectByExampleAndRowBounds:帶條件的分頁查詢
         */
        List<User> users = userDao.selectByExampleAndRowBounds(example, rowBounds);
        for (User user : users) {
            System.out.println("========> " + user);
        }

        /**
         * selectCountByExample:根據條件查詢總記錄數
         */
        int count = userDao.selectCountByExample(example);
        System.out.println("========> count = " + count);
    }
}

tkMapper 關聯/多表查詢

說明:所有的關聯/多表查詢都可以由多個單表查詢組成

關聯/多表查詢實現方式:

方式一:多次使用單表查詢,然後封裝數據

方式二:自定義查詢方法和 SQL

情景:基於以上的用戶表,新添加一個訂單表 orders,訂單表中有訂單信息,但是也有用戶 id;

要求:在查詢用戶表的同時還要查詢出用戶的訂單信息,這就涉及到了兩張表的查詢。

具體業務要求:根據用戶名查詢用戶的所有信息,包括訂單信息。

數據準備

新建訂單表 orders:

DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders`  (
  `order_id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) NOT NULL,
  `receiver_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `receiver_mobile` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  `receiver_address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`order_id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Compact;

INSERT INTO `orders` VALUES (1, 1, 'luis', '13344445555', '湖北武漢');

新建實體類 Order:

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "orders")
public class Order {

    @Id
    private Integer orderId;
    private Integer userId;
    private String receiverName;
    private String receiverMobile;
    private String receiverAddress;

}

新建 dao 介面:

註意,此處 dao 介面繼承的是自定義的通用介面模板,相關說明參見之前創建示例 UserDao 的步驟。

也可以直接繼承 tkMapper 的兩個介面。(註意靈活運用!)

public interface OrderDao extends GeneralDao<Order> {
}

說明:進行關聯/多表查詢前,需要修改下之前的 User 實體類,在實體類中需要添加一個訂單的欄位,以便查詢出用戶所關聯的訂單信息。

@Data
@NoArgsConstructor
@AllArgsConstructor
@Table(name = "users") //資料庫表名和實體類類名不一致需要指定映射關係!
public class User {

    @Id //指定主鍵
    private Integer userId;
    private String userName;
    private String userPwd;
    private String userRealname;
    private String userImg;
    
    //訂單
    private List<Order> orderList;

}
方式一:多次單表查詢
@RunWith(SpringRunner.class)
@SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //啟動類.class
public class UserDaoTest {

    @Autowired
    private UserDao userDao; //如果爆紅線不用管(或Dao介面上添加@Repository註解)
    @Autowired
    private OrderDao orderDao;

    @Test
    public void test() {

        //根據用戶名查詢用戶信息
        Example example = new Example(User.class);
        Example.Criteria criteria = example.createCriteria();
        criteria.andEqualTo("userName", "luis");
        //條件查詢
        List<User> users = userDao.selectByExample(example);
        User user = users.get(0);

        //根據用戶id查詢訂單信息
        Example example1 = new Example(Order.class);
        Example.Criteria criteria1 = example.createCriteria();
        criteria.andEqualTo("userId", user.getUserId());
        //條件查詢
        List<Order> orders = orderDao.selectByExample(example1);

        //將查詢到的訂單信息設置到user中
        user.setOrderList(orders);

        System.out.println("========> " + user);
    }
}    
方式二:自定義連接查詢
  1. UserDao 介面中新建查詢方法

    public interface UserDao extends GeneralDao<User> {
    
        public User selectByUserName(String userName);
    }
    
  2. mappers 目錄下創建對應的 UserMapper.xml 文件,自定義查詢 SQL

    <?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="com.luis.dao.UserDao">
        
        <resultMap id="userMap" type="com.luis.beans.User">
            <id column="user_id" property="userId"/>
            <result column="user_name" property="userName"/>
            <result column="user_pwd" property="userPwd"/>
            <result column="user_realname" property="userRealname"/>
            <result column="user_img" property="userImg"/>
            <collection property="orderList" ofType="com.luis.beans.Order">
                <id column="order_id" property="orderId"/>
                <result column="user_id" property="userId"/>
                <result column="receiver_name" property="receiverName"/>
                <result column="receiver_mobile" property="receiverMobile"/>
                <result column="receiver_address" property="receiverAddress"/>
            </collection>
        </resultMap>
    
        <select id="selectByUserName" resultMap="userMap">
            select u.user_id,u.user_name,u.user_pwd,u.user_realname,u.user_img,
                   o.order_id,o.user_id,o.receiver_name,o.receiver_mobile,o.receiver_address
            from users u inner join orders o
            on u.user_id = o.user_id;
      </select>
    </mapper>
    
  3. 測試

    @RunWith(SpringRunner.class)
    @SpringBootTest(classes = SpringbootTkMapperDemoApplication.class) //啟動類.class
    public class UserDaoTest {
    
        @Autowired
        private UserDao userDao; //如果爆紅線不用管(或Dao介面上添加@Repository註解)
        @Autowired
        private OrderDao orderDao;
    
        @Test
        public void test02() {
    
            //使用自定義的查詢方法
            User user = userDao.selectByUserName("luis");
            System.out.println("========> " + user);
        }
    }    
    

逆向工程

所謂逆向工程,就是通過資料庫表,來自動生成實體類、dao 介面和 mapper 文件。

需要註意的是,本逆向工程是最好配合 tkMapper 環境使用,因為,有一些配置和 tkMapper 相關,如生成的 dao 介面會繼承自定義的通用介面模板,而該通用的介面模板就是繼承了 tkMapper 中的兩個介面,從而才能使用 tkMapper 提供的通用數據操作方法;還有,生成的實體類上的註解需要依賴 tkMapper 環境。

重要說明:本逆向工程使用的 mysql 版本是低版本 5.1.36!經測試,如果使用高版本如 8.xxx,很大概率會生成有問題!所以建議項目中統一使用低版本的 MySQL。

  1. 在 pom.xml 中 build 的 plugins 下添加下列生成器插件

    <!-- mybatis-generator-maven-plugin -->
    <plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.6</version>
        <!-- 生成器配置文件位置;如果還沒有添加,可以先註釋,添加後再放開 -->
        <configuration>
            <configurationFile>
                ${basedir}/src/main/resources/generator/GeneratorConfig.xml
            </configurationFile>
        </configuration>
        <!-- 插件所需的兩個依賴 -->
        <dependencies>
            <!-- mysql -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.36</version>
            </dependency>
            <!-- mapper -->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper</artifactId>
                <version>4.1.5</version>
            </dependency>
        </dependencies>
    </plugin>
    

    註意:推薦直接複製,但如果想自己在 maven 倉庫中搜索,註意關鍵詞:mybatis-generator-maven-plugin,並且,千萬註意,你搜索到的肯定是依賴,而並非插件!此時,你只需要複製依賴的 gav 坐標,自己在 pom 中創建空 plugin 標簽,將 gav 坐標複製進去即可!(如果相關依賴刷新添加失敗,可以複製到 dependences 下,重新刷新添加試試,添加成功後複製回來即可)

  2. 註意查看項目中是否自定義有通用介面模板 GeneralDao,使其繼承 tkMapper 的兩個介面;如果沒有,則在 dao 同級目錄,創建 general 目錄,在 general 目錄下創建自定義通用介面模板 GeneralDao,繼承 tkMapper 的兩個介面;

    public interface GeneralDao<T> extends Mapper<T>, MySqlMapper<T> {
    }
    
  3. resources/generator 下添加 GeneratorConfig.xml 生成器配置(創建並複製後改主要配置即可)

    主要需要配置:配置資料庫連接、配置實體類存放路徑、配置 XML 存放路徑、配置 DAO 存放路徑、配置 GeneralDao

    註意:預設配置是生成指定資料庫中所有表,也可以自定義的指定只生成哪些表

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE generatorConfiguration
            PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
            "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
    <generatorConfiguration>
        <!-- 引入資料庫連接配置 -->
    <!--    <properties resource="jdbc.properties"/>-->
    
        <context id="Mysql" targetRuntime="MyBatis3Simple" defaultModelType="flat">
            <property name="beginningDelimiter" value="`"/>
            <property name="endingDelimiter" value="`"/>
    
            <!-- 配置 GeneralDao -->
            <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
                <property name="mappers" value="com.luis.general.GeneralDao"/>
            </plugin>
    
            <!-- 配置資料庫連接(註意資料庫版本問題,需要使用低版本的,高版本可能出現問題!) -->
            <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                    connectionURL="jdbc:mysql://localhost:3306/springdb?serverTimezone=UTC"
                    userId="root" password="luis">
            </jdbcConnection>
    
            <!-- 配置實體類存放路徑 -->
            <javaModelGenerator targetPackage="com.luis.beans" targetProject="src/main/java"/>
    
            <!-- 配置 XML 存放路徑 -->
            <sqlMapGenerator targetPackage="/" targetProject="src/main/resources/mappers"/>
    
            <!-- 配置 Dao 存放路徑 -->
            <javaClientGenerator targetPackage="com.luis.dao" targetProject="src/main/java" type="XMLMAPPER"/>
    
            <!-- 配置需要指定生成的資料庫和表,% 代表所有表 -->
            <table tableName="%">
                <!-- mysql 配置 -->
    <!--            <generatedKey column="id" sqlStatement="Mysql" identity="true"/>-->
            </table>
    <!--        <table tableName="tb_roles">-->
    <!--            &lt;!&ndash; mysql 配置 &ndash;&gt;-->
    <!--            <generatedKey column="roleid" sqlStatement="Mysql" identity="true"/>-->
    <!--        </table>-->
    <!--        <table tableName="tb_permissions">-->
    <!--            &lt;!&ndash; mysql 配置 &ndash;&gt;-->
    <!--            <generatedKey column="perid" sqlStatement="Mysql" identity="true"/>-->
    <!--        </table>-->
        </context>
    </generatorConfiguration>
    
  4. 打開 IDEA 右側 Maven 視窗,找到項目--》Plugins--》mybatis-generator--》mybatis-generator:generate,雙擊執行逆向生成即可!

    示例圖:

    image-20221109212212306

  5. 查看 beans、dao、mappers 目錄下的生成情況,看生成的相關介面是否符合開發要求,根據情況可做相關修改,然後進行相關測試。

都看到最後了,右下角來個贊鴨!-.- 歡迎評論留言~


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 1.uni.getLocation 獲取當前經維度 先上代碼 let that = this // 獲取用戶是否開啟 授權獲取當前的地理位置、速度的許可權。 uni.getSetting({ success (res) { console. ...
  • android studio 升級 Android Studio Dolphin | 2021.3.1 Patch 1後,xml佈局預覽界面報錯 一開始以為是那些警告導致的,有很多黃色的xml警告,比如命名的名字不是英文,或者設置了各種顏色值警告,或者系統要求你添加 contentDescripti ...
  • 面向對象之設計模式 一、設計模式概述 ​ 設計模式(Design Pattern)是前輩們對代碼開發經驗的總結,是解決特定問題的一系列套路。它不是語法規定,而是一套用來提高代碼可復用性、可維護性、穩健性以及安全性的解決方案。 ​ 1995年,GoF(Gang of Four,四人組/四人幫)合作出版 ...
  • 中介模式屬於行為型設計模式,可以將原本難以理解的網狀結構轉換成了相對加單的星型結構,主要用來降低多個對象和類之間的通信複雜性。 ...
  • RAID技術出現的初衷是把多個小容量的硬碟組合起來,以獲得更大的存儲容量。當前我們所說的RAID技術更多則是與數據保護相關,換言之,當物理設備失效時,RAID能夠用來防止數據的丟失。 隨著陣列技術的發展,已經產生了很多不同類型的RAID,但現在只有少數幾種RAID仍在使用。在這個章節中,我們將討論最... ...
  • 面向對象之元類 一、什麼是元類 Python中一切皆為對象,對象是有類實例化生成; 類也是對象(類對象),生成類對象的類可稱之為元類; 所以,元類就是來創建類對象的,可稱之為類工廠; type是python內建元類,type是最上層的元類,也可稱為一切類對象的元類 二、元類推導流程 """推導步驟1 ...
  • 異常 一、異常:就是程式出現不正常的情況。 Throwable Error Exception RuntimeException 非RuntimeException Error:嚴重問題,不處理 Exception:異常類,程式本身可以處理 RuntimeException:編譯期間不檢查,程式出現 ...
  • 簡介: 迭代器模式,是行為型的設計模式。 提供一中方法順序訪問一個聚合對象中的各個元素,而又不需要暴露該對象的內部表示。 適用場景: 除了學習,在PHP中幾乎沒有應用場景。 優點: 學習意義遠大於實際意義。 缺點: 實際開發中幾乎用不上,完全可以被更簡單的foreach,或者是所用框架內置的遍歷方案 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...