JAVAEE——宜立方商城13:訂單系統實現、訂單生成、Mycat資料庫分片

来源:https://www.cnblogs.com/xieyupeng/archive/2018/08/07/9440242.html
-Advertisement-
Play Games

1. 學習計劃 1、訂單系統實現 2、訂單生成 3、Mycat資料庫分片 2. 訂單系統 2.1. 功能分析 1、在購物車頁面點擊“去結算”按鈕,跳轉到訂單確認頁面 a) 必須要求用戶登錄 b) 使用攔截器實現。 c) 如果用戶未登錄跳轉到登錄頁面。 d) 如果用戶已經登錄,放行。展示確認頁面。 e ...


1. 學習計劃

1、訂單系統實現

2、訂單生成

3、Mycat資料庫分片

 

2. 訂單系統

2.1. 功能分析

1、在購物車頁面點擊“去結算”按鈕,跳轉到訂單確認頁面

a) 必須要求用戶登錄

b) 使用攔截器實現。

c) 如果用戶未登錄跳轉到登錄頁面。

d) 如果用戶已經登錄,放行。展示確認頁面。

e) 判斷cookie中是否有購物車數據

f) 如果有同步到服務端。

2、訂單確認頁面中選擇收貨地址,選擇支付方式,確認商品列表。

a) 根據用戶id查詢收貨地址列表

b) 展示支付方式列表。

c) 從購物車中取商品列表,從服務端取購物車列表。

3、訂單確認頁面點擊“提交”,生成訂單。

4、展示訂單生成完成,或者跳轉到支付頁面。

 

2.2. 工程搭建

E3-order

  |--E3-order-interfacejar

  |--E3-order-servicewar

E3-order-webwar

 

2.3. 展示訂單確認頁面

2.3.1. 功能分析

1、根據id查詢用戶的收貨地址列表(使用靜態數據)

2、從購物車中取商品列表,展示到頁面。調用購物車服務查詢。

 

2.3.2. Dao

直接從redis中取購車商品列表。

 

2.3.3. Service

收貨地址靜態數據,沒有server

調用購物車的service查詢購物車商品列表。

 

2.3.4. Controller

引用購物車服務

 

 

 

 

請求的url/order/order-cart

參數:沒有參數

返回值:邏輯視圖

 

Controller

@Controller
public class OrderCartController {

    @Autowired
    private CartService cartService;
    
    @RequestMapping("/order/order-cart")
    public String showOrderCart(HttpServletRequest request) {
        //取用戶信息
        TbUser user = (TbUser) request.getAttribute("user");
        //取購物車商品列表
        List<TbItem> cartList = cartService.getCartList(user.getId());
        //把商品列表傳遞給jsp
        request.setAttribute("cartList", cartList);
        //返回邏輯視圖
        return "order-cart";
    }
}

 


2.4. 登錄攔截器
 

2.4.1. 功能分析

1、cookie中取token

2、如果沒有取到,沒有登錄,跳轉到sso系統的登錄頁面。攔截

3、如果取到token。判斷登錄是否過期,需要調用sso系統的服務,根據token取用戶信息

4、如果沒有取到用戶信息,登錄已經過期,重新登錄。跳轉到登錄頁面。攔截

5、如果取到用戶信息,用戶已經是登錄狀態,把用戶信息保存到request中。放行

6、判斷cookie中是否有購物車信息,如果有合併購物車

 

2.4.2. 攔截器實現

 

/**
 * 用戶登錄判斷攔截器
 * <p>Title: LoginInterceptor</p>
 * <p>Description: </p>
 * <p>Company: www.itcast.cn</p> 
 * @version 1.0
 */
public class LoginInterceptor implements HandlerInterceptor {

