spring data jpa(一)

来源:https://www.cnblogs.com/xuan-cz/archive/2019/01/09/10242430.html
-Advertisement-
Play Games

第1章 Spring Data JPA的快速入門 1.1 需求說明 Spring Data JPA完成客戶的基本CRUD操作 1.2 搭建Spring Data JPA的開發環境 1.2.1 引入Spring Data JPA的坐標 使用Spring Data JPA,需要整合Spring與Spri ...


第1章     Spring Data JPA的快速入門

1.1   需求說明

Spring Data JPA完成客戶的基本CRUD操作

1.2   搭建Spring Data JPA的開發環境

1.2.1      引入Spring Data JPA的坐標

使用Spring Data JPA,需要整合Spring與Spring Data JPA,並且需要提供JPA的服務提供者hibernate,所以需要導入spring相關坐標,hibernate坐標,資料庫驅動坐標等

 

  <properties>

        <spring.version>4.2.4.RELEASE</spring.version>

        <hibernate.version>5.0.7.Final</hibernate.version>

        <slf4j.version>1.6.6</slf4j.version>

        <log4j.version>1.2.12</log4j.version>

        <c3p0.version>0.9.1.2</c3p0.version>

        <mysql.version>5.1.6</mysql.version>

    </properties>

 

    <dependencies>

        <!-- junit單元測試 -->

        <dependency>

            <groupId>junit</groupId>

            <artifactId>junit</artifactId>

            <version>4.9</version>

            <scope>test</scope>

        </dependency>

       

        <!-- spring beg -->

        <dependency>

            <groupId>org.aspectj</groupId>

            <artifactId>aspectjweaver</artifactId>

            <version>1.6.8</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-aop</artifactId>

            <version>${spring.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context</artifactId>

            <version>${spring.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-context-support</artifactId>

            <version>${spring.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-orm</artifactId>

            <version>${spring.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-beans</artifactId>

            <version>${spring.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-core</artifactId>

            <version>${spring.version}</version>

        </dependency>

       

        <!-- spring end -->

 

        <!-- hibernate beg -->

        <dependency>

            <groupId>org.hibernate</groupId>

            <artifactId>hibernate-core</artifactId>

            <version>${hibernate.version}</version>

        </dependency>

        <dependency>

            <groupId>org.hibernate</groupId>

            <artifactId>hibernate-entitymanager</artifactId>

            <version>${hibernate.version}</version>

        </dependency>

        <dependency>

            <groupId>org.hibernate</groupId>

            <artifactId>hibernate-validator</artifactId>

            <version>5.2.1.Final</version>

        </dependency>

        <!-- hibernate end -->

 

        <!-- c3p0 beg -->

        <dependency>

            <groupId>c3p0</groupId>

            <artifactId>c3p0</artifactId>

            <version>${c3p0.version}</version>

        </dependency>

        <!-- c3p0 end -->

 

        <!-- log end -->

        <dependency>

            <groupId>log4j</groupId>

            <artifactId>log4j</artifactId>

            <version>${log4j.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-api</artifactId>

            <version>${slf4j.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.slf4j</groupId>

            <artifactId>slf4j-log4j12</artifactId>

            <version>${slf4j.version}</version>

        </dependency>

        <!-- log end -->

 

       

        <dependency>

            <groupId>mysql</groupId>

            <artifactId>mysql-connector-java</artifactId>

            <version>${mysql.version}</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.data</groupId>

            <artifactId>spring-data-jpa</artifactId>

            <version>1.9.0.RELEASE</version>

        </dependency>

 

        <dependency>

            <groupId>org.springframework</groupId>

            <artifactId>spring-test</artifactId>

            <version>4.2.4.RELEASE</version>

        </dependency>

       

        <!-- el beg 使用spring data jpa 必須引入 -->

        <dependency> 

            <groupId>javax.el</groupId> 

            <artifactId>javax.el-api</artifactId> 

            <version>2.2.4</version> 

        </dependency> 

         

        <dependency> 

            <groupId>org.glassfish.web</groupId> 

            <artifactId>javax.el</artifactId> 

            <version>2.2.4</version> 

        </dependency>

        <!-- el end -->

    </dependencies>

 

 

1.2.2      整合Spring Data JPA與Spring

 

<?xml version="1.0" encoding="UTF-8"?>

<beans xmlns="http://www.springframework.org/schema/beans"

    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"

    xmlns:context="http://www.springframework.org/schema/context"

    xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx"

    xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task"

    xsi:schemaLocation="

        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd

        http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd

        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd

        http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd

        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd

        http://www.springframework.org/schema/data/jpa

        http://www.springframework.org/schema/data/jpa/spring-jpa.xsd">

   

    <!-- 1.dataSource 配置資料庫連接池-->

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">

        <property name="driverClass" value="com.mysql.jdbc.Driver" />

        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa" />

        <property name="user" value="root" />

        <property name="password" value="111111" />

    </bean>

   

    <!-- 2.配置entityManagerFactory -->

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">

        <property name="dataSource" ref="dataSource" />

        <property name="packagesToScan" value="cn.itcast.entity" />

        <property name="persistenceProvider">

            <bean class="org.hibernate.jpa.HibernatePersistenceProvider" />

        </property>

        <!--JPA的供應商適配器-->

        <property name="jpaVendorAdapter">

            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">

                <property name="generateDdl" value="false" />

                <property name="database" value="MYSQL" />

                <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect" />

                <property name="showSql" value="true" />

            </bean>

        </property>

        <property name="jpaDialect">

            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect" />

        </property>

    </bean>

   

   

    <!-- 3.事務管理器-->

    <!-- JPA事務管理器  -->

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">

        <property name="entityManagerFactory" ref="entityManagerFactory" />

    </bean>

   

    <!-- 整合spring data jpa-->

    <jpa:repositories base-package="cn.itcast.dao"

        transaction-manager-ref="transactionManager"

        entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>

       

    <!-- 4.txAdvice-->

    <tx:advice id="txAdvice" transaction-manager="transactionManager">

        <tx:attributes>

            <tx:method name="save*" propagation="REQUIRED"/>

            <tx:method name="insert*" propagation="REQUIRED"/>

            <tx:method name="update*" propagation="REQUIRED"/>

            <tx:method name="delete*" propagation="REQUIRED"/>

            <tx:method name="get*" read-only="true"/>

            <tx:method name="find*" read-only="true"/>

            <tx:method name="*" propagation="REQUIRED"/>

        </tx:attributes>

    </tx:advice>

   

    <!-- 5.aop-->

    <aop:config>

        <aop:pointcut id="pointcut" expression="execution(* cn.itcast.service.*.*(..))" />

        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut" />

    </aop:config>

   

    <context:component-scan base-package="cn.itcast"></context:component-scan>

       

    <!--組裝其它 配置文件-->

   

</beans>

 

 

1.2.3      使用JPA註解配置映射關係

我們使用昨天案例中的Customer實體類對象,已經配置好了映射關係

 

package cn.itcast.entity;

 

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.GeneratedValue;

import javax.persistence.GenerationType;

import javax.persistence.Id;

import javax.persistence.Table;

 

/**

 *

 *      * 所有的註解都是使用JPA的規範提供的註解,

 *      * 所以在導入註解包的時候,一定要導入javax.persistence下的

 */

@Entity //聲明實體類

@Table(name="cst_customer") //建立實體類和表的映射關係

public class Customer {

   

    @Id//聲明當前私有屬性為主鍵

    @GeneratedValue(strategy=GenerationType.IDENTITY) //配置主鍵的生成策略

    @Column(name="cust_id") //指定和表中cust_id欄位的映射關係

    private Long custId;

   

    @Column(name="cust_name") //指定和表中cust_name欄位的映射關係

    private String custName;

   

    @Column(name="cust_source")//指定和表中cust_source欄位的映射關係

    private String custSource;

   

    @Column(name="cust_industry")//指定和表中cust_industry欄位的映射關係

    private String custIndustry;

   

    @Column(name="cust_level")//指定和表中cust_level欄位的映射關係

    private String custLevel;

   

    @Column(name="cust_address")//指定和表中cust_address欄位的映射關係

    private String custAddress;

   

    @Column(name="cust_phone")//指定和表中cust_phone欄位的映射關係

    private String custPhone;

   

    public Long getCustId() {

        return custId;

    }

    public void setCustId(Long custId) {

        this.custId = custId;

    }

    public String getCustName() {

        return custName;

    }

    public void setCustName(String custName) {

        this.custName = custName;

    }

    public String getCustSource() {

        return custSource;

    }

    public void setCustSource(String custSource) {

        this.custSource = custSource;

    }

    public String getCustIndustry() {

        return custIndustry;

    }

    public void setCustIndustry(String custIndustry) {

        this.custIndustry = custIndustry;

    }

    public String getCustLevel() {

        return custLevel;

    }

    public void setCustLevel(String custLevel) {

        this.custLevel = custLevel;

    }

    public String getCustAddress() {

        return custAddress;

    }

    public void setCustAddress(String custAddress) {

        this.custAddress = custAddress;

    }

    public String getCustPhone() {

        return custPhone;

    }

    public void setCustPhone(String custPhone) {

        this.custPhone = custPhone;

    }

}

 

 

1.3   使用Spring Data JPA完成需求

1.3.1      編寫符合Spring Data JPA規範的Dao層介面

Spring Data JPA是spring提供的一款對於數據訪問層(Dao層)的框架,使用Spring Data JPA,只需要按照框架的規範提供dao介面,不需要實現類就可以完成資料庫的增刪改查、分頁查詢等方法的定義,極大的簡化了我們的開發過程。

 

在Spring Data JPA中,對於定義符合規範的Dao層介面,我們只需要遵循以下幾點就可以了:

 

1.創建一個Dao層介面,並實現JpaRepositoryJpaSpecificationExecutor

    2.提供相應的泛型

 

package cn.itcast.dao;

 

import java.util.List;

 

import org.springframework.data.jpa.repository.JpaRepository;

import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

 

import cn.itcast.entity.Customer;

 

/**

 * JpaRepository<實體類類型,主鍵類型>:用來完成基本CRUD操作

 * JpaSpecificationExecutor<實體類類型>:用於複雜查詢(分頁等查詢操作)

 */

public interface CustomerDao extends JpaRepository<Customer, Long>, JpaSpecificationExecutor<Customer> {

}

 

 

這樣我們就定義好了一個符合Spring Data JPA規範的Dao層介面

1.3.2      完成基本CRUD操作

完成了Spring Data JPA的環境搭建,並且編寫了符合Spring Data JPA 規範的Dao層介面之後,就可以使用定義好的Dao層介面進行客戶的基本CRUD操作

 

@RunWith(SpringJUnit4ClassRunner.class)

@ContextConfiguration(locations="classpath:applicationContext.xml")

public class CustomerDaoTest {

 

    @Autowired

    private CustomerDao customerDao;

   

    /**

     * 保存客戶:調用save(obj)方法

     */

    @Test

    public void testSave() {

        Customer c = new Customer();

        c.setCustName("傳智播客");

        customerDao.save(c);

    }

   

    /**

     * 修改客戶:調用save(obj)方法

     *      對於save方法的解釋:如果執行此方法是對象中存在id屬性,即為更新操作會先根據id查詢,再更新   

     *                      如果執行此方法中對象中不存在id屬性,即為保存操作

     *         

     */

    @Test

    public void testUpdate() {

        //根據id查詢id為1的客戶

        Customer customer = customerDao.findOne(1l);

        //修改客戶名稱

        customer.setCustName("傳智播客順義校區");

        //更新

        customerDao.save(customer);

    }

   

    /**

     * 根據id刪除:調用delete(id)方法

     */

    @Test

    public void testDelete() {

        customerDao.delete(1l);

    }

   

    /**

     * 根據id查詢:調用findOne(id)方法

     */

    @Test

    public void testFindById() {

        Customer customer = customerDao.findOne(2l);

        System.out.println(customer);

    }

}

 

 

第2章     Spring Data JPA的內部原理剖析

2.1   Spring Data JPA的常用介面分析

在客戶的案例中,我們發現在自定義的CustomerDao中,並沒有提供任何方法就可以使用其中的很多方法,那麼這些方法究竟是怎麼來的呢?答案很簡單,對於我們自定義的Dao介面,由於繼承了JpaRepository和JpaSpecificationExecutor,所以我們可以使用這兩個介面的所有方法。

 

 

在使用Spring Data JPA時,一般實現JpaRepository和JpaSpecificationExecutor介面,這樣就可以使用這些介面中定義的方法,但是這些方法都只是一些聲明,沒有具體的實現方式,那麼在 Spring Data JPA中它又是怎麼實現的呢?

2.2   Spring Data JPA的實現過程

通過對客戶案例,以debug斷點調試的方式,通過分析Spring Data JPA的原來來分析程式的執行過程

我們以findOne方法為例進行分析

 

代理子類的實現過程

 通過JDKDynamicAopProxy 創建動態代理對象

動態代理對象:simpleJpaRepository 實現了JapRepository 和 JpaSpecificationExecutor。對基本增刪改查進行了封裝。最終通過EntityManager完成增刪改查操作

 

 

 

斷點執行到方法上時,我們可以發現註入的customerDao對象,本質上是通過JdkDynamicAopProxy生成的一個代理對象

 

 

代理對象中方法調用的分析

 

當程式執行的時候,會通過JdkDynamicAopProxy的invoke方法,對customerDao對象生成動態代理對象。根據對Spring Data JPA介紹而知,要想進行findOne查詢方法,最終還是會出現JPA規範的API完成操作,那麼這些底層代碼存在於何處呢?答案很簡單,都隱藏在通過JdkDynamicAopProxy生成的動態代理對象當中,而這個動態代理對象就是SimpleJpaRepository

     

   

 

   

通過SimpleJpaRepository的源碼分析,定位到了findOne方法,在此方法中,返回em.find()的返回結果,那麼em又是什麼呢?

 

   

帶著問題繼續查找em對象,我們發現em就是EntityManager對象,而他是JPA原生的實現方式,所以我們得到結論Spring Data JPA只是對標準JPA操作進行了進一步封裝,簡化了Dao層代碼的開發

2.3   Spring Data JPA完整的調用過程分析

 

第3章     Spring Data JPA的查詢方式

3.1   使用Spring Data JPA中介面定義的方法進行查詢

在繼承JpaRepository,和JpaRepository介面後,我們就可以使用介面中定義的方法進行查詢

 

繼承JpaRepository後的方法列表

 delete

  刪除

findAll

  查詢所有

findOne

  直接載入

getOne

  底層是getRefresh()。是延遲載入的

save:

      save方法保存的對象主鍵為null,視為保存。主鍵存在值,視為修改

 

 

繼承JpaSpecificationExecutor的方法列表

   繼承了以 Specification 為參數的動態查詢方法

3.2   使用JPQL的方式查詢

使用Spring Data JPA提供的查詢方法已經可以解決大部分的應用場景,但是對於某些業務來說,我們還需要靈活的構造查詢條件,這時就可以使用@Query註解,結合JPQL的語句方式完成查詢

 

@Query 註解的使用非常簡單,只需在方法上面標註該註解,同時提供一個JPQL查詢語句即可

 

public interface CustomerDao extends JpaRepository<Customer, Long>,JpaSpecificationExecutor<Customer> {   

    //@Query 使用jpql的方式查詢。

    @Query(value="from Customer")

    public List<Customer> findAllCustomer();

   

    //@Query 使用jpql的方式查詢。?1代表參數的占位符,其中1對應方法中的參數索引

    @Query(value="from Customer where custName = ?1")

    public Customer findCustomer(String custName);

}

 

 

此外,也可以通過使用 @Query 來執行一個更新操作,為此,我們需要在使用 @Query 的同時,用 @Modifying 來將該操作標識為修改查詢,這樣框架最終會生成一個更新的操作,而非查詢

 

    @Query(value="update Customer set custName = ?1 where custId = ?2")

    @Modifying

    public void updateCustomer(String custName,Long custId);

 

3.3   使用SQL語句查詢

Spring Data JPA同樣也支持sql語句的查詢,如下:

 

    /**

     * nativeQuery : 使用本地sql的方式查詢

     */

    @Query(value="select * from cst_customer",nativeQuery=true)

    public void findSql();

 

3.4   方法命名規則查詢

顧名思義,方法命名規則查詢就是根據方法的名字,就能創建查詢。只需要按照Spring Data JPA提供的方法命名規則定義方法的名稱,就可以完成查詢工作。Spring Data JPA在程式執行的時候會根據方法名稱進行解析,並自動生成查詢語句進行查詢

 

按照Spring Data JPA 定義的規則,查詢方法以findBy開頭,涉及條件查詢時,條件的屬性用條件關鍵字連接,要註意的是:條件屬性首字母需大寫。框架在進行方法名解析時,會先把方法名多餘的首碼截取掉,然後對剩下部分進行解析。

 

    //方法命名方式查詢(根據客戶名稱查詢客戶)

    public Customer findByCustName(String custName);

 

 

具體的關鍵字,使用方法和生產成SQL如下表所示

 

         

Keyword

Sample

JPQL

   

And

findByLastnameAndFirstname

… where x.lastname = ?1 and x.firstname = ?2

   

Or

findByLastnameOrFirstname

… where x.lastname = ?1 or x.firstname = ?2

   

Is,Equals

findByFirstnameIs,

findByFirstnameEquals

… where x.firstname = ?1

   

Between

findByStartDateBetween

… where x.startDate between ?1 and ?2

   

LessThan

findByAgeLessThan

… where x.age < ?1

   

LessThanEqual

findByAgeLessThanEqual

… where x.age ⇐ ?1

   

GreaterThan

findByAgeGreaterThan

… where x.age > ?1

   

GreaterThanEqual

findByAgeGreaterThanEqual

… where x.age >= ?1

   

After

findByStartDateAfter

… where x.startDate > ?1

   

Before

findByStartDateBefore

… where x.startDate < ?1

   

IsNull

findByAgeIsNull

… where x.age is null

   

IsNotNull,NotNull

findByAge(Is)NotNull

… where x.age not null

   

Like

findByFirstnameLike

… where x.firstname like ?1

   

NotLike

findByFirstnameNotLike

… where x.firstname not like ?1

   

StartingWith

findByFirstnameStartingWith

… where x.firstname like ?1 (parameter bound with appended %)

   

EndingWith

findByFirstnameEndingWith

… where x.firstname like ?1 (parameter bound with prepended %)

   

Containing

findByFirstnameContaining

… where x.firstname like ?1 (parameter bound wrapped in %)

   

OrderBy

findByAgeOrderByLastnameDesc

… where x.age = ?1 order by x.lastname desc

   

Not

findByLastnameNot

… where x.lastname <> ?1

   

In

findByAgeIn(Collection ages)

… where x.age in ?1

   

NotIn

findByAgeNotIn(Collection age)

… where x.age not in ?1

   

TRUE

findByActiveTrue()

… where x.active = true

   

FALSE

findByActiveFalse()

… where x.active = false

   

IgnoreCase

findByFirstnameIgnoreCase

… where UPPER(x.firstame) = UPPER(?1)

   

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

-Advertisement-
Play Games
更多相關文章
  • 首先,在進行認識深拷貝和淺拷貝之前,我們需要瞭解到W3關於數據類型的區分 數據類型: 基本類型:String/Number/Boolean/Null/undefined/Symbol/ 直接存儲在棧中的數據 引用類型:Object,Array等 存儲的時是對象在棧中的引用,真實的數據存放在堆記憶體里 ...
  • 在網頁開發中,常常會遇見很多Tab切換,Tab切換增加網頁瀏覽的舒適性,對於開發人員特別常見,本文使用JS實現tab切換效果,僅對學習中遇到的知識點做一個總結。 效果圖如下: 實現思路: 1.首先使用HTML和CSS構建靜態網頁如上,標題使用ul-li標簽,有浮動,主體使用四個大小一樣的盒子,不添加 ...
  • 這幾天在項目中遇到,一個難點, 就是需要非同步載入一個pdf插件, 同時又需要獲取這個插件中的點擊事件來生成用戶的下載記錄. 剛開始也是想了很多方法,網上搜的 發現在跨域環境下並沒有用, 看到有些人說這個無解, 需要走後臺, 我當時也是涼涼感覺. 後來自己也是想了辦法,在插件頁面中給按鈕綁定事件,然後 ...
  • 1、長度 2、角度 3、時間 4、解析度 5、顏色 6、函數 7、生成內容 8、圖像 9、數字 1、長度 <length>:數字和單位之間沒有空格,0之後的長度單位是可選的 相對長度單位 em:相對於字體大小 ex:相對於小寫字母"x"的高度,對於很多字體,1ex ≈ 0.5em ch:相對於數字" ...
  • 1、CSS語法 2、@規則 3、註釋 4、層疊 5、優先順序 6、繼承 7、值 8、塊格式化上下文 9、盒模型 10、層疊上下文 11、可替換元素 12、外邊距合併 13、包含塊 14、視覺格式化模型 15、佈局模式 1、CSS語法 屬性:property 值:value CSS聲明:property ...
  • 在面向對象當中繼承是非常重要的,也是面向對象的三大特性之一(繼承、封裝、多態),今天我們來揭開他的神秘面紗。 話不多說,我們上菜。 寫好代碼後我們運行看看效果! 很顯然看出來,公司兩個程式員都繼承了程式員類。 總結: 父類包含了多少內容,派生類(子類)全部接受(包括屬性 欄位 方法等), 可以重寫覆 ...
  • 委托 1、 什麼是委托? 委托就是具有相同簽名和返回值類型的有序方法列表 它定義了方法的類型,使得可以將方法當作另一個方法的參數來進行傳遞 如圖: 2、 委托的聲明 先來看看委托是如何聲明的 a、委托類型的聲明看上去與方法的聲明很類似,有返回類型和簽名。返回類型和簽名指定了委托接受的方法的形式 b、 ...
  • 在新的項目里使用倉庫的包 上一講中我們說了 "java~gradle構建公用包並上傳到倉庫" ,如何發佈公用的非自啟動類的包到私有倉庫,而這一講我們將學習如何使用這些包,就像我們使用spring框架里的功能包一樣。 參考:http://www.zhyea.com/2018/04/24/gradle ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...