Verite an premye, oswa poukisa yon sistèm bezwen yo dwe fèt ki baze sou konsepsyon baz done a

Hey Habr!

Nou kontinye fè rechèch sou sijè a Java и Prentan, ki gen ladan nan nivo baz done a. Jodi a nou envite w li sou poukisa, lè w ap desine gwo aplikasyon, se estrikti baz done a, e pa kòd Java a, ki ta dwe gen yon enpòtans desizif, ki jan sa fèt, ak ki eksepsyon ki genyen nan règ sa a.

Nan atik sa a byen ta, mwen pral eksplike poukisa mwen kwè ke nan prèske tout ka yo, modèl done nan yon aplikasyon yo ta dwe fèt "apati baz done a" olye ke "nan kapasite yo nan Java" (oswa kèlkeswa lang kliyan ou ye). travay avèk). Lè w pran dezyèm apwòch la, w ap mete tèt ou kanpe pou yon chemen long nan doulè ak soufrans yon fwa pwojè ou a kòmanse grandi.

Atik la te ekri baze sou yon kesyon, yo bay sou Stack Debòde.

Diskisyon enteresan sou reddit nan seksyon /r/java и / r / pwogramasyon.

Kòd jenerasyon

Ki jan m te etone ke gen yon ti segman itilizatè yo ki, yo te vin konnen jOOQ, yo imilye pa lefèt ke jOOQ seryezman depann sou jenerasyon kòd sous yo opere. Pa gen moun ki anpeche w sèvi ak jOOQ jan w panse a apwopriye, oswa pa fòse w sèvi ak jenerasyon kòd. Men, fason default (jan sa dekri nan manyèl la) travay ak jOOQ se ke ou kòmanse ak yon chema baz done (eritaj), enjenyè li lè l sèvi avèk dèlko kòd jOOQ la pou w ka jwenn yon seri klas ki reprezante tab ou yo, epi ekri tip. -rekèt san danje nan tab sa yo:

	for (Record2<String, String> record : DSL.using(configuration)
//   ^^^^^^^^^^^^^^^^^^^^^^^ Информация о типах выведена на 
//   основании сгенерированного кода, на который ссылается приведенное
// ниже условие SELECT 
 
       .select(ACTOR.FIRST_NAME, ACTOR.LAST_NAME)
//           vvvvv ^^^^^^^^^^^^  ^^^^^^^^^^^^^^^ сгенерированные имена
       .from(ACTOR)
       .orderBy(1, 2)) {
    // ...
}

Kòd la pwodwi swa manyèlman deyò asanble a, oswa manyèlman nan chak asanble. Pou egzanp, rejenerasyon sa yo ka swiv imedyatman apre Migrasyon baz done Flyway, ki ka fè tou manyèlman oswa otomatikman.

Jenerasyon kòd sous

Gen plizyè filozofi, avantaj ak dezavantaj ki asosye ak apwòch sa yo nan jenerasyon kòd - manyèl ak otomatik - ke mwen pa pral diskite an detay nan atik sa a. Men, an jeneral, pwen an antye nan kòd la pwodwi a se ke li pèmèt nou repwodui nan Java "verite" ke nou pran pou akòde, swa nan sistèm nou an oswa deyò li. Nan yon sans, sa a se sa konpilateur yo fè lè yo jenere bytecode, kòd machin, oswa kèk lòt fòm kòd sous - nou jwenn yon reprezantasyon nan "verite" nou an nan yon lòt lang, kèlkeswa rezon espesifik yo.

Gen anpil jeneratè kòd sa yo. Pa egzanp, XJC ka jenere kòd Java ki baze sou dosye XSD oswa WSDL. Prensip la toujou menm:

  • Gen kèk verite (entèn oswa ekstèn) - pou egzanp, yon spesifikasyon, yon modèl done, elatriye.
  • Nou bezwen yon reprezantasyon lokal verite sa a nan lang pwogramasyon nou an.

Anplis, li se prèske toujou rekòmande jenere tankou yon reprezantasyon yo nan lòd pou fè pou evite èkse.

Kalite Founisè ak Pwosesis Anòt