    @Value("${COOKIE_TOKEN_KEY}")
    private String COOKIE_TOKEN_KEY;
    @Value("${COOKIE_CART_KEY}")
    private String COOKIE_CART_KEY;
    @Value("${SSO_URL}")
    private String SSO_URL;
    @Autowired
    private UserService userService;
    @Autowired
    private CartService cartService;
    
    @Override
    public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)
            throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3)
            throws Exception {
        // TODO Auto-generated method stub

    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        // 1、從cookie中取token
        String token = CookieUtils.getCookieValue(request, COOKIE_TOKEN_KEY);
        // 2、如果沒有取到,沒有登錄,跳轉到sso系統的登錄頁面。攔截
        if (StringUtils.isBlank(token)) {
            //跳轉到登錄頁面
            response.sendRedirect(SSO_URL + "/page/login?redirect=" + request.getRequestURL());
            return false;
        }
        // 3、如果取到token。判斷登錄是否過期,需要調用sso系統的服務,根據token取用戶信息
        E3Result e3Result = userService.getUserByToken(token);
        // 4、如果沒有取到用戶信息,登錄已經過期,重新登錄。跳轉到登錄頁面。攔截
        if (e3Result.getStatus() != 200) {
            response.sendRedirect(SSO_URL + "/page/login?redirect=" + request.getRequestURL());
            return false;
        }
        // 5、如果取到用戶信息,用戶已經是登錄狀態,把用戶信息保存到request中。放行
        TbUser user = (TbUser) e3Result.getData();
        request.setAttribute("user", user);
        // 6、判斷cookie中是否有購物車信息,如果有合併購物車
        String json = CookieUtils.getCookieValue(request, COOKIE_CART_KEY, true);
        if (StringUtils.isNotBlank(json)) {
            cartService.mergeCart(user.getId(), JsonUtils.jsonToList(json, TbItem.class));
            //刪除cookie中的購物車數據
            CookieUtils.setCookie(request, response, COOKIE_CART_KEY, "");
        }
        //放行
        return true;
    }

}

 


2.4.3. Springmvc
配置 

<!-- 攔截器配置 -->
    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**"/>
            <bean class="cn.e3mall.order.interceptor.LoginInterceptor"/>
        </mvc:interceptor>
    </mvc:interceptors>

  

2.4.4. 實現sso系統的回調

 

 

2.5. 提交訂單

2.5.1. 功能分析

1、在訂單確認頁面點擊“提交訂單”按鈕生成訂單。

2、請求的url/order/create

3、參數:提交的是表單的數據。保存的數據:訂單、訂單明細、配送地址。

a) tb_order中插入記錄。

  1. 訂單號需要手動生成。

要求訂單號不能重覆。

訂單號可讀性號。

可以使用redisincr命令生成訂單號。訂單號需要一個初始值。

  1. Payment:表單數據
  2. payment_type:表單數據
  3. user_id:用戶信息
  4. buyer_nick:用戶名
  5. 其他欄位null

b) tb_order_item訂單明細表插入數據。

  1. Id:使用incr生成
  2. order_id:生成的訂單號
  3. 其他的都是表單中的數據。

c) tb_order_shipping,訂單配送信息

  1. order_id:生成的訂單號
  2. 其他欄位都是表單中的數據。

d) 使用pojo接收表單的數據。

可以擴展TbOrder,在子類中添加兩個屬性一個是商品明細列表,一個是配送信息。

pojo放到e3-order-interface工程中。

public class OrderInfo extends TbOrder implements Serializable{
    private List<TbOrderItem> orderItems;
    private TbOrderShipping orderShipping;
    public List<TbOrderItem> getOrderItems() {
        return orderItems;
    }
    public void setOrderItems(List<TbOrderItem> orderItems) {
        this.orderItems = orderItems;
    }
    public TbOrderShipping getOrderShipping() {
        return orderShipping;
    }
    public void setOrderShipping(TbOrderShipping orderShipping) {
        this.orderShipping = orderShipping;
    }
    
}

 


業務邏輯: 

