网页制作与网站建设填空题开发一个游戏软件需要多少钱
web/
2025/10/9 0:54:00/
文章来源:
网页制作与网站建设填空题,开发一个游戏软件需要多少钱,官网网站搭建,树莓派搭建wordpress卡不卡首先#xff0c;免责声明#xff1a;如果您正在编写微服务 #xff08;每个人现在都对吗#xff1f;#xff09;并希望它是惯用的 #xff0c;那么通常不会在其中使用几个不同的数据源。 图片取自Pixabay https: //pixabay.com/illustrations/software-binary-sys… 首先免责声明如果您正在编写微服务 每个人现在都对吗并希望它是惯用的 那么通常不会在其中使用几个不同的数据源。 图片取自Pixabay© https: //pixabay.com/illustrations/software-binary-system-1-0-binary-557616/ 为什么 好吧按照定义微服务应该松散耦合以便它们可以独立。 将多个微服务写入同一个数据库确实违反了这一原则因为这意味着您的数据可以由几个独立的参与者以可能以不同的方式进行更改 这使得谈论数据一致性确实非常困难而且您很难说这些服务是独立的因为它们至少具有它们共同依赖的一件事共享并且可能是固定的数据。 因此有一种称为数据库每个服务的设计模式旨在通过对每个数据库实施一个服务来解决此问题。 这意味着每个微服务都充当客户端与其数据源之间的中介并且只能通过该服务提供的接口来更改数据 。 但是每个数据库一项服务等于一个服务一项数据库吗 不不是。 如果您考虑一下那并不是一回事。 这意味着如果我们有几个只能由一个微服务访问的数据库并且通过该服务的接口实现了对这些数据库的任何外部访问那么仍然可以认为该服务是惯用的。 它仍然是每个数据库一项服务尽管不是每个服务一项数据库。 另外也许您根本不关心微服务的惯用性。 这也是一个选择。 不过这将取决于您的良心。 那么何时会有几个数据库要从同一服务访问 我可以想到不同的选择 数据太大无法存放在一个数据库中。 您将数据库用作命名空间以仅分隔属于不同域或功能区域的不同数据。 您需要对数据库的不同访问权限-也许其中一个是关键任务因此您将其置于各种安全层的后面而另一个则不是那么重要也不需要这种保护。 这些数据库位于不同的区域因为它们是由不同地方的人写入的但需要从中央位置读取反之亦然 真的所有其他一切都导致了这种情况您只需要忍受它。 如果您的应用程序是Spring Boot应用程序并且您将Mongo用作数据库那么最简单的方法就是使用Spring Data Repositories 。 您只需为mongo入门数据设置依赖项我们将在此处以Gradle项目为例。 dependencies {implementation(org.springframework.boot:spring-boot-starter-data-mongodb)implementation(org.springframework.boot:spring-boot-starter-web)implementation(com.fasterxml.jackson.module:jackson-module-kotlin)implementation(org.jetbrains.kotlin:kotlin-reflect)implementation(org.jetbrains.kotlin:kotlin-stdlib-jdk8)annotationProcessor(org.springframework.boot:spring-boot-configuration-processor)testImplementation(org.springframework.boot:spring-boot-starter-test)
} 实际上我们是使用Spring Initializer生成此示例项目的因为这是开始基于Spring的新示例的最简单方法。 我们刚刚在生成器设置中选择了Kotlin和Gradle并添加了Spring Web Starter和Spring Data MongoDB作为依赖项。 我们称这个项目为multimongo。 当我们创建一个项目并下载源代码时我们可以看到Spring默认情况下创建了一个application.properties文件。 我更喜欢yaml 所以我们将其重命名为application.yml并完成它。 所以。 我们如何使用Spring Data设置对默认mongo数据库的访问权限 没什么容易的。 这就是application.yml 。 # possible MongoProperties
# spring.data.mongodb.authentication-database # Authentication database name.
# spring.data.mongodb.database # Database name.
# spring.data.mongodb.field-naming-strategy # Fully qualified name of the FieldNamingStrategy to use.
# spring.data.mongodb.grid-fs-database # GridFS database name.
# spring.data.mongodb.host # Mongo server host. Cannot be set with URI.
# spring.data.mongodb.password # Login password of the mongo server. Cannot be set with URI.
# spring.data.mongodb.port # Mongo server port. Cannot be set with URI.
# spring.data.mongodb.repositories.typeauto # Type of Mongo repositories to enable.
# spring.data.mongodb.urimongodb://localhost/test # Mongo database URI. Cannot be set with host, port and credentials.
# spring.data.mongodb.username # Login user of the mongo server. Cannot be set with URI.spring:data:mongodb:uri: mongodb://localhost:27017database: multimongo-core 现在让我们想象一下一个非常简单而愚蠢的数据拆分案例。 假设我们有一个core数据库用于存储我们的网上商店的产品。 然后我们获得了有关产品价格的数据 此数据不需要任何访问限制因为网络上的任何用户都可以看到价格因此我们将其称为external 。 但是我们还有价格历史记录可用于分析目的。 这是有限的访问信息所以我们说好的它进入一个单独的数据库我们将对其进行保护并调用internal 。 显然就我而言所有这些都仍在localhost上并且不受保护但是请允许我这只是一个示例。 # Predefined spring data properties dont help us anymore.
# Therefore, were creating our own configuration for the additional mongo instances.additional-db:internal:uri: mongodb://localhost:27017database: multimongo-internalexternal:uri: mongodb://localhost:27017database: multimongo-external 我们还将创建三个不同的目录以将与数据访问相关的代码保留在其中 data.core data.external和data.internal 。 我们的Product.kt保留产品的实体和存储库 ProductPrice.kt和ProductPriceHistory.kt代表产品的当前价格和历史价格。 实体和存储库非常基础。 Document
data class Product(Idval id: String? null,val sku: String,val name: String
)interface ProductRepository : MongoRepositoryProduct, StringDocument(collection productPrice)
data class ProductPrice(Idval id: String? null,val sku: String,val price: Double
)interface ProductPriceRepository : MongoRepositoryProductPrice, StringDocument(collection priceHistory)
data class PriceHistory(Idval id: String? null,val sku: String,val prices: MutableListPriceEntry mutableListOf()
)data class PriceEntry(val price: Double,val expired: Date? null
)interface PriceHistoryRepository : MongoRepositoryPriceHistory, String 现在让我们为default mongo创建配置。 Configuration
EnableMongoRepositories(basePackages [com.example.multimongo.data.core])
Import(value [MongoAutoConfiguration::class])
class CoreMongoConfiguration {Beanfun mongoTemplate(mongoDbFactory: MongoDbFactory): MongoTemplate {return MongoTemplate(mongoDbFactory)}
} 我们在这里使用MongoAutoConfiguration类创建默认的mongo客户端实例。 但是我们仍然需要一个明确定义的MongoTemplate bean。 如您所见 core配置仅扫描core目录。 这实际上是一切的关键我们需要将我们的存储库放在不同的目录中并且这些存储库将由不同的mongo模板进行扫描。 因此让我们创建那些附加的mongo模板。 我们将使用一个基类该基类将保留一些共享功能我们将重复使用这些功能来创建mongo客户端。 Configuration
class ExtraMongoConfiguration {val uri: String? nullval host: String? nullval port: Int? 0val database: String? null/*** Method that creates MongoClient*/private val mongoClient: MongoClientget() {if (uri ! null !uri.isNullOrEmpty()) {return MongoClient(MongoClientURI(uri!!))}return MongoClient(host!!, port!!)}/*** Factory method to create the MongoTemplate*/protected fun mongoTemplate(): MongoTemplate {val factory SimpleMongoDbFactory(mongoClient, database!!)return MongoTemplate(factory)}
} 然后最后我们创建两个配置以容纳external和internal数据库的mongo模板实例。 EnableMongoRepositories(basePackages [com.example.multimongo.data.external],mongoTemplateRef externalMongoTemplate)
Configuration
class ExternalDatabaseConfiguration : ExtraMongoConfiguration() {Value(\${additional-db.external.uri:})override val uri: String? nullValue(\${additional-db.external.host:})override val host: String? nullValue(\${additional-db.external.port:0})override val port: Int? 0Value(\${additional-db.external.database:})override val database: String? nullBean(externalMongoTemplate)fun externalMongoTemplate(): MongoTemplate mongoTemplate()
}EnableMongoRepositories(basePackages [com.example.multimongo.data.internal],mongoTemplateRef internalMongoTemplate)
Configuration
class InternalDatabaseConfiguration : ExtraMongoConfiguration() {Value(\${additional-db.internal.uri:})override val uri: String? nullValue(\${additional-db.internal.host:})override val host: String? nullValue(\${additional-db.internal.port:0})override val port: Int? 0Value(\${additional-db.internal.database:})override val database: String? nullBean(internalMongoTemplate)fun internalMongoTemplate(): MongoTemplate mongoTemplate()
} 因此我们现在有三个mongo模板bean它们由mongoTemplate() externalMongoTemplate()和internalMongoTemplate()在三种不同的配置中创建。 这些配置扫描不同的目录并通过EnableMongoRepositories批注中的直接引用使用这些不同的mongo模板EnableMongoRepositories这意味着它们将使用创建的bean。 春天没有问题。 依存关系将以正确的顺序解决。 那么我们如何检查一切正常 还有一个步骤需要完成我们需要初始化一些数据然后从数据库中获取数据。 由于这只是一个示例因此我们将在应用程序启动时立即创建一些非常基本的数据以确保它们在那里。 我们将为此使用ApplicationListener 。 Component
class DataInitializer(val productRepo: ProductRepository,val priceRepo: ProductPriceRepository,val priceHistoryRepo: PriceHistoryRepository
) : ApplicationListenerContextStartedEvent {override fun onApplicationEvent(event: ContextStartedEvent) {// clean upproductRepo.deleteAll()priceRepo.deleteAll()priceHistoryRepo.deleteAll()val p1 productRepo.save(Product(sku 123, name Toy Horse))val p2 productRepo.save(Product(sku 456, name Real Horse))val h1 PriceHistory(sku p1.sku)val h2 PriceHistory(sku p2.sku)for (i in 5 downTo 1) {if (i 5) {// current pricepriceRepo.save(ProductPrice(sku p1.sku, price i.toDouble()))priceRepo.save(ProductPrice(sku p2.sku, price (i * 2).toDouble()))// current price historyh1.prices.add(PriceEntry(price i.toDouble()))h2.prices.add(PriceEntry(price (i * 2).toDouble()))} else {// previous priceval expiredDate Date(ZonedDateTime.now().minusMonths(i.toLong()).toInstant().toEpochMilli())h1.prices.add(PriceEntry(price i.toDouble(), expired expiredDate))h2.prices.add(PriceEntry(price (i * 2).toDouble(), expired expiredDate))}}priceHistoryRepo.saveAll(listOf(h1, h2))}
} 我们如何检查数据是否已保存到数据库 由于它是一个Web应用程序因此我们将在REST控制器中公开数据。 RestController
RequestMapping(/api)
class ProductResource(val productRepo: ProductRepository,val priceRepo: ProductPriceRepository,val priceHistoryRepo: PriceHistoryRepository
) {GetMapping(/product)fun getProducts(): ListProduct productRepo.findAll()GetMapping(/price)fun getPrices(): ListProductPrice priceRepo.findAll()GetMapping(/priceHistory)fun getPricesHistory(): ListPriceHistory priceHistoryRepo.findAll()
} REST控制器只是使用我们的存储库来调用findAll()方法。 我们没有对数据转换做任何事情我们没有分页或排序我们只是想看看有什么东西。 最后可以启动应用程序然后看看会发生什么。 [{id: 5d5e64d80a986d381a8af4ce,name: Toy Horse,sku: 123},{id: 5d5e64d80a986d381a8af4cf,name: Real Horse,sku: 456}
] 是的我们创建了两个产品 我们可以看到Mongo在保存时为其分配了自动生成的ID我们仅定义了名称和伪SKU代码。 我们还可以在http// localhost8080 / api / price和http// localhost8080 / api / priceHistory上检查数据 并确保是的实际上这些实体也确实已创建。 我不会在此处粘贴此JSON因为它并不相关。 但是我们如何确保数据确实已保存到其他数据库或从中读取 为此我们可以使用任何允许我们连接到本地mongo实例的mongo客户端应用程序我正在使用mongo的官方工具-MongoDB Compass 。 让我们检查保持当前价格的数据库中的内容。 如果我们想做对的事情实际上不是所有的事我们也可以使用集成测试来检查数据而不是手动处理实际上不是所有的事情我们需要使用嵌入式mongo数据库进行测试但是这里我们将跳过这一部分不会使教程太复杂。 为此 我们将利用spring-test库中的MockMvc 。 RunWith(SpringRunner::class)
SpringBootTest
class MultimongoApplicationTests {Autowiredprivate val productRepo: ProductRepository? nullAutowiredprivate val priceRepo: ProductPriceRepository? nullAutowiredprivate val priceHistoryRepo: PriceHistoryRepository? nullAutowiredprivate val initializer: DataInitializer? nullAutowiredprivate val context: ApplicationContext? nullprivate var mvc: MockMvc? nullBeforefun setUp() {val resource ProductResource(productRepo!!,priceRepo!!,priceHistoryRepo!!)this.mvc MockMvcBuilders.standaloneSetup(resource).build()initializer!!.onApplicationEvent(ContextStartedEvent(context!!))}Testfun productsCreated() {mvc!!.perform(get(“/api/product”)).andExpect(status().isOk).andDo {println(it.response.contentAsString)}.andExpect(jsonPath(“$.[*].sku”).isArray).andExpect(jsonPath(“$.[*].sku”).value(hasItems(“123”, “456”)))}Testfun pricesCreated() {mvc!!.perform(get(“/api/price”)).andExpect(status().isOk).andDo {println(it.response.contentAsString)}.andExpect(jsonPath(“$.[*].sku”).isArray).andExpect(jsonPath(“$.[*].sku”).value(hasItems(“123”, “456”))).andExpect(jsonPath(“$.[0].price”).value(5.0)).andExpect(jsonPath(“$.[1].price”).value(10.0))}Testfun pricesHistoryCreated() {mvc!!.perform(get(“/api/priceHistory”)).andExpect(status().isOk).andDo {println(it.response.contentAsString)}.andExpect(jsonPath(“$.[*].sku”).isArray).andExpect(jsonPath(“$.[*].sku”).value(hasItems(“123”, “456”))).andExpect(jsonPath(“$.[0].prices.[*].price”).value(hasItems(5.0, 4.0, 3.0, 2.0, 1.0))).andExpect(jsonPath(“$.[1].prices.[*].price”).value(hasItems(10.0, 8.0, 6.0, 4.0, 2.0)))}
} 你可以找到完整的工作示例这里在我的github回购。 希望这可以帮助您解决在一个Spring Boot Web应用程序中使用多个mongo实例的问题 这不是一个难题但也不是一件容易的事。 当我在网上查看其他示例时我还阅读了这篇文章 Azadi Bogolubov 撰写的 “ Spring Data ConfigurationMultiple Mongo Databases” 它相当不错而且很全面。 但是它不太适合我的情况因为它完全覆盖了自动mongo配置。 另一方面我仍然希望将其保留在我的默认数据库中而不是其他数据库。 但是该文章中的方法基于相同的原理即使用不同的mongo模板扫描不同的存储库 。 只是使用默认配置例如一旦发生某些更改并且所有数据再次进入同一数据库您就可以轻松摆脱多余的类。 然后您可以轻松清除非默认配置但仍保留默认配置仅更改其扫描范围。 该应用程序仍将继续正常运行。 但是这两种方式都是完全有效的 。 本文也在此处的 Medium中发布。 翻译自: https://www.javacodegeeks.com/2019/09/spring-application-multiple-mongo-repositories-kotlin.html
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/89353.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!