CRUD-operaatioiden suorittaminen
Hallitsette tietojen luomisen, lukemisen, päivittämisen ja poistamisen relaatiotietokannoista Clojurella.
CRUD-operaatioiden suorittaminen on ilmainen Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-oppitunti CoddyKitissä. Tämä on oppitunti 2/4. Voit lukea koko oppitunnin alta ilmaiseksi ja harjoitella sen jälkeen käytännössä selaimessa sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla. Oppitunti kuuluu Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-oppimispolkuun, ja edistymisesi synkronoituu verkon ja CoddyKit-sovelluksen välillä. Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-kurssilla on yhteensä 4 oppituntia.
Mitä CRUD tarkoittaa?
Sovelluksia rakentaessanne olette jatkuvasti vuorovaikutuksessa tietokantojen kanssa. Tietojen hallinnan perusoperaatiot tiivistetään usein lyhenteeseen CRUD.
- Create: uusien tietojen lisääminen.
- Read: olemassa olevien tietojen hakeminen.
- Update: olemassa olevien tietojen muokkaaminen.
- Delete: tietojen poistaminen.
Tässä oppitunnissa opitte suorittamaan nämä keskeiset operaatiot Clojuren next.jdbc-kirjaston avulla.
Tietokantayhteyden määritys
Ennen CRUD-operaatioiden suorittamista tarvitsemme tietokantayhteyden. Käytämme esimerkeissä next.jdbc-kirjastoa ja muistissa toimivaa SQLite-tietokantaa.
Muistattehan edellisestä oppitunnista, että määrittelemme tietokannan määrityksen (db-spec) ja haemme tietolähteen (ds) tai suoran yhteyden.
Luomme esimerkkejä varten yksinkertaisen users-taulun.
Create: uusien tietueiden lisääminen
Uusien tietojen lisäämiseen käytämme next.jdbc.sql/insert!-funktiota. Se saa parametrikseen yhteyden, taulun nimen ja sarake–arvo-parien kartan.
Suorittakaa tämä esimerkki luodaksenne users-taulun ja lisätäksenne ensimmäisen käyttäjänne:
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Insert a new user into the database."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(println "Inserting new user...")
(let [new-user {:name "Alice" :email "alice@example.com"}
result (sql/insert! conn :users new-user)]
(println "Insert result:" result))
(println "\nUsers in database:")
(doseq [user (sql/select! conn ["SELECT * FROM users"])]
(println user)))))Create: useiden tietueiden lisääminen
Entä jos useita tietueita on lisättävä kerralla? next.jdbc.sql/insert-multi!-funktio sopii tähän erinomaisesti. Se saa parametrikseen karttojen sarjan, jossa kukin kartta edustaa lisättävää riviä.
Se on tehokkaampi kuin insert!-funktion kutsuminen toistuvasti silmukassa.
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Insert multiple users into the database."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(println "Inserting multiple users...")
(let [new-users [{:name "Bob" :email "bob@example.com"}
{:name "Charlie" :email "charlie@example.com"}]
result (sql/insert-multi! conn :users new-users)]
(println "Insert result:" result))
(println "\nUsers in database:")
(doseq [user (sql/select! conn ["SELECT * FROM users"])]
(println user)))))Read: kaikkien tietojen hakeminen
Voitte hakea kaikki taulun tietueet käyttämällä next.jdbc.sql/select-all!-funktiota. Se saa parametrikseen yhteyden ja taulun nimen (avainsanana tai merkkijonona).
Funktio palauttaa karttojen sarjan, jossa kukin kartta edustaa yhtä riviä.
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Select all users from the database."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(sql/insert! conn :users {:name "Alice" :email "alice@example.com"})
(sql/insert! conn :users {:name "Bob" :email "bob@example.com"})
(println "Fetching all users...")
(let [all-users (sql/select-all! conn :users)]
(doseq [user all-users]
(println user))))))Read: tietojen suodattaminen `WHERE`-ehdolla
Usein haluatte vain tietyt tietueet. Käyttäkää tulosten suodattamiseen next.jdbc.sql/select!-funktiota yhdessä WHERE-ehdon kanssa. WHERE-ehto annetaan karttana.
Voitte esimerkiksi etsiä käyttäjiä tietyn nimen tai sähköpostiosoitteen perusteella:
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Select users with a specific name."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(sql/insert! conn :users {:name "Alice" :email "alice@example.com"})
(sql/insert! conn :users {:name "Bob" :email "bob@example.com"})
(sql/insert! conn :users {:name "Alice" :email "alice2@example.com"})
(println "Fetching users named Alice...")
(let [alices (sql/select! conn :users {:name "Alice"})]
(doseq [user alices]
(println user))))))Update: olemassa olevien tietojen muokkaaminen
Olemassa olevien tietueiden muuttamiseen käytetään next.jdbc.sql/update!-funktiota. Se saa parametrikseen yhteyden, taulun nimen, päivitettävien sarakkeiden kartan ja WHERE-ehtokartan, joka määrittää muokattavat tietueet.
Olkaa aina tarkkoja WHERE-ehdon kanssa päivityksiä tehdessänne!
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Update a user's email address."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(sql/insert! conn :users {:name "Alice" :email "alice@example.com"})
(println "Original user:")
(println (first (sql/select! conn :users {:name "Alice"})))
(println "\nUpdating Alice's email...")
(let [result (sql/update! conn :users {:email "alice.new@example.com"} {:name "Alice"})]
(println "Update result:" result))
(println "\nUpdated user:")
(println (first (sql/select! conn :users {:name "Alice"})))))Delete: tietojen poistaminen
Taulun tietueiden poistamiseen käytetään next.jdbc.sql/delete!-funktiota. Kuten update!, se tarvitsee yhteyden, taulun nimen ja poistettavat tietueet määrittävän WHERE-ehtokartan.
Puuttuva tai tyhjä WHERE-ehto voi poistaa KAIKKI tietueet, joten toimikaa erittäin varovasti!
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Delete a user from the database."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS users;"])
(jdbc/execute! conn ["CREATE TABLE users (id INTEGER PRIMARY KEY, name TEXT, email TEXT)"])
(sql/insert! conn :users {:name "Alice" :email "alice@example.com"})
(sql/insert! conn :users {:name "Bob" :email "bob@example.com"})
(println "Users before delete:")
(doseq [user (sql/select-all! conn :users)] (println user))
(println "\nDeleting Bob...")
(let [result (sql/delete! conn :users {:name "Bob"})]
(println "Delete result:" result))
(println "\nUsers after delete:")
(doseq [user (sql/select-all! conn :users)] (println user)))))Atomiset operaatiot transaktioilla
Joskus useiden CRUD-operaatioiden on onnistuttava tai epäonnistuttava yhtenä atomisena kokonaisuutena. Tällöin tarvitaan transaktioita.
Jos jokin transaktion sisäinen operaatio epäonnistuu, kaikki muutokset perutaan, mikä varmistaa tietojen eheyden. Käyttäkää tähän next.jdbc/with-transaction-toimintoa.
(ns coddykit.core
(:require [next.jdbc :as jdbc]
[next.jdbc.sql :as sql]))
(defn -main
"Demonstrate a database transaction."
[& args]
(let [db-spec {:dbtype "sqlite" :dbname ":memory:"}]
(with-open [conn (jdbc/get-connection db-spec)]
(jdbc/execute! conn ["DROP TABLE IF EXISTS accounts;"])
(jdbc/execute! conn ["CREATE TABLE accounts (id INTEGER PRIMARY KEY, name TEXT, balance INTEGER)"])
(sql/insert! conn :accounts {:name "Alice" :balance 100})
(sql/insert! conn :accounts {:name "Bob" :balance 50})
(println "Balances before transaction:")
(doseq [acc (sql/select-all! conn :accounts)] (println acc))
(println "\nAttempting to transfer $20 from Alice to Bob...")
(try
(jdbc/with-transaction [tx conn]
(sql/update! tx :accounts {:balance [- :balance 20]} {:name "Alice"})
(sql/update! tx :accounts {:balance [+ :balance 20]} {:name "Bob"})
(println "Transfer successful!"))
(catch Exception e
(println "Transfer failed:" (.getMessage e))))
(println "\nBalances after transaction:")
(doseq [acc (sql/select-all! conn :accounts)] (println acc)))))CRUD-pikatarkistus
Olette oppineet tietokantojen käsittelyn keskeiset funktiot. Testataanpa ymmärrystänne!
Kertaus: CRUD-operaatioiden hallinta
Onneksi olkoon! Hallitsette nyt tietokantojen käsittelyn keskeiset CRUD-operaatiot Clojuren next.jdbc-kirjastolla:
- Create:
insert!jainsert-multi!tietojen lisäämiseen. - Read:
select!jaselect-all!tietojen hakemiseen. - Update:
update!olemassa olevien tietojen muokkaamiseen. - Delete:
delete!tietojen poistamiseen.
Opitte myös käyttämään transaktioita yhdessä with-transaction-toiminnon kanssa atomisiin operaatioihin, mikä varmistaa tietojen eheyden. Nämä ovat lähes kaikkien tietopohjaisten sovellusten rakennuspalikoita!
Opi Clojure tekoälytuutorin avulla — ilmaiseksi
Kirjoita ja suorita oikeaa koodia selaimessa, saa välitöntä apua tekoälytuutorilta ympäri vuorokauden ja jatka siitä, mihin jäit, verkossa tai sovelluksessa.
- Kurssit
- 12
- Oppitunnit
- 48
Usein kysytyt kysymykset
Onko oppitunti ”CRUD-operaatioiden suorittaminen” ilmainen?
Kyllä – oppitunnin ”CRUD-operaatioiden suorittaminen” koko tekstin voi lukea täällä verkossa ilmaiseksi. Jos haluat harjoitella interaktiivisesti sisäänrakennetulla koodieditorilla ja ympäri vuorokauden käytettävissä olevan tekoälytuutorin avulla sekä avata koko Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-kurssin, päivitä CoddyKit PROhon. Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-kurssilla on yhteensä 4 oppituntia.
Mitä opin oppitunnilla ”CRUD-operaatioiden suorittaminen”?
Hallitsette tietojen luomisen, lukemisen, päivittämisen ja poistamisen relaatiotietokannoista Clojurella. Harjoittelet Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-aihetta koodilla, jonka suoritat suoraan selaimessa. Ympäri vuorokauden käytettävissä oleva tekoälytuutori vastaa kysymyksiisi oppitunnin aikana.
Tarvitsenko kokemusta aloittaakseni Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-opiskelun?
Aiempi kokemus ei ole tarpeen. CoddyKitin Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-oppimispolku sopii vasta-alkajista edistyneisiin, joten voit aloittaa tästä tai alusta ja edetä omaan tahtiisi. Tämä on oppitunti 2/4.
Kuinka kauan ”CRUD-operaatioiden suorittaminen”-oppitunnin suorittaminen kestää?
Useimmat CoddyKitin oppitunnit kestävät noin 5–10 minuuttia. Jokainen oppitunti on lyhyt ja interaktiivinen, joten edistyt tasaisesti ja voit jatkaa siitä, mihin jäit – sekä verkossa että sovelluksessa.
Voinko kirjoittaa ja suorittaa koodia tällä Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-oppitunnilla?
Kyllä. Jokainen Clojure-funktionaalinen ohjelmointi ja JVM-backend-kehitys-oppitunti sisältää sisäänrakennetun koodieditorin, joten voit kirjoittaa ja suorittaa oikeaa koodia suoraan selaimessa ja saada välitöntä palautetta tekoälyltä – paikallista asennusta ei tarvita.
Kaikki tämän kurssin oppitunnit
- Tietokantayhteydet next.jdbc:llä
- CRUD-operaatioiden suorittaminen
- Tietokantamigraatiot ja skeeman hallinta
- Yhteyspoolit ja transaktiot