1、接收表單的數據

2、生成訂單id

3、向訂單表插入數據。

4、向訂單明細表插入數據

5、向訂單物流表插入數據。

6、返回e3Result

 

返回值:e3Result

 

2.5.2. Dao

可以使用逆向工程。

 

2.5.3. Service

參數:OrderInfo

返回值:e3Result

@Service
public class OrderServiceImpl implements OrderService {

    @Autowired
    private TbOrderMapper orderMapper;
    @Autowired
    private TbOrderItemMapper orderItemMapper;
    @Autowired
    private TbOrderShippingMapper orderShippingMapper;
    @Autowired
    private JedisClient jedisClient;
    
    @Value("${ORDER_GEN_KEY}")
    private String ORDER_GEN_KEY;
    @Value("${ORDER_ID_BEGIN}")
    private String ORDER_ID_BEGIN;
    @Value("${ORDER_ITEM_ID_GEN_KEY}")
    private String ORDER_ITEM_ID_GEN_KEY;
    
    @Override
    public e3Result createOrder(OrderInfo orderInfo) {
        // 1、接收表單的數據
        // 2、生成訂單id
        if (!jedisClient.exists(ORDER_GEN_KEY)) {
            //設置初始值
            jedisClient.set(ORDER_GEN_KEY, ORDER_ID_BEGIN);
        }
        String orderId = jedisClient.incr(ORDER_GEN_KEY).toString();
        orderInfo.setOrderId(orderId);
        orderInfo.setPostFee("0");
        //1、未付款,2、已付款,3、未發貨,4、已發貨,5、交易成功,6、交易關閉
        orderInfo.setStatus(1);
        Date date = new Date();
        orderInfo.setCreateTime(date);
        orderInfo.setUpdateTime(date);
        // 3、向訂單表插入數據。
        orderMapper.insert(orderInfo);
        // 4、向訂單明細表插入數據
        List<TbOrderItem> orderItems = orderInfo.getOrderItems();
        for (TbOrderItem tbOrderItem : orderItems) {
            //生成明細id
            Long orderItemId = jedisClient.incr(ORDER_ITEM_ID_GEN_KEY);
            tbOrderItem.setId(orderItemId.toString());
            tbOrderItem.setOrderId(orderId);
            //插入數據
            orderItemMapper.insert(tbOrderItem);
        }
        // 5、向訂單物流表插入數據。
        TbOrderShipping orderShipping = orderInfo.getOrderShipping();
        orderShipping.setOrderId(orderId);
        orderShipping.setCreated(date);
        orderShipping.setUpdated(date);
        orderShippingMapper.insert(orderShipping);
        // 6、返回e3Result。
        return e3Result.ok(orderId);
    }

}

 


  

2.5.4. Controller

請求的url/order/create

參數:使用OrderInfo接收

返回值:邏輯視圖。

業務邏輯:

1、接收表單提交的數據OrderInfo

2、補全用戶信息。

3、調用Service創建訂單。

4、返回邏輯視圖展示成功頁面

a) 需要Service返回訂單號

b) 當前日期加三天。

 

在攔截器中添加用戶處理邏輯:

 

@RequestMapping(value="/order/create", method=RequestMethod.POST)
    public String createOrder(OrderInfo orderInfo, HttpServletRequest request) {
        // 1、接收表單提交的數據OrderInfo。
        // 2、補全用戶信息。
        TbUser user = (TbUser) request.getAttribute("user");
        orderInfo.setUserId(user.getId());
        orderInfo.setBuyerNick(user.getUsername());
        // 3、調用Service創建訂單。
        e3Result result = orderService.createOrder(orderInfo);
        //取訂單號
        String orderId = result.getData().toString();
        // a)需要Service返回訂單號
        request.setAttribute("orderId", orderId);
        request.setAttribute("payment", orderInfo.getPayment());
        // b)當前日期加三天。
        DateTime dateTime = new DateTime();
        dateTime = dateTime.plusDays(3);
        request.setAttribute("date", dateTime.toString("yyyy-MM-dd"));
        // 4、返回邏輯視圖展示成功頁面
        return "success";
    }

 


