• <noscript id="e0iig"><kbd id="e0iig"></kbd></noscript>
  • <td id="e0iig"></td>
  • <option id="e0iig"></option>
  • <noscript id="e0iig"><source id="e0iig"></source></noscript>
  • 01Mybatis的介紹和基本使用

    標簽: Mybatis

    01Mybatis的介紹和基本使用

    0、數據庫操作框架的歷程

    (1) JDBC

    ? JDBC(Java Data Base Connection,java數據庫連接)是一種用于執行SQL語句的Java API,可以為多種關系數據庫提供統一訪問,它由一組用Java語言編寫的類和接口組成.JDBC提供了一種基準,據此可以構建更高級的工具和接口,使數據庫開發人員能夠編寫數據庫應用程序

    • 優點:運行期:快捷、高效
    • 缺點:編輯期:代碼量大、繁瑣異常處理、不支持數據庫跨平臺

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-b3Uo7GuX-1598875733422)(images\jdbc.jpg)]

    (2) DBUtils

    ? DBUtils是Java編程中的數據庫操作實用工具,小巧簡單實用。

    ? DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少寫代碼。

    ? DBUtils三個核心功能介紹

    ? 1、QueryRunner中提供對sql語句操作的API

    ? 2、ResultSetHandler接口,用于定義select操作后,怎樣封裝結果集

    ? 3、DBUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法

    (3)Hibernate

    ? Hibernate 是由 Gavin King 于 2001 年創建的開放源代碼的對象關系框架。它強大且高效的構建具有關系對象持久性和查詢服務的 Java 應用程序。

    ? Hibernate 將 Java 類映射到數據庫表中,從 Java 數據類型中映射到 SQL 數據類型中,并把開發人員從 95% 的公共數據持續性編程工作中解放出來。

    ? Hibernate 是傳統 Java 對象和數據庫服務器之間的橋梁,用來處理基于 O/R 映射機制和模式的那些對象。

    [外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-MP8gjGFL-1598875733425)(images\hibernate.jpg)]

    ? Hibernate 優勢

    • Hibernate 使用 XML 文件來處理映射 Java 類別到數據庫表格中,并且不用編寫任何代碼。

    • 為在數據庫中直接儲存和檢索 Java 對象提供簡單的 APIs。

    • 如果在數據庫中或任何其它表格中出現變化,那么僅需要改變 XML 文件屬性。

    • 抽象不熟悉的 SQL 類型,并為我們提供工作中所熟悉的 Java 對象。

    • Hibernate 不需要應用程序服務器來操作。

    • 操控你數據庫中對象復雜的關聯。

    • 最小化與訪問數據庫的智能提取策略。

    • 提供簡單的數據詢問。

      Hibernate劣勢

    • hibernate的完全封裝導致無法使用數據的一些功能。

    • Hibernate的緩存問題。

    • Hibernate對于代碼的耦合度太高。

    • Hibernate尋找bug困難。

    • Hibernate批量數據操作需要大量的內存空間而且執行過程中需要的對象太多

      (4) JDBCTemplate

    ? JdbcTemplate針對數據查詢提供了多個重載的模板方法,你可以根據需要選用不同的模板方法.如果你的查詢很簡單,僅僅是傳入相應SQL或者相關參數,然后取得一個單一的結果,那么你可以選擇如下一組便利的模板方法。

    ? 優點:運行期:高效、內嵌Spring框架中、支持基于AOP的聲明式事務
    ? 缺點:必須于Spring框架結合在一起使用、不支持數據庫跨平臺、默認沒有緩存

    1、什么是Mybatis?

    ? MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)為數據庫中的記錄。

    ? 優點:

    ? 1、與JDBC相比,減少了50%的代碼量

    ? 2、 最簡單的持久化框架,簡單易學

    ? 3、SQL代碼從程序代碼中徹底分離出來,可以重用

    ? 4、提供XML標簽,支持編寫動態SQL

    ? 5、提供映射標簽,支持對象與數據庫的ORM字段關系映射

    ? 缺點:

    ? 1、SQL語句編寫工作量大,熟練度要高

    ? 2、數據庫移植性比較差,如果需要切換數據庫的話,SQL語句會有很大的差異

    2、第一個Mybatis項目

    ? 1、創建普通的maven項目

    ? 2、導入相關的依賴

    ? pom.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <project xmlns="http://maven.apache.org/POM/4.0.0"
             xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
             xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
    
        <groupId>com.mashibing</groupId>
        <artifactId>mybatis_helloworld</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.4</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>8.0.16</version>
            </dependency>
            <!-- https://mvnrepository.com/artifact/log4j/log4j -->
            <dependency>
                <groupId>log4j</groupId>
                <artifactId>log4j</artifactId>
                <version>1.2.17</version>
            </dependency>
    
        </dependencies>
    
    </project>
    

    ? 3、創建對應的數據表,數據表我們使用之前的demo數據庫,腳本文件在群里,大家自行去下載安裝

    ? 4、創建與表對應的實體類對象

    emp.java

    package com.mashibing.bean;
    
    import java.util.Date;
    
    public class Emp {
    
        private Integer empno;
        private String ename;
        private String job;
        private Integer mgr;
        private Date hiredate;
        private Double sal;
        private Double common;
        private Integer deptno;
    
        public Emp() {
        }
    
        public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double common, Integer deptno) {
            this.empno = empno;
            this.ename = ename;
            this.job = job;
            this.mgr = mgr;
            this.hiredate = hiredate;
            this.sal = sal;
            this.common = common;
            this.deptno = deptno;
        }
    
        public Integer getEmpno() {
            return empno;
        }
    
        public void setEmpno(Integer empno) {
            this.empno = empno;
        }
    
        public String getEname() {
            return ename;
        }
    
        public void setEname(String ename) {
            this.ename = ename;
        }
    
        public String getJob() {
            return job;
        }
    
        public void setJob(String job) {
            this.job = job;
        }
    
        public Integer getMgr() {
            return mgr;
        }
    
        public void setMgr(Integer mgr) {
            this.mgr = mgr;
        }
    
        public Date getHiredate() {
            return hiredate;
        }
    
        public void setHiredate(Date hiredate) {
            this.hiredate = hiredate;
        }
    
        public Double getSal() {
            return sal;
        }
    
        public void setSal(Double sal) {
            this.sal = sal;
        }
    
        public Double getCommon() {
            return common;
        }
    
        public void setCommon(Double common) {
            this.common = common;
        }
    
        public Integer getDeptno() {
            return deptno;
        }
    
        public void setDeptno(Integer deptno) {
            this.deptno = deptno;
        }
    
        @Override
        public String toString() {
            return "Emp{" +
                    "empno=" + empno +
                    ", ename='" + ename + '\'' +
                    ", job='" + job + '\'' +
                    ", mgr=" + mgr +
                    ", hiredate=" + hiredate +
                    ", sal=" + sal +
                    ", common=" + common +
                    ", deptno=" + deptno +
                    '}';
        }
    }
    

    ? 5、創建對應的dao類

    EmpDao.java

    package com.mashibing.dao;
    
    import com.mashibing.bean.Emp;
    
    public interface EmpDao {
    
        public Emp findEmpByEmpno(Integer empno);
        
    }
    

    ? 6、編寫配置文件

    log4j.properties

    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">
    <configuration>
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!--配置數據庫連接-->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/demo?serverTimezone=UTC"/>
                    <property name="username" value="root"/>
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
        <!--引入每一個接口對應點xml文件-->
        <mappers>
            <mapper resource="EmpDao.xml"/>
        </mappers>
    </configuration>
    

    EmpDao.xml

    <?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:編寫接口的全類名,就是告訴要實現該配置文件是哪個接口的具體實現-->
    <mapper namespace="com.mashibing.dao.EmpDao">
        <!--
        select:表示這個操作是一個查詢操作
        id表示的是要匹配的方法的名稱
        resultType:表示返回值的類型,查詢操作必須要包含返回值的類型
        #{屬性名}:表示要傳遞的參數的名稱
        -->
        <select id="findEmpByEmpno" resultType="com.mashibing.bean.Emp">
            select * from emp where empno = #{empno}
      </select>
    </mapper>
    

    ? 7、編寫測試類

    MyTest.java

    package com.mashibing.test;
    
    import com.mashibing.bean.Emp;
    import com.mashibing.dao.EmpDao;
    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.InputStream;
    
    public class MyTest {
    
        @Test
        public void test01() {
            // 根據全局配置文件創建出SqlSessionFactory
            // SqlSessionFactory:負責創建SqlSession對象的工廠
            // SqlSession:表示跟數據庫建議的一次會話
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
            } catch (IOException e) {
                e.printStackTrace();
            }
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            // 獲取數據庫的會話
            SqlSession sqlSession = sqlSessionFactory.openSession();
            Emp empByEmpno = null;
            try {
                // 獲取要調用的接口類
                EmpDao mapper = sqlSession.getMapper(EmpDao.class);
                // 調用方法開始執行
                empByEmpno = mapper.findEmpByEmpno(7369);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                sqlSession.close();
            }
            System.out.println(empByEmpno);
        }
    }
    

    3、增刪改查的基本操作

    EmpDao.java

    package com.mashibing.dao;
    
    import com.mashibing.bean.Emp;
    
    public interface EmpDao {
    
        public Emp findEmpByEmpno(Integer empno);
    
        public int updateEmp(Emp emp);
    
        public int deleteEmp(Integer empno);
    
        public int insertEmp(Emp emp);
    
    }
    

    EmpDao.xml

    <?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:編寫接口的全類名,就是告訴要實現該配置文件是哪個接口的具體實現-->
    <mapper namespace="com.mashibing.dao.EmpDao">
        <!--
        select:表示這個操作是一個查詢操作
        id表示的是要匹配的方法的名稱
        resultType:表示返回值的類型,查詢操作必須要包含返回值的類型
        #{屬性名}:表示要傳遞的參數的名稱
        -->
        <select id="findEmpByEmpno" resultType="com.mashibing.bean.Emp">
            select * from emp where empno = #{empno}
        </select>
        <!--增刪改查操作不需要返回值,增刪改返回的是影響的行數,mybatis會自動做判斷-->
        <insert id="insertEmp">
            insert into emp(empno,ename) values(#{empno},#{ename})
        </insert>
        <update id="updateEmp">
            update emp set ename=#{ename} where empno = #{empno}
        </update>
        <delete id="deleteEmp">
            delete from emp where empno = #{empno}
        </delete>
    </mapper>
    

    MyTest.java

    package com.mashibing.test;
    
    import com.mashibing.bean.Emp;
    import com.mashibing.dao.EmpDao;
    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.Before;
    import org.junit.Test;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    public class MyTest {
        SqlSessionFactory sqlSessionFactory = null;
        @Before
        public void init(){
            // 根據全局配置文件創建出SqlSessionFactory
            // SqlSessionFactory:負責創建SqlSession對象的工廠
            // SqlSession:表示跟數據庫建議的一次會話
            String resource = "mybatis-config.xml";
            InputStream inputStream = null;
            try {
                inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        @Test
        public void test01() {
    
            // 獲取數據庫的會話
            SqlSession sqlSession = sqlSessionFactory.openSession();
            Emp empByEmpno = null;
            try {
                // 獲取要調用的接口類
                EmpDao mapper = sqlSession.getMapper(EmpDao.class);
                // 調用方法開始執行
                empByEmpno = mapper.findEmpByEmpno(7369);
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                sqlSession.close();
            }
            System.out.println(empByEmpno);
        }
    
        @Test
        public void test02(){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            int zhangsan = mapper.insertEmp(new Emp(1111, "zhangsan"));
            System.out.println(zhangsan);
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Test
        public void test03(){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            int zhangsan = mapper.updateEmp(new Emp(1111, "lisi"));
            System.out.println(zhangsan);
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Test
        public void test04(){
            SqlSession sqlSession = sqlSessionFactory.openSession();
            EmpDao mapper = sqlSession.getMapper(EmpDao.class);
            int zhangsan = mapper.deleteEmp(1111);
            System.out.println(zhangsan);
            sqlSession.commit();
            sqlSession.close();
        }
    }
    

    4、配置文件詳解

    ? 在mybatis的項目中,我們發現了有一個mybatis-config.xml的配置文件,這個配置文件是mybatis的全局配置文件,用來進行相關的全局配置,在任何操作下都生效的配置。下面我們要針對其中的屬性做詳細的解釋,方便大家在后續使用的時候更加熟練。

    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">
    <configuration>
        <!--引入外部配置文件,類似于Spring中的property-placeholder
        resource:從類路徑引入
        url:從磁盤路徑或者網絡路徑引入
        -->
        <properties resource="db.properties"></properties>
        <!--用來控制mybatis運行時的行為,是mybatis中的重要配置-->
        <settings>
            <!--設置列名映射的時候是否是駝峰標識-->
            <setting name="mapUnderscoreToCamelCase" value="true"/>
        </settings>
        <!--typeAliases表示為我們引用的實體類起別名,默認情況下我們需要寫類的完全限定名
        如果在此處做了配置,那么可以直接寫類的名稱,在type中配置上類的完全限定名,在使用的時候可以忽略大小寫
        還可以通過alias屬性來表示類的別名
        -->
        <typeAliases>
    <!--        <typeAlias type="com.mashibing.bean.Emp" alias="Emp"></typeAlias>-->
            <!--如果需要引用多個類,那么給每一個類起別名肯定會很麻煩,因此可以指定對應的包名,那么默認用的是類名-->
            <package name="com.mashibing.bean"/>
        </typeAliases>
        <!--
        在實際的開發過程中,我們可能分為開發環境,生產環境,測試環境等等,每個環境的配置可以是不一樣的
        environment就用來表示不同環境的細節配置,每一個環境中都需要一個事務管理器以及數據源的配置
        我們在后續的項目開發中幾乎都是使用spring中配置的數據源和事務管理器來配置,此處不需要研究
        -->
        <!--default:用來選擇需要的環境-->
        <environments default="development">
            <!--id:表示不同環境的名稱-->
            <environment id="development">
                <transactionManager type="JDBC"/>
                <!--配置數據庫連接-->
                <dataSource type="POOLED">
                    <!--使用${}來引入外部變量-->
                    <property name="driver" value="${driverClassname}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
        <!--
        在不同的數據庫中,可能sql語句的寫法是不一樣的,為了增強移植性,可以提供不同數據庫的操作實現
        在編寫不同的sql語句的時候,可以指定databaseId屬性來標識當前sql語句可以運行在哪個數據庫中
        -->
        <databaseIdProvider type="DB_VENDOR">
            <property name="MySQL" value="mysql"/>
            <property name="SQL Server" value="sqlserver"/>
            <property name="Oracle" value="orcl"/>
        </databaseIdProvider>
        
        <!--將sql的映射文件適用mappers進行映射-->
        <mappers>
            <!--
            指定具體的不同的配置文件
            class:直接引入接口的全類名,可以將xml文件放在dao的同級目錄下,并且設置相同的文件名稱,同時可以使用注解的方式來進行相關的配置
            url:可以從磁盤或者網絡路徑查找sql映射文件
            resource:在類路徑下尋找sql映射文件
            -->
    <!--        <mapper resource="EmpDao.xml"/>
            <mapper resource="UserDao.xml"/>
            <mapper class="com.mashibing.dao.EmpDaoAnnotation"></mapper>-->
            <!--
            當包含多個配置文件或者配置類的時候,可以使用批量注冊的功能,也就是引入對應的包,而不是具體的配置文件或者類
            但是需要注意的是,
            1、如果使用的配置文件的形式,必須要將配置文件跟dao類放在一起,這樣才能找到對應的配置文件.
                如果是maven的項目的話,還需要添加以下配置,原因是maven在編譯的文件的時候只會編譯java文件
                    <build>
                        <resources>
                            <resource>
                                <directory>src/main/java</directory>
                            <includes>
                                <include>**/*.xml</include>
                            </includes>
                        </resource>
                        </resources>
                    </build>
    
            2、將配置文件在resources資源路徑下創建跟dao相同的包名
            -->
            <package name="com.mashibing.dao"/>
        </mappers>
    </configuration>
    

    EmpDaoAnnotation.java

    package com.mashibing.dao;
    
    import com.mashibing.bean.Emp;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
    
    public interface EmpDaoAnnotation {
    
        @Select("select * from emp where empno = #{empno}")
        public Emp findEmpByEmpno(Integer empno);
    
        @Update("update emp set ename=#{ename} where empno = #{empno}")
        public int updateEmp(Emp emp);
    
        @Delete("delete from emp where empno = #{empno}")
        public int deleteEmp(Integer empno);
    
        @Insert("insert into emp(empno,ename) values(#{empno},#{ename})")
        public int insertEmp(Emp emp);
    
    }
    
    版權聲明:本文為BUDDHA_Hugo原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。
    本文鏈接:https://blog.csdn.net/BUDDHA_Hugo/article/details/108328440

    智能推薦

    cordova學習筆記_創建一個cordova項目

    環境和工具 webstorm Node.js JDK git 打開git bash,進入你要創建項目的目錄,鍵入以下命令 進入cordovaDemo這個文件夾: 添加Android平臺 cordova platforms add android platforms中已經有了一個Android平臺 下面打開webstorm,然后file - open 找到cordovaDemo打開 現在在webst...

    TensorFlow識別圖片數字

    一、 第一步是先用tensorflow官網(http://www.tensorfly.cn/tfdoc/get_started/introduction.html)的手寫體數字識別例子訓練好一個模型,訓練完準確率一般能達到99%,然后保存訓練好的模型。 二、 主文件 完整代碼地址...

    spring boot項目搭建helloworld(一)

    備注:本文僅限快速啟動spring boot項目(尤其初學者了解spring boot框架) 結果展示: 工具: 編譯器:myeclipse2014  JDK:jdk1.8(1.8以下也可以但不可低于1.5,但會在項目上報小感嘆號(不影響運行)) maven:maven-3.5.3(myeclipse自帶maven也可以,但官網要求3.2或以上) spring boo...

    基于jquery Stellar.js實現 網站視差滾動效果

    stellar.js是一個 jQuery插件,能很容易地給網站添加視差滾動效果。 雖然已經停止了維護,但它非常穩定,與最新版本的jQuery兼容。 http://markdalgleish.com/projects/stellar.js/ 官網 1.引用js 包 2.引用html 3.引用css 4.js函數調用 常用參數:...

    vue富文本使用詳解

    一、cnpm 安裝 vue-quill-editor 二、在main.js中引入 三、在模塊中引用 這樣引入后你會得到這樣一個編輯器 那么你如果不需要那么多的工具欄功能要怎么辦呢;應該是通過options來修改但是他的默認值是什么的,這個官方文檔 :https://quilljs.com/docs/themes/里面看到了類似的方法 。 初始值的設置應該是一樣的吧 所以我就照著toolbar部分去...

    猜你喜歡

    指針所占字節大小

    在32位系統下一個指針的大小為4個字節 在64位系統下一個指針的大小為8個字節...

    ssh: connect to host 192.168.121.128 port 22: No route to host

    Ubuntu下測試ssh時使用ssh localhost 命令,出現錯誤提示connect to host localhost port 22:Connection refused 造成這個錯誤的原因可能是ssh-server未安裝或者未啟動。ubuntu 11.10 默認安裝openssh-client,但是木有安裝server 運行 ps -e | grep ssh,查看是否有sshd進程 如...

    JVM調優魔法棒-Java VisualVM

    Java VisualVM是單獨的一個工具,它提供了一個虛擬接口用以查看、故障排除和分析運行在JVM上的java程序的運行情況。在JDK中提供了各種類型的工具,其中就包含了Java VisualVM。例如,以前大多數獨立的工具如JConsole、jstat、jinfo、jstack和jmap,現在都集成到Java VisualVM中。Java VisualVM集成這些工具去獲取JVM的數據,然后重...

    如何實現自定義sk_buff數據包并提交協議棧

    目錄 一、自定義數據包的封裝流程 1. 分配skb 2.初始定位(skb_reserve) 3.拷貝數據(skb_push / skb_pull / skb_put / ) 4.設置傳輸層頭部 5.設置IP層頭部 6.添加以太網頭 二、自定義數據包的封裝實例 1. “純凈數據包”發送到本機的協議棧并交由上層處理: 2. “完整的IP數據包”...

    scrapy爬取前程無憂(2)

    1.安裝 pip install scrapy 報錯解決:離線安裝twisted pip install xxx-twisted.whl(百度搜索twisted 點擊twisted pypi進去下載相應的whl pip install pywin32(https://www.lfd.uci.edu/~gohlke/pythonlibs/,下載對應的whl文件) 2 切換到自己pycharm文件的位...

    精品国产乱码久久久久久蜜桃不卡