Remak: yon lòt apwòch ki pi modèn ak espesifik pou jenere kòd pou jOOQ ap itilize founisè kalite, jan yo aplike nan F#. Nan ka sa a, se kòd la ki te pwodwi pa du a, aktyèlman nan etap konpilasyon an. Nan prensip, kòd sa a pa egziste nan fòm sous. Java gen zouti menm jan an, byenke pa tankou elegant, - processeurs anotasyon, pou egzanp, Lombok.

Nan yon sans, menm bagay sa yo rive isit la tankou nan premye ka a, ak eksepsyon de:

  • Ou pa wè kòd la pwodwi (petèt sitiyasyon sa a sanble mwens repouse yon moun?)
  • Ou dwe asire ke kalite yo ka bay, sa vle di, "vre" dwe toujou disponib. Sa a se fasil nan ka a nan Lombok, ki anote "verite". Li se yon ti kras pi konplike ak modèl baz done ki depann sou yon koneksyon ap toujou disponib.

Ki pwoblèm ki genyen ak jenerasyon kòd?

Anplis de sa nan kesyon an difisil nan ki jan pi bon yo kouri jenerasyon kòd - manyèlman oswa otomatikman, nou menm tou nou dwe mansyone ke gen moun ki kwè ke jenerasyon kòd pa nesesè ditou. Jistifikasyon pou pwennvi sa a, ki mwen te rankontre pi souvan, se ke li se Lè sa a, difisil yo mete kanpe yon pipeline bati. Wi, li vrèman difisil. Lòt depans enfrastrikti rive. Si w ap kòmanse kòmanse ak yon pwodwi patikilye (si se jOOQ, oswa JAXB, oswa Hibernate, elatriye), mete yon anviwònman pwodiksyon pran tan ke ou ta pito pase aprann API nan tèt li pou ou ka ekstrè valè nan li. .

Si depans ki asosye ak konpreyansyon estrikti dèlko a twò wo, Lè sa a, tout bon, API a te fè yon travay pòv sou itilizasyon dèlko kòd la (e pita li sanble ke personnalisation itilizatè nan li se tou konplèks). Itilizasyon ta dwe pi gwo priyorite pou nenpòt API sa yo. Men, sa a se jis youn agiman kont jenerasyon kòd. Sinon, li se absoliman totalman manyèl yo ekri yon reprezantasyon lokal nan verite entèn oswa ekstèn.

Anpil moun pral di ke yo pa gen tan fè tout bagay sa yo. Yo ap kouri soti nan dat limit pou Super Product yo. Yon jou nou pral ranje transporteur asanble yo, nou pral gen tan. Mwen pral reponn yo:

Verite an premye, oswa poukisa yon sistèm bezwen yo dwe fèt ki baze sou konsepsyon baz done a
Original, Alan O'Rourke, Stack Odyans

Men, nan Hibernate/JPA li tèlman fasil pou ekri kòd Java.

Vrèman. Pou Hibernate ak itilizatè li yo, sa a se tou de yon benediksyon ak yon madichon. Nan Hibernate ou ka senpleman ekri yon koup nan antite, tankou sa a:

	@Entity
class Book {
  @Id
  int id;
  String title;
}

Ak prèske tout bagay pare. Koulye a, li se jiska Hibernate jenere "detay yo" konplèks sou ki jan egzakteman antite sa a pral defini nan DDL nan "dyalèk" SQL ou a:

	CREATE TABLE book (
  id INTEGER PRIMARY KEY GENERATED ALWAYS AS IDENTITY,
  title VARCHAR(50),
 
  CONSTRAINT pk_book PRIMARY KEY (id)
);
 
CREATE INDEX i_book_title ON book (title);

... epi kòmanse kouri aplikasyon an. Yon opòtinite vrèman fre pou kòmanse byen vit epi eseye diferan bagay.

Sepandan, tanpri pèmèt mwen. Mwen te bay manti.

  • Èske Hibernate aktyèlman aplike definisyon kle prensipal sa a?
  • Èske Hibernate kreye yon endèks nan TITLE? – Mwen konnen pou asire w ke nou pral bezwen li.
  • Èske Hibernate egzakteman fè idantifye kle sa a nan spesifikasyon idantite a?