3. 
Mycat資料庫分片

 

海量數據的存儲問題

如今隨著互聯網的發展,數據的量級也是撐指數的增長,從GBTBPB。對數據的各種操作也是愈加的困難,傳統的關係性資料庫已經無法滿足快速查詢與插入數據的需求。這個時候NoSQL的出現暫時解決了這一危機。它通過降低數據的安全性,減少對事務的支持,減少對複雜查詢的支持,來獲取性能上的提升。

但是,在有些場合NoSQL一些折衷是無法滿足使用場景的,就比如有些使用場景是絕對要有事務與安全指標的。這個時候NoSQL肯定是無法滿足的,所以還是需要使用關係性資料庫。如果使用關係型資料庫解決海量存儲的問題呢?此時就需要做資料庫集群,為了提高查詢性能將一個資料庫的數據分散到不同的資料庫中存儲。

1.1 什麼是資料庫分片

簡單來說,就是指通過某種特定的條件,將我們存放在同一個資料庫中的數據分散存放到多個資料庫(主機)上面,以達到分散單台設備負載的效果。

數據的切分(Sharding)根據其切分規則的類型,可以分為兩種切分模式。

(1)一種是按照不同的表(或者Schema)來切分到不同的資料庫(主機)之上,這種切可以稱之為數據的垂直(縱向)切分

 

 

 

(2)另外一種則是根據表中的數據的邏輯關係,將同一個表中的數據按照某種條件拆分到多台資料庫(主機)上面,這種切分稱之為數據的水平(橫向)切分。

 

 

1.2 如何實現資料庫分片

當資料庫分片後,數據由一個資料庫分散到多個資料庫中。此時系統要查詢時需要切換不同的資料庫進行查詢,那麼系統如何知道要查詢的數據在哪個資料庫中?當添加一條記錄時要向哪個資料庫中插入呢?這些問題處理起來都是非常的麻煩。

這種情況下可以使用一個資料庫中間件mycat來解決相關的問題。接下來瞭解一下什麼是mycat

Mycat介紹

2.1 什麼是Mycat

 

Mycat 背後是阿裡曾經開源的知名產品——CobarCobar 的核心功能和優勢是 MySQL 資料庫分片,此產品曾經廣為流傳,據說最早的發起者對 Mysql 很精通,後來從阿裡跳槽了,阿裡隨後開源的 Cobar,並維持到 2013 年年初,然後,就沒有然後了。

Cobar 的思路和實現路徑的確不錯。基於 Java 開發的,實現了 MySQL 公開的二進位傳輸協議,巧妙地將自己偽裝成一個 MySQL Server,目前市面上絕大多數 MySQL 客戶端工具和應用都能相容。比自己實現一個新的資料庫協議要明智的多,因為生態環境在哪裡擺著。

 

Mycat 是基於 cobar 演變而來,對 cobar 的代碼進行了徹底的重構,使用 NIO 重構了網路模塊,並且優化了 Buffer 內核,增強了聚合,Join 等基本特性,同時相容絕大多數資料庫成為通用的資料庫中間件。

簡單的說,MyCAT就是:

·一個新穎的資料庫中間件產品支持mysql集群,或者mariadb cluster提供高可用性數據分片集群。你可以像使用mysql一樣使用mycat。對於開發人員來說根本感覺不到mycat的存在。

 

2.2 Mycat支持的資料庫

 

2.3 Mycat的分片策略

 

 

 

 

2.4 概念說明

2.4.1 邏輯庫(schema)

前面一節講了資料庫中間件,通常對實際應用來說,並不需要知道中間件的存在,業務開發人員只需要知道資料庫的概念,所以資料庫中間件可以被看做是一個或多個資料庫集群構成的邏輯庫。

