kotlin數據庫_如何在Kotlin應用程序中使用Xodus數據庫

kotlin數據庫

I want to show you how to use one of my favorite database choices for Kotlin applications. Namely, Xodus. Why do I like using Xodus for Kotlin applications? Well, here are a couple of its selling points:

我想向您展示如何在Kotlin應用程序中使用我最喜歡的數據庫選擇之一。 即Xodus 。 為什么我喜歡在Kotlin應用程序中使用Xodus? 好吧,這里有幾個賣點:

  • Transactional

    交易性

  • Embedded

    嵌入式的

  • Schema-less

    無模式

  • Pure JVM-based

    基于純JVM

  • Has an additional Kotlin DSL — Xodus-DNQ.

    還有一個額外的Kotlin DSL — Xodus-DNQ 。

What does this mean to you?

這對您意味著什么?

  • ACID on-board — all database operations are atomic, consistent, isolated, and durable.

    板載ACID —所有數據庫操作都是原子的,一致的,隔離的且持久的。
  • No need to manage an external database — everything is inside your application.

    無需管理外部數據庫-一切都在應用程序內部。
  • Painless refactorings — if you need to add a couple of properties you won’t have to then rebuild the tables.

    無痛重構–如果您需要添加幾個屬性,則無需重新構建表。
  • Cross-platform database — Xodus can run on any platform that can run a Java virtual machine.

    跨平臺數據庫-Xodus可以在可以運行Java虛擬機的任何平臺上運行。
  • Kotlin language benefits — take the best from using types, nullable values and delegates for properties declaration and constraints description.

    Kotlin語言的好處-充分利用類型,可空值和委托進行屬性聲明和約束描述。

Xodus is an open-source product from JetBrains. Originally it was developed for internal use, but it was subsequently released to the public back in July 2016. YouTrack issue tracker and Hub team tool use it as their data storage. If you are curious about the performance, you can check out the benchmarks. As for the real-life example, take a look at the JetBrains YouTrack installation: which at the time of writing has over 1,6 million issues, and that is not even taking into account all the comments and time tracking entries all stored there.

Xodus是JetBrains的開源產品。 它最初是為內部使用而開發的,但后來于2016年7月發布給公眾。YouTrack問題跟蹤程序和Hub團隊工具將其用作數據存儲。 如果您對性能感到好奇,可以查看基準測試 。 對于真實的示例,請看一下JetBrains YouTrack的安裝 :在撰寫本文時,它已發行了超過1,600萬個問題,并且甚至沒有考慮所有存儲在其中的注釋和時間跟蹤條目。

Xodus-DNQ is a Kotlin library that contains the data definition language and queries for Xodus. It was also developed first as a part of the product and then later released publicly. YouTrack and Hub both use it for persistent layer definition.

Xodus-DNQ是Kotlin庫,其中包含數據定義語言和Xodus查詢。 它也首先作為產品的一部分進行開發,然后再公開發布。 YouTrack和Hub都將其用于持久層定義。

建立 (Setup)

Let’s write a small application which stores books and their authors.

讓我們編寫一個存儲書及其作者的小應用程序。

I will use Gradle as a build tool, as it helps simplify all the dependencies management and project compilation stuff. If you have never worked with Gradle, I recommend taking a look at the official guides they have on installation and creating new builds.

我將Gradle用作構建工具,因為它有助于簡化所有依賴項管理和項目編譯的工作。 如果您從未使用過Gradle,建議您閱讀他們在安裝和創建新版本方面的官方指南。

So first, we need to start by creating a new directory for our example, and then run gradle init there. This will initialize the project structure and add some directories and build scripts.

因此,首先,我們需要為示例創建一個新目錄,然后在gradle init運行gradle init 。 這將初始化項目結構,并添加一些目錄和構建腳本。

Now, create a bookstore.kt file in src/main/kotlin directory. Fill it with the never-going-out-of-fashion classics:

現在,在src/main/kotlin目錄中創建一個bookstore.kt文件。 用永不過時的經典裝滿它:

fun main() {println("Hello World")
}

Then, update the build.gradle file using code similar to this:

然后,使用類似于以下代碼的代碼更新build.gradle文件:

plugins {id 'application'id 'org.jetbrains.kotlin.jvm' version '1.3.21'
}
group 'mariyadavydova'
version '1.0-SNAPSHOT'
sourceCompatibility = 1.8
targetCompatibility = 1.8
tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {kotlinOptions {jvmTarget = "1.8"}
}
repositories {mavenCentral()
}
dependencies {implementation 'org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.3.21'implementation 'org.jetbrains.xodus:dnq:1.2.420'
}
mainClassName = 'BookstoreKt'

There are a few things that are happening here:

這里發生了一些事情:

  1. We add the Kotlin plugin and claim that the compilation output is targeted for JVM 1.8.

    我們添加了Kotlin插件,并聲稱編譯輸出針對JVM 1.8。
  2. We add dependencies to the Kotlin standard library and Xodus-DNQ.

    我們向Kotlin標準庫和Xodus-DNQ添加依賴項。
  3. We also add the application plugin and define the main class. In the case of the Kotlin application, we do not have a class with a static method main, like in Java. Instead, we have to define a standalone function main. However, under the hood, Kotlin still makes a class containing this function, and the name of the class is generated from the name of the file. For example, ‘bookstore.kt’ makes ‘BookstoreKt’.

    我們還添加了應用程序插件并定義了主類。 在Kotlin應用程序的情況下,我們沒有像Java這樣的帶有靜態方法main的類。 相反,我們必須定義一個獨立的函數main 。 但是,在幕后,Kotlin仍然制作了一個包含此功能的類,并且該類的名稱是從文件名生成的。 例如, 'bookstore.kt'成為'BookstoreKt'

We can actually safely remove settings.gradle, as we don’t need it in this example.

實際上,我們可以安全地刪除settings.gradle ,因為在此示例中不需要它。

Now, execute ./gradlew run; you should see “Hello World” in your console:

現在,執行./gradlew run ; 您應該在控制臺中看到“ Hello World”:

> Task :run
Hello World

資料定義 (Data definition)

Xodus provides three different ways to deal with data, namely Environments, Entity Stores and the Virtual File System. However, Xodus-DNQ supports only the Entity Stores, which describe a data model as a set of typed entities with named properties (attributes) and named entity links (relations). It is similar to rows in the SQL database table.

Xodus提供了三種不同的數據處理方式,即環境 , 實體存儲和虛擬文件系統 。 但是,Xodus-DNQ僅支持實體存儲,它們將數據模型描述為一組具有命名屬性(屬性)和命名實體鏈接(關系)的類型化實體。 它類似于SQL數據庫表中的行。

As my goal is to demonstrate how simple it is to operate Xodus via Kotlin DSL, I’ll stick to the entity types API for this story.

因為我的目標是演示通過Kotlin DSL操作Xodus多么簡單,所以我將堅持本故事的實體類型API。

Let’s start with an XdAuthor:

讓我們從XdAuthor開始:

class XdAuthor(entity: Entity) : XdEntity(entity) {companion object : XdNaturalEntityType<XdAuthor>()
var name by xdRequiredStringProp()var countryOfBirth by xdStringProp()var yearOfBirth by xdRequiredIntProp()var yearOfDeath by xdNullableIntProp()val books by xdLink0_N(XdBook::authors)
}

From my point of view, this declaration looks pretty natural: we say that our authors always have names and year of birth, may have country of birth and year of death (the latter is irrelevant for the currently living authors); also, there could be any number of books from each author in our bookstore.

從我的角度來看,這種說法看起來很自然:我們說我們的作者總是有名字和出生年份,可能有出生國家和死亡年份(后者與當前在世的作者無關); 此外,我們書店中的每位作者都有多少本書籍。

There are several things worth mentioning in this code snippet:

此代碼段中有幾件事值得一提:

  • The companion object declares the entityType property for each class (which is used by the database engine).

    companion對象為每個類聲明entityType屬性(數據庫引擎使用該屬性)。

  • The data fields are declared with the help of the delegates, which encapsulate the types, properties, and constraints for these fields.

    數據字段是在委托的幫助下聲明的,這些委托封裝了這些字段的類型,屬性和約束。
  • Links are values, not variables; that is, you don’t set them with =, but access them as a collection. (Pay attention to val books versus var name; I spent quite a bit of time trying to figure out why the compilation with var books kept failing.)

    鏈接是值,而不是變量; 也就是說,您不必將其設置為= ,而是將其作為集合進行訪問。 (請注意val books而不是var name ;我花了很多時間試圖弄清楚為什么使用var books的編譯總是失敗。)

The second type is an XdBook:

第二種是XdBook