Pwobableman pa. Si w ap devlope pwojè ou a nan grafouyen, li toujou pratik tou senpleman jete ansyen baz done a epi jenere yon nouvo le pli vit ke ou ajoute annotasyon ki nesesè yo. Kidonk, antite Liv la pral finalman pran fòm sa a:

	@Entity
@Table(name = "book", indexes = {
  @Index(name = "i_book_title", columnList = "title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
  String title;
}

Cool. Rejenere. Ankò, nan ka sa a li pral trè fasil nan kòmansman an.

Men, ou pral oblije peye pou li pita

Pi bonè oswa pita ou pral oblije ale nan pwodiksyon an. Se lè sa a modèl sa a ap sispann travay. Paske:

Nan pwodiksyon, li p ap posib ankò, si sa nesesè, jete ansyen baz done a epi kòmanse nan grafouyen. Baz done w ap vin eritaj.

Depi koulye a ak pou tout tan ou pral oblije ekri Scripts migrasyon DDL, pou egzanp, lè l sèvi avèk Flyway. Kisa ki pral rive antite ou yo nan ka sa a? Ou ka swa adapte yo manyèlman (e konsa double kantite travay ou), oswa ou ka di Hibernate rejenere yo pou ou (ki jan chans yo pwodwi yo nan fason sa a satisfè atant ou yo?) Nenpòt fason, ou pèdi.

Se konsa, yon fwa ou antre nan pwodiksyon w ap bezwen plak cho. Apre sa, yo bezwen yo dwe mete nan pwodiksyon trè vit. Depi ou pa t 'prepare epi yo pa t' òganize yon tiyo lis nan migrasyon ou yo pou pwodiksyon, ou sovaj patch tout bagay. Lè sa a, ou pa gen tan ankò fè tout bagay kòrèkteman. Epi ou kritike Hibernate, paske se toujou fòt yon lòt moun, jis pa ou menm...

Olye de sa, bagay yo te ka fè yon fason konplètman diferan depi nan kòmansman an. Pou egzanp, mete wou wonn sou yon bisiklèt.

Baz done an premye

Vrè "verite" nan chema baz done w la ak "souverènte" sou li se nan baz done a. Chema a defini sèlman nan baz done a li menm ak okenn lòt kote, epi chak kliyan gen yon kopi chema sa a, kidonk li fè tout sans pou ranfòse konfòmite ak chema a ak entegrite li, pou fè li byen nan baz done a - kote enfòmasyon an ye. ki estoke.
Sa a se ansyen, menm sajès rache. Prensipal ak kle inik yo bon. Kle etranje yo bon. Tcheke restriksyon yo bon. Deklarasyon - Byen.

Anplis, sa a se pa tout. Pou egzanp, lè l sèvi avèk Oracle, ou ta pwobableman vle presize:

  • Nan ki espas tab ou a ye?
  • Ki valè PCTFREE li ye?
  • Ki gwosè kachèt la nan sekans ou a (dèyè id la)

Sa a ka pa enpòtan nan ti sistèm, men ou pa oblije rete tann jiskaske ou deplase nan domèn done gwo-ou ka kòmanse benefisye de optimize depo machann yo bay tankou sa yo mansyone pi wo a pi bonè. Okenn nan ORM mwen te wè (ki gen ladan jOOQ) pa bay aksè a tout seri opsyon DDL ou ta ka vle itilize nan baz done w la. ORM yo ofri kèk zouti ki ede w ekri DDL.

Men, nan fen jounen an, yon kous ki byen fèt yo ekri alamen nan DDL. Nenpòt DDL pwodwi se sèlman yon apwoksimasyon de li.

Ki sa ki sou modèl kliyan an?

Kòm mansyone pi wo a, sou kliyan an ou pral bezwen yon kopi nan chema baz done ou a, gade nan kliyan. Evidamman mansyone, gade kliyan sa a dwe nan senkronizasyon ak modèl aktyèl la. Ki pi bon fason pou reyalize sa? Sèvi ak yon dèlko kòd.

Tout baz done bay meta enfòmasyon yo atravè SQL. Men ki jan yo jwenn tout tab yo nan baz done ou a nan diferan dyalèk SQL:

	-- H2, HSQLDB, MySQL, PostgreSQL, SQL Server
SELECT table_schema, table_name
FROM information_schema.tables
 
-- DB2
SELECT tabschema, tabname
FROM syscat.tables
 
-- Oracle
SELECT owner, table_name
FROM all_tables
 
-- SQLite
SELECT name
FROM sqlite_master
 
-- Teradata
SELECT databasename, tablename
FROM dbc.tables

Rekèt sa yo (oswa sa yo menm jan an, tou depann de si ou gen tou konsidere opinyon, opinyon materyalize, fonksyon tab-valè) yo tou egzekite lè w rele. DatabaseMetaData.getTables() soti nan JDBC, oswa lè l sèvi avèk jOOQ meta-modil la.

Soti nan rezilta yo nan demann sa yo, li se relativman fasil jenere nenpòt reprezantasyon bò kliyan nan modèl baz done ou a, kèlkeswa ki teknoloji ou itilize sou kliyan an.

  • Si w ap itilize JDBC oswa Spring, ou ka kreye yon seri konstan fisèl
  • Si ou itilize JPA, ou ka jenere antite yo tèt yo
  • Si ou itilize jOOQ, ou ka jenere jOOQ meta-modèl la

Tou depan de konbyen fonksyonalite API kliyan ou an ofri (egzanp jOOQ oswa JPA), modèl meta pwodwi a ka vrèman rich ak konplè. Pran, pou egzanp, posibilite pou rantre nan implicite, prezante nan jOOQ 3.11, ki depann sou enfòmasyon meta pwodwi sou relasyon kle etranje ki egziste ant tab ou yo.

Koulye a, nenpòt enkreman baz done pral otomatikman mete ajou kòd kliyan an. Imajine pa egzanp:

ALTER TABLE book RENAME COLUMN title TO book_title;

Èske ou ta reyèlman vle fè travay sa a de fwa? Nan okenn ka. Senpleman komèt DDL a, kouri li atravè tiyo konstriksyon ou a, epi jwenn antite a mete ajou:

@Entity
@Table(name = "book", indexes = {
 
  // Вы об этом задумывались?
  @Index(name = "i_book_title", columnList = "book_title")
})
class Book {
  @Id
  @GeneratedValue(strategy = IDENTITY)
  int id;
 
  @Column("book_title")
  String bookTitle;
}

Oswa klas jOOQ ajou. Pifò chanjman DDL tou afekte semantik, pa sèlman sentaks. Se poutèt sa, li ka itil pou gade nan kòd konpile a pou wè ki kòd ki pral (oswa ki ka) afekte pa enkreman baz done ou a.

Sèl verite a

Kèlkeswa sa teknoloji ou itilize, toujou gen yon modèl ki se sèl sous verite a pou kèk subsistèm - oswa, nan yon minimòm, nou ta dwe fè efò pou sa a epi evite konfizyon antrepriz sa yo, kote "verite" se tout kote ak okenn kote nan yon fwa. . Tout bagay ta ka pi senp. Si w ap jis echanj fichye XML ak kèk lòt sistèm, jis itilize XSD. Gade meta-modèl INFORMATION_SCHEMA ki soti nan jOOQ nan fòm XML:
https://www.jooq.org/xsd/jooq-meta-3.10.0.xsd

  • XSD byen konprann
  • XSD tokenize kontni XML trè byen epi li pèmèt validation nan tout lang kliyan
  • XSD byen vèsyon e li gen konpatibilite avanse
  • XSD ka tradui nan kòd Java lè l sèvi avèk XJC

Dènye pwen an enpòtan. Lè nou kominike ak yon sistèm ekstèn lè l sèvi avèk mesaj XML, nou vle asire w ke mesaj nou yo valab. Sa a se trè fasil reyalize lè l sèvi avèk JAXB, XJC ak XSD. Li ta yon bagay moun fou pou panse ke, ak yon apwòch konsepsyon "Java premye" kote nou fè mesaj nou yo kòm objè Java, ke yo ta ka yon jan kanmenm dwe kat jeyografik nan XML ak voye ale nan yon lòt sistèm pou konsomasyon. XML ki te pwodwi nan fason sa a ta gen bon jan kalite trè pòv, san papye, ak difisil yo devlope. Si te gen yon akò nivo sèvis (SLA) pou yon koòdone konsa, nou ta imedyatman vis li.

Onètman, sa a se sa k ap pase tout tan tout tan an ak JSON APIs, men sa a se yon lòt istwa, mwen pral kont pwochen fwa ...

Baz done: yo se menm bagay la

Lè w ap travay ak baz done, ou reyalize ke yo tout fondamantalman menm jan an. Baz la posede done li yo epi li dwe jere konplo a. Nenpòt modifikasyon ki fèt nan chema a dwe aplike dirèkteman nan DDL la pou sèl sous verite a mete ajou.

Lè yon aktyalizasyon sous fèt, tout kliyan yo dwe mete ajou kopi modèl la tou. Gen kèk kliyan yo ka ekri nan Java lè l sèvi avèk jOOQ ak Hibernate oswa JDBC (oswa toude). Lòt kliyan yo ka ekri nan Perl (nou jis swete yo bòn chans), pandan ke lòt yo ka ekri nan C#. Li pa gen pwoblèm. Modèl prensipal la se nan baz done a. Modèl ki te pwodwi lè l sèvi avèk ORM yo anjeneral nan bon jan kalite pòv, mal dokimante, ak difisil yo devlope.

Se konsa, pa fè erè. Pa fè erè depi nan kòmansman an. Travay nan baz done a. Bati yon tiyo deplwaman ki ka otomatize. Pèmèt jeneratè kòd pou fè li fasil pou kopye modèl baz done w la epi jete l sou kliyan yo. Epi sispann enkyete sou dèlko kòd. Yo bon. Avèk yo ou pral vin pi pwodiktif. Ou jis bezwen pase yon ti tan mete kanpe yo depi nan konmansman an anpil - ak Lè sa a, ane nan ogmante pwodiktivite ap tann ou, ki pral fè moute istwa a nan pwojè ou a.

Pa di m mèsi ankò, pita.

Eksplikasyon

Pou yo ka klè: Atik sa a nan okenn fason defann ke ou bezwen pliye tout sistèm nan (sa vle di, domèn, lojik biznis, elatriye, elatriye) anfòm modèl baz done ou a. Sa m ap di nan atik sa a se ke kòd kliyan an ki kominike avèk baz done a ta dwe aji sou baz modèl baz done a, pou li menm li pa repwodui modèl baz done a nan yon estati "premye klas". Lojik sa a anjeneral sitiye nan kouch aksè done sou kliyan ou a.

Nan achitekti de-nivo, ki toujou konsève nan kèk kote, tankou yon modèl sistèm ka sèlman youn posib. Sepandan, nan pifò sistèm nan kouch aksè done sanble m 'yo dwe yon "sous-sistèm" ki encapsule modèl baz done a.

Eksepsyon

Gen eksepsyon nan chak règ, e mwen te deja di ke apwòch jenerasyon baz done-premye ak sous-kòd ka pafwa pa apwopriye. Isit la yo se yon koup nan eksepsyon sa yo (genyen pwobableman lòt):

  • Lè chema a se enkoni epi li bezwen yo dwe dekouvri. Pou egzanp, ou se yon founisè nan yon zouti ki ede itilizatè navige nenpòt dyagram. Ugh. Pa gen okenn jenerasyon kòd isit la. Men, toujou, baz done a vini an premye.
  • Lè yon kous dwe pwodwi sou vole pou rezoud kèk pwoblèm. Egzanp sa a sanble tankou yon vèsyon yon ti kras fantaisie nan modèl la valè atribi antite, sa vle di, ou pa reyèlman gen yon konplo defini klèman. Nan ka sa a, ou ka souvan pa menm asire w ke yon RDBMS pral kostim ou.

Eksepsyon yo pa nati eksepsyonèl. Nan pifò ka ki enplike itilizasyon yon RDBMS, yo konnen chema a davans, li abite nan RDBMS la epi li se sèl sous "verite", epi tout kliyan gen pou jwenn kopi ki sòti nan li. Idealman, ou bezwen sèvi ak yon dèlko kòd.

Sous: www.habr.com

Add nouvo kòmantè