2.4.2 邏輯表(table):

既然有邏輯庫,那麼就會有邏輯表,分散式資料庫中,對應用來說,讀寫數據的表就是邏輯表。邏輯表,可以是數據切分後,分佈在一個或多個分片庫中,也可以不做數據切分,不分片,只有一個表構成。

分片表:是指那些原有的很大數據的表,需要切分到多個資料庫的表,這樣,每個分片都有一部分數據,所有分片構成了完整的數據。 總而言之就是需要進行分片的表。

非分片表:一個資料庫中並不是所有的表都很大,某些表是可以不用進行切分的,非分片是相對分片表來說的,就是那些不需要進行數據切分的表。

2.4.3 分片節點(dataNode)

數據切分後,一個大表被分到不同的分片資料庫上面,每個表分片所在的資料庫就是分片節點(dataNode)。

2.4.4 節點主機(dataHost)

數據切分後,每個分片節點(dataNode)不一定都會獨占一臺機器,同一機器上面可以有多個分片資料庫,這樣一個或多個分片節點(dataNode)所在的機器就是節點主機(dataHost,為了規避單節點主機併發數限制,儘量將讀寫壓力高的分片節點(dataNode)均衡的放在不同的節點主機(dataHost)。

2.4.5 分片規則(rule)

前面講了數據切分,一個大表被分成若幹個分片表,就需要一定的規則,這樣按照某種業務規則把數據分到某個分片的規則就是分片規則,數據切分選擇合適的分片規則非常重要,將極大的避免後續數據處理的難度。

Mycat的下載及安裝

3.1 安裝環境

1、jdk:要求jdk必須是1.7及以上版本

2、Mysql:推薦mysql5.5以上版本

3、Mycat

Mycat的官方網站:

http://www.mycat.org.cn/

下載地址:

https://github.com/MyCATApache/Mycat-download

 

3.2 安裝步驟

Mycatwindowslinux多種版本。本教程為linux安裝步驟,windows基本相同。

第一步:下載Mycat-server-xxxx-linux.tar.gz

第二步:將壓縮包解壓縮。建議將mycat放到/usr/local/mycat目錄下。

第三步:進入mycat目錄,啟動mycat

./mycat start

停止:

./mycat stop

mycat 支持的命令{ console | start | stop | restart | status | dump }

Mycat的預設埠號為:8066

Mycat的分片

4.1 需求

把商品表分片存儲到三個數據節點上。

 

4.2 安裝環境分析

兩台mysql資料庫伺服器:

Host1192.168.25.134

Host2192.168.25.166

 

host1環境

操作系統版本 : centos6.4

資料庫版本 : mysql-5.6

mycat版本 :1.4 release

資料庫名 : db1db3

 

 

mysql節點2環境

操作系統版本 : centos6.4

資料庫版本 : mysql-5.6

mycat版本 :1.4 release

資料庫名 : db2

 

MyCat安裝到節點1上(需要安裝jdk

 

4.3 配置schema.xml

4.3.1 Schema.xml介紹

Schema.xml作為MyCat中重要的配置文件之一,管理著MyCat的邏輯庫、表、分片規則、DataNode以及DataSource。弄懂這些配置,是正確使用MyCat的前提。這裡就一層層對該文件進行解析。

 

schema 標簽用於定義MyCat實例中的邏輯庫

Table 標簽定義了MyCat中的邏輯表

dataNode 標簽定義了MyCat中的數據節點,也就是我們通常說所的數據分片。

dataHost標簽在mycat邏輯庫中也是作為最底層的標簽存在,直接定義了具體的資料庫實例、讀寫分離配置和心跳語句。

 

註意:若是LINUX版本的MYSQL,則需要設置為Mysql大小寫不敏感,否則可能會發生表找不到的問題。

MySQL的配置文件中/etc/my.cnf [mysqld] 中增加一行

  lower_case_table_names=1

 

4.3.2 Schema.xml配置

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">

        <schema name="e3mall" checkSQLschema="false" sqlMaxLimit="100">
                <!-- auto sharding by id (long) -->
                <table name="tb_item" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />
        </schema>
        <dataNode name="dn1" dataHost="localhost1" database="db1" />
        <dataNode name="dn2" dataHost="localhost2" database="db2" />
        <dataNode name="dn3" dataHost="localhost1" database="db3" />
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="192.168.25.134:3306" user="root"
                        password="root">
                        <!-- can have multi read hosts -->

                </writeHost>
        </dataHost>
        <dataHost name="localhost2" maxCon="1000" minCon="10" balance="0"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
                <heartbeat>select user()</heartbeat>
                <!-- can have multi write hosts -->
                <writeHost host="hostM1" url="192.168.25.166:3306" user="root"
                        password="root">
                        <!-- can have multi read hosts -->

                </writeHost>
        </dataHost>
</mycat:schema>

 


4.4 
配置server.xml 

 

4.4.1 Server.xml介紹

server.xml幾乎保存了所有mycat需要的系統配置信息。最常用的是在此配置用戶名、密碼及許可權。

 

4.4.2 Server.xml配置

<user name="test">
    <property name="password">test</property>
    <property name="schemas">e3mall</property>
    <property name="readOnly">false</property>
</user>

 


4.5 
配置rule.xml 

rule.xml裡面就定義了我們對錶進行拆分所涉及到的規則定義。我們可以靈活的對錶使用不同的分片演算法,或者對錶使用相同的演算法但具體的參數不同。這個文件裡面主要有tableRulefunction這兩個標簽。在具體使用過程中可以按照需求添加tableRule

function

此配置文件可以不用修改,使用預設即可。

4.6 測試分片

4.6.1 創建表

配置完畢後,重新啟動mycat。使用mysql客戶端連接mycat,創建表。

-- ----------------------------
-- Table structure for tb_item
-- ----------------------------
DROP TABLE IF EXISTS `tb_item`;
CREATE TABLE `tb_item` (
  `id` bigint(20) NOT NULL COMMENT '商品id,同時也是商品編號',
  `title` varchar(100) NOT NULL COMMENT '商品標題',
  `sell_point` varchar(500) DEFAULT NULL COMMENT '商品賣點',
  `price` bigint(20) NOT NULL COMMENT '商品價格,單位為:分',
  `num` int(10) NOT NULL COMMENT '庫存數量',
  `barcode` varchar(30) DEFAULT NULL COMMENT '商品條形碼',
  `image` varchar(500) DEFAULT NULL COMMENT '商品圖片',
  `cid` bigint(10) NOT NULL COMMENT '所屬類目,葉子類目',
  `status` tinyint(4) NOT NULL DEFAULT '1' COMMENT '商品狀態,1-正常,2-下架,3-刪除',
  `created` datetime NOT NULL COMMENT '創建時間',
  `updated` datetime NOT NULL COMMENT '更新時間',
  PRIMARY KEY (`id`),
  KEY `cid` (`cid`),
  KEY `status` (`status`),
  KEY `updated` (`updated`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='商品表';

 


4.6.2 
插入數據 

 

將此文件中的數據插入到資料庫:

 

 

 

4.6.3 分片測試

由於配置的分片規則為“auto-sharding-long”,所以mycat會根據此規則自動分片。

每個datanode中保存一定數量的數據。根據id進行分片

經測試id範圍為:

Datanode11~5000000

Datanode25000000~10000000

Datanode310000001~15000000

 

15000000以上的id插入時報錯:

[Err] 1064 - can't find any valid datanode :TB_ITEM -> ID -> 15000001

此時需要添加節點了。


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

-Advertisement-
Play Games
更多相關文章
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...