class XdBook(entity: Entity) : XdEntity(entity) {companion object : XdNaturalEntityType<XdBook>()
var title by xdRequiredStringProp()var year by xdNullableIntProp()val genres by xdLink1_N(XdGenre)val authors : XdMutableQuery<XdAuthor> by xdLink1_N(XdAuthor::books)
}

The thing to pay attention to here is the declaration of the authors’ field:

這里要注意的是authors字段的聲明:

  • Notice that we write down the type explicitly (XdMutableQuery<XdAuthor>). For the bidirectional link, we have to help the compiler to resolve the types by leaving a hint on one of the link ends.

    請注意,我們明確記錄了類型( XdMutableQuery<XdAuth或>)。 對于雙向鏈接,我們必須通過在鏈接端之一上留下提示來幫助編譯器解析類型。

  • Also, notice that XdAuthor::books references XdBook::authors and vice versa. We have to add these references if we want the link to be bidirectional; so if you add an author to the book, the book will appear in the list of the books of this author, and vice versa.

    另外,請注意XdAuthor::books引用了XdBook::authors ,反之亦然。 如果我們希望鏈接是雙向的,則必須添加這些引用。 因此,如果您將作者添加到書中,則該書將出現在該作者的書列表中,反之亦然。

The third entity type is an XdGenre enumeration, which is pretty trivial:

第三種實體類型是XdGenre枚舉,這很簡單:

class XdGenre(entity: Entity) : XdEnumEntity(entity) {companion object : XdEnumEntityType<XdGenre>() {val FANTASY by enumField {}val ROMANCE by enumField {}}
}

數據庫初始化 (Database initialization)

Now, when we have declared the entity types, we have to initialize the database:

現在,當我們聲明實體類型時,我們必須初始化數據庫:

fun initXodus(): TransientEntityStore {XdModel.registerNodes(XdAuthor,XdBook,XdGenre)val databaseHome = File(System.getProperty("user.home"), "bookstore")val store = StaticStoreContainer.init(dbFolder = databaseHome,environmentName = "db")initMetaData(XdModel.hierarchy, store)return store
}
fun main() {val store = initXodus()
}

This code shows the most basic setup:

此代碼顯示了最基本的設置:

  • We define the data model. Here we list all entity types manually, but it is possible to auto scan the classpath as well.

    我們定義數據模型。 在這里,我們手動列出了所有實體類型,但是也可以自動掃描類路徑 。

  • We initialize the database store in {user.home}/bookstore folder.

    我們在{user.home}/bookstore文件夾中初始化數據庫存儲。

  • We link the metadata with the store.

    我們將元數據與商店鏈接。

填寫數據 (Filling the data in)

Now that we have initialized the database, it’s time to put something inside. Before doing this, let’s add toString methods to our entity classes. Their only purpose is to allow us to output the database content in a human-readable format.

現在我們已經初始化了數據庫,是時候將一些東西放到里面了。 在執行此操作之前,讓我們將toString方法添加到我們的實體類中。 它們的唯一目的是允許我們以人類可讀的格式輸出數據庫內容。

class XdAuthor(entity: Entity) : XdEntity(entity) {...override fun toString(): String {val bibliography = books.asSequence().joinToString("\n")return "$name ($yearOfBirth-${yearOfDeath ?: "???"}):\n$bibliography"}
}
class XdBook(entity: Entity) : XdEntity(entity) {...override fun toString(): String {val genres = genres.asSequence().joinToString(", ")return "$title (${year ?: "Unknown"}) - $genres"}
}
class XdGenre(entity: Entity) : XdEnumEntity(entity) {...override fun toString(): String {return this.name.toLowerCase().capitalize()}
}

Notice books.asSequence().joinToString("\n") and genres.asSequence().joinToString(", ") instructions: here we use asSequence() method to convert an XdQuery to a Kotlin collection.

請注意books.asSequence().joinToString("\n")genres.asSequence().joinToString(", ")指令:在這里,我們使用asSequence()方法將XdQuery轉換為Kotlin集合。

Right, let’s now add several books from our collection inside the main function. All database operations (creating, reading, updating and removing entities) we do inside transactions — atomic database modifications, which guarantees to preserve the consistency.

正確,現在讓我們在主函數中添加我們收藏中的幾本書。 我們在事務內部執行所有數據庫操作(創建,讀取,更新和刪除實體)-原子數據庫修改,這保證了保持一致性。

In the case of our bookstore, there are plenty of ways to fill it with stuff:

就我們的書店而言,有很多方法可以填充其中的內容:

1. Add an author and a book separately:

1.分別添加作者和書籍:

val bronte = store.transactional {XdAuthor.new {name = "Charlotte Bront?"countryOfBirth = "England"yearOfBirth = 1816yearOfDeath = 1855} }store.transactional {XdBook.new {title = "Jane Eyre"year = 1847genres.add(XdGenre.ROMANCE)authors.add(bronte)}}

2. Add an author and put several books in their list:

2.添加一位作者,并在列表中放入幾本書:

val tolkien = store.transactional {XdAuthor.new {name = "J. R. R. Tolkien"countryOfBirth = "England"yearOfBirth = 1892yearOfDeath = 1973}}store.transactional {tolkien.books.add(XdBook.new {title = "The Hobbit"year = 1937genres.add(XdGenre.FANTASY)})tolkien.books.add(XdBook.new {title = "The Lord of the Rings"year = 1955genres.add(XdGenre.FANTASY)})}

3. Add an author with books:

3.為作者添加書籍:

store.transactional {XdAuthor.new {name = "George R. R. Martin"countryOfBirth = "USA"yearOfBirth = 1948books.add(XdBook.new {title = "A Game of Thrones"year = 1996genres.add(XdGenre.FANTASY)})}}

To check that everything is created, all we need to do is to print the content of our database:

要檢查所有內容是否已創建,我們所需要做的就是打印數據庫的內容:

store.transactional(readonly = true) {     println(XdAuthor.all().asSequence().joinToString("\n***\n"))}

Now, if you execute ./gradlew run, you should see the following output:

現在,如果執行./gradlew run ,應該會看到以下輸出:

Charlotte Bront? (1816-1855):
Jane Eyre (1847) - Romance
***
J. R. R. Tolkien (1892-1973):
The Hobbit (1937) - Fantasy
The Lord of the Rings (1955) - Fantasy
***
George R. R. Martin (1948-???):
A Game of Thrones (1996) - Fantasy

約束條件 (Constraints)

As mentioned, the transactions guarantee data consistency. One of the operations which Xodus does before saving the changes is checking the constraints. In the DNQ, some of them are encoded in the name of the delegate which provides a property of a given type. For example, xdRequiredIntProp has to always be set to some value, whereas xdNullableIntProp can remain empty.

如前所述,事務保證了數據的一致性。 Xodus在保存更改之前所做的一項操作是檢查約束。 在DNQ中,其中一些編碼為委托人的名稱,該委托人提供給定類型的屬性。 例如, xdRequiredIntProp必須始終設置為某個值,而xdNullableIntProp可以保持為空。

Despite this, Xodus-DNQ allows defining more complex constraints which are described in the official documentation. I have added several examples to the XdAuthor entity type:

盡管如此,Xodus-DNQ允許定義更復雜的約束,這些約束在官方文檔中進行了介紹 。 我向XdAuthor實體類型添加了幾個示例:

var name by xdRequiredStringProp { containsNone("?!") }var country by xdStringProp {length(min = 3, max = 56)regex(Regex("[A-Za-z.,]+"))}var yearOfBirth by xdRequiredIntProp { max(2019) }var yearOfDeath by xdNullableIntProp { max(2019) }

You may be wondering why I have limited the countryOfBirth property length to 56 characters. Well, the longest official country name which I found is “The United Kingdom of Great Britain and Northern Ireland” — precisely 56 characters!

您可能想知道為什么我將countryOfBirth屬性的長度限制為56個字符。 好吧,我發現的最長的官方國家名稱是“大不列顛及北愛爾蘭聯合王國”,正好是56個字符!

查詢 (Queries)

We have already used database queries above. Do you remember? We printed the list of authors using XdAuthor.all().asSequence(). As you may guess, the all() method returns all the entries of a given entity type.

上面我們已經使用過數據庫查詢。 你還記得嗎? 我們使用XdAuthor.all().asSequence()打印了作者列表。 您可能會猜到, all()方法返回給定實體類型的所有條目。

More often than not though, we will prefer filtering data. Here are some examples:

通常,我們會更喜歡過濾數據。 這里有些例子:

store.transactional(readonly = true) {val fantasyBooks = XdBook.filter { it.genres contains XdGenre.FANTASY }val booksOf20thCentury = XdBook.filter { (it.year ge 1900) and (it.year lt 1999) }val authorsFromEngland = XdAuthor.filter { it.countryOfBirth eq "England" }val booksSortedByYear = XdBook.all().sortedBy(XdBook::year)val allGenres = XdBook.all().flatMapDistinct(XdBook::genres)
}

Again, there are plenty of options for building data queries, so I strongly recommend taking a look at the documentation.

同樣,構建數據查詢有很多選擇,因此我強烈建議您閱讀文檔 。

I hope this story is as useful for you as it was for me when I wrote it :) Any feedback is highly appreciated!

我希望這個故事對您和我寫這篇文章時一樣有用:)任何反饋都非常感謝!

You can find the source code for this tutorial here.

您可以在此處找到本教程的源代碼 。

翻譯自: https://www.freecodecamp.org/news/how-to-use-the-xodus-database-in-kotlin-applications-3f899896b9df/

kotlin數據庫

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/391786.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/391786.shtml
英文地址,請注明出處:http://en.pswp.cn/news/391786.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

使用route add添加路由,使兩個網卡同時訪問內外網

route add命令格式&#xff1a;route [-f] [-p] [Command] [Destination] [mask Netmask] [Gateway] [metric Metric] [if Interface] 通過配置電腦的靜態路由來實現同時訪問內外網的。電腦的網絡IP配置不用變&#xff0c;兩個網卡都按照正常配置&#xff08;都配置IP地址、子網…

基于JavaConfig配置的Spring MVC的構建

上一篇講了基于XML配置的構建&#xff0c;這一篇講一講基于JavaConfig的構建。為什么要寫這篇文章&#xff0c;因為基于xml配置的構建&#xff0c;本人認為很麻煩&#xff0c;要寫一堆的配置&#xff0c;不夠簡潔&#xff0c;而基于JavacConfig配置的構建符合程序員的編碼習慣&…

pymc3 貝葉斯線性回歸_使用PyMC3進行貝葉斯媒體混合建模,帶來樂趣和收益

pymc3 貝葉斯線性回歸Michael Johns, Zhenyu Wang, Bruno Dupont, and Luca Fiaschi邁克爾約翰斯&#xff0c;王振宇&#xff0c;布魯諾杜邦和盧卡菲亞斯基 “If you can’t measure it, you can’t manage it, or fix it”“如果無法衡量&#xff0c;就無法管理或修復它” –…

webkit中對incomplete type指針的處理技巧

近日在研究webkit的時候發現了一個函數 template<typename T> inline void deleteOwnedPtr(T* ptr) {typedef char known[sizeof(T) ? 1 : -1];if(sizeof(known))delete ptr; } 一開始對這個函數非常費解&#xff0c;為什么作者不直接 delete ptr; 通過上stackoverflow提…

leetcode 1004. 最大連續1的個數 III(滑動窗口)

給定一個由若干 0 和 1 組成的數組 A&#xff0c;我們最多可以將 K 個值從 0 變成 1 。 返回僅包含 1 的最長&#xff08;連續&#xff09;子數組的長度。 示例 1&#xff1a; 輸入&#xff1a;A [1,1,1,0,0,0,1,1,1,1,0], K 2 輸出&#xff1a;6 解釋&#xff1a; [1,1,1…

我如何找到工作并找到理想的工作

By Julius Zerwick朱利葉斯澤威克(Julius Zerwick) This article is about how I went through my job hunt for a full time position as a software engineer in New York City and ended up with my dream job. I had spent two years building my skills and had aspirati…

synchronized 與 Lock 的那點事

synchronized 與 Lock 的那點事 最近在做一個監控系統&#xff0c;該系統主要包括對數據實時分析和存儲兩個部分&#xff0c;由于并發量比較高&#xff0c;所以不可避免的使用到了一些并發的知識。為了實現這些要求&#xff0c;后臺使用一個隊列作為緩存&#xff0c;對于請求只…

ols線性回歸_普通最小二乘[OLS]方法使用于機器學習的簡單線性回歸變得容易

ols線性回歸Hello Everyone!大家好&#xff01; I am super excited to be writing another article after a long time since my previous article was published.自從上一篇文章發表很長時間以來&#xff0c;我很高興能寫另一篇文章。 A Simple Linear Regression [SLR] is…

ubuntu安裝配置jdk

先去 Oracle下載Linux下的JDK壓縮包&#xff0c;我下載的是jdk-7u4-linux-i586.tar.gz文件&#xff0c;下好后直接解壓Step1:# 將解壓好的jdk1.7.0_04文件夾用最高權限復制到/usr/lib/jvm目錄里sudo cp -r ~/jdk1.7.0_04/ /usr/lib/jvm/Step2:# 配置環境變量sudo gedit ~/.prof…

leetcode 697. 數組的度(hashmap)

給定一個非空且只包含非負數的整數數組 nums&#xff0c;數組的度的定義是指數組里任一元素出現頻數的最大值。 你的任務是在 nums 中找到與 nums 擁有相同大小的度的最短連續子數組&#xff0c;返回其長度。 示例 1&#xff1a; 輸入&#xff1a;[1, 2, 2, 3, 1] 輸出&…

facebook機器學習_如何為您的頁面創建Facebook Messenger機器人

facebook機器學習by Paul Pinard保羅皮納德(Paul Pinard) 如何為您的頁面創建Facebook Messenger機器人 (How to create a Facebook messenger bot for your page) When it comes to sharing your chatbot, Facebook Messenger is a must. We created a very easy step-by-ste…

Logstash配置語法及相關命令

配置結構以及插件位置 輸入插件&#xff1a; input{ … } 過濾插件&#xff1a; filter{ … } 輸出插件&#xff1a; output{ … } 數據類型 - Array users > [{id > 1,name > N1},{id > 2,name > N2}] - lists path > ["/var/log/messages"…

面試整理

SpringMVC 和Struts2的區別 1. 機制&#xff1a; spring mvc的入口是servlet&#xff0c;而struts2是filter&#xff0c;這樣就導致了二者的機制不同。 2. 性能&#xff1a; spring會稍微比struts快。spring mvc是基于方法的設計&#xff0c;而sturts 是基于類&#xff0c;…

Amazon Personalize:幫助釋放精益數字業務的高級推薦解決方案的功能

By Gerd Wittchen蓋德維琴 推薦解決方案的動機 (Motivation for recommendation solutions) Rapid changes in customer behaviour requires businesses to adapt at an ever increasing pace. The recent changes to our work and personal life has forced entire nations t…

Linux 鏈接文件講解

鏈接文件是Linux文件系統的一個優勢。如需要在系統上維護同一文件的兩份或者多份副本&#xff0c;除了保存多份單獨的物理文件之外&#xff0c;可以采用保留一份物理文件副本和多個虛擬副本的方式&#xff0c;這種虛擬的副本就成為鏈接。鏈接是目錄中指向文件真實位置的占位符。…

系統滾動條實現的NUD控件Unusable版

昨天研究了一下系統滾動條&#xff0c;準備使用它來實現一個NumericUpDown控件&#xff0c;因為它可以帶來最正宗的微調按鈕外觀&#xff0c;并說了一下可以使用viewport里的onScroll事件來獲取系統滾動條的上下點擊動作。 同時昨天還說了onScroll事件的一個問題是&#xf…

react 中渲染html_如何在React中識別和解決浪費的渲染

react 中渲染htmlby Nayeem Reza通過Nayeem Reza 如何在React中識別和解決浪費的渲染 (How to identify and resolve wasted renders in React) So, recently I was thinking about performance profiling of a react app that I was working on, and suddenly thought to set…

php變量的數據類型

一、類型 標量類型: 布爾型 整型 浮點型 字符串 復合類型: 數組 對象 特殊類型: 資源 null 1. 布爾型 true false 以下值認為是false 其他值都認為是true; 布爾值false 整型值0 浮點的0 空字符串和字符串0 空數組 空對象(只適用于php4) 特殊類型null 2. 整型 正整數和負整…

[習題].FindControl()方法 與 PlaceHolder控件 #2(動態加入「子控件」的事件)

這是我的文章備份&#xff0c;有空請到我的網站走走&#xff0c; http://www.dotblogs.com.tw/mis2000lab/ 才能掌握我提供的第一手信息&#xff0c;謝謝您。 http://www.dotblogs.com.tw/mis2000lab/archive/2011/07/26/placeholder_findcontrol_eventhandler.aspx [習題].Fi…

西雅圖治安_數據科學家對西雅圖住宿業務的分析

西雅圖治安介紹 (Introduction) Airbnb provides an online platform for hosts to accommodate guests with short-term lodging. Guests can search for lodging using filters such as lodging type, dates, location, and price, and can search for specific types of hom…