<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ThinkChat2.0新版上線,更智能更精彩,支持會話、畫圖、視頻、閱讀、搜索等,送10W Token,即刻開啟你的AI之旅 廣告
                # JDBI 教程 > 原文: [http://zetcode.com/db/jdbi/](http://zetcode.com/db/jdbi/) 在本教程中,我們展示了如何使用 JDBI 處理數據。 我們選擇 MySQL 作為數據庫。 ZetCode 擁有用于 MySQL Java 的完整電子書,其中包含 JDBI 章節: [MySQL Java 編程電子書](/ebooks/mysqljava/)。 [Tweet](https://twitter.com/share) JDBI 是建立在 JDBC 之上的便捷庫。 它使數據庫編程容易得多。 它管理異常。 它具有用于自動資源管理和將結果集映射到類的工具。 JDBI 在概念上類似于 Spring 的`JdbcTemplate`,為此 ZetCode 具有[教程](/db/jdbctemplate/)。 `DBI`實例通過`Handle`實例提供與數據庫的連接。 `Handle`表示與數據庫系統的連接; 它是 JDBC 連接對象的包裝。 JDBI 提供了兩種不同的樣式 API:流利的樣式和對象樣式。 ## 在 MySQL 中創建數據庫 在本節中,我們將在 MySQL 中創建一個新的`testdb`數據庫。 我們使用`mysql`監視器來完成這項工作,但是我們也可以使用 NetBeans 數據庫工具。 `cars_mysql.sql` ```java DROP TABLE IF EXISTS Cars; CREATE TABLE Cars(Id INT PRIMARY KEY AUTO_INCREMENT, Name TEXT, Price INT) ENGINE=InnoDB; INSERT INTO Cars(Name, Price) VALUES('Audi', 52642); INSERT INTO Cars(Name, Price) VALUES('Mercedes', 57127); INSERT INTO Cars(Name, Price) VALUES('Skoda', 9000); INSERT INTO Cars(Name, Price) VALUES('Volvo', 29000); INSERT INTO Cars(Name, Price) VALUES('Bentley', 350000); INSERT INTO Cars(Name, Price) VALUES('Citroen', 21000); INSERT INTO Cars(Name, Price) VALUES('Hummer', 41400); INSERT INTO Cars(Name, Price) VALUES('Volkswagen', 21600); ``` 這是在 MySQL 中創建`Cars`表的 SQL。 要創建數據庫和表,我們使用`mysql`監視工具。 ```java $ sudo service mysql start ``` MySQL 用`sudo service mysql start`命令啟動。 ```java $ mysql -u testuser -p ``` 我們使用`mysql`監視器連接到數據庫。 ```java mysql> CREATE DATABASE testdb; Query OK, 1 row affected (0.02 sec) ``` 使用`CREATE DATABASE`語句創建一個新數據庫。 ```java mysql> USE testdb; mysql> SOURCE cars_mysql.sql ``` 使用`source`命令,加載并執行`cars_mysql.sql`文件。 ```java mysql> SELECT * FROM Cars; +----+------------+--------+ | Id | Name | Price | +----+------------+--------+ | 1 | Audi | 52642 | | 2 | Mercedes | 57127 | | 3 | Skoda | 9000 | | 4 | Volvo | 29000 | | 5 | Bentley | 350000 | | 6 | Citroen | 21000 | | 7 | Hummer | 41400 | | 8 | Volkswagen | 21600 | +----+------------+--------+ 8 rows in set (0.00 sec) ``` 我們驗證數據。 ## `pom.xml`文件 這些示例將使用以下 Maven POM 文件: `pom.xml` ```java <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zetcode</groupId> <artifactId>JDBIEx</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>org.jdbi</groupId> <artifactId>jdbi</artifactId> <version>2.73</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> </dependencies> </project> ``` 我們已經為 JDBI 庫和 MySQL 驅動程序定義了依賴項。 ## 流利的 API 在以下示例中,我們將使用 JDBI 流利 API 與 MySQL 數據庫一起使用。 ### 取回所有汽車 在第一個示例中,我們從`Cars`表中提取所有汽車。 `JDBIEx.java` ```java package com.zetcode; import java.util.List; import java.util.Map; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.Query; public class JDBIEx { public static void main(String[] args) { Handle handle = null; DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); String sql = "SELECT * FROM Cars"; try { handle = dbi.open(); Query<Map<String, Object>> q = handle.createQuery(sql); List<Map<String, Object>> l = q.list(); for (Map<String, Object> m : l) { System.out.printf("%d ", m.get("Id")); System.out.printf("%s ", m.get("Name")); System.out.println(m.get("Price")); } } finally { if (handle != null) { handle.close(); } } } } ``` 該示例連接到`testdb`數據庫,并從`Cars`表中檢索所有汽車。 ```java DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); ``` 使用`DBI`類為數據庫創建一個訪問點。 ```java handle = dbi.open(); ``` 使用`DBI`的`open()`方法創建數據庫的`Handle`。 它表示與數據庫的連接。 使用`DriverManager`創建到數據庫的連接。 ```java Query<Map<String, Object>> q = handle.createQuery(sql); ``` 使用`createQuery()`方法創建`Query`對象。 ```java List<Map<String, Object>> l = q.list(); ``` 從查詢對象中,我們獲得鍵/值對的列表。 ```java for (Map<String, Object> m : l) { System.out.printf("%d ", m.get("Id")); System.out.printf("%s ", m.get("Name")); System.out.println(m.get("Price")); } ``` 我們遍歷列表并打印所有列。 ```java } finally { if (handle != null) { handle.close(); } } ``` 最后,我們關閉手柄。 ```java 1 Audi 52642 2 Mercedes 57127 3 Skoda 9000 4 Volvo 29000 5 Bentley 350000 6 Citroen 21000 7 Hummer 41400 8 Volkswagen 21600 ``` 這是示例的輸出。 ### 通過 ID 檢索汽車 在下一個示例中,我們通過`Cars`表中的 ID 提取汽車名稱。 `JDBIEx2.java` ```java package com.zetcode; import java.util.Map; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.Query; import org.skife.jdbi.v2.util.StringColumnMapper; public class JDBIEx2 { public static void main(String[] args) { Handle handle = null; DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); try { handle = dbi.open(); String sql = "SELECT Name FROM Cars WHERE Id = ?"; Query<Map<String, Object>> q = handle.createQuery(sql); q.bind(0, 1); String carName = q.map(StringColumnMapper.INSTANCE).first(); System.out.println(carName); } finally { if (handle != null) { handle.close(); } } } } ``` 在示例中,我們從`Cars`表中選擇汽車名稱。 SQL 查詢采用一個稍后綁定的參數。 ```java String sql = "SELECT Name FROM Cars WHERE Id = ?"; ``` 這是用于從表中選擇汽車名稱的 SQL 代碼。 問號是一個令牌,稍后將在代碼中填充。 ```java Query<Map<String, Object>> q = handle.createQuery(sql); ``` 從 SQL 語句創建一個新的`Query`對象。 ```java q.bind(0, 1); ``` 使用`bind()`方法,我們綁定缺少的參數。 參數在位置上綁定。 ```java String carName = q.map(StringColumnMapper.INSTANCE).first(); ``` 我們將帶有`StringColumnMapper`的結果集的列映射到字符串類型。 `first()`方法用于返回一個值。 ```java System.out.println(carName); ``` 汽車的名稱被打印到控制臺上。 ### 數據源 在此示例中,我們使用數據源連接到數據庫。 數據源的使用可以提高應用的性能和可伸縮性。 `db.properties` ```java # mysql properties mysql.driver=com.mysql.jdbc.Driver mysql.url=jdbc:mysql://localhost:3306/testdb mysql.username=testuser mysql.password=test623 ``` 在`db.properties`文件中,我們具有連接屬性。 ![Database properties](https://img.kancloud.cn/f7/c6/f7c64b97102fab51455a73e2fa06ae75_213x55.jpg) 圖:數據庫屬性 該文件放置在項目的`Resources`目錄中。 `JDBIEx3.java` ```java package com.zetcode; import com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource; import com.mysql.jdbc.jdbc2.optional.MysqlDataSource; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.Map; import java.util.Properties; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.Query; import org.skife.jdbi.v2.util.IntegerColumnMapper; public class JDBIEx3 { public static MysqlDataSource getMySQLDataSource() throws FileNotFoundException, IOException { Properties props = new Properties(); FileInputStream fis = null; MysqlDataSource ds = null; fis = new FileInputStream("src/main/Resources/db.properties"); props.load(fis); ds = new MysqlConnectionPoolDataSource(); ds.setURL(props.getProperty("mysql.url")); ds.setUser(props.getProperty("mysql.username")); ds.setPassword(props.getProperty("mysql.password")); return ds; } public static void main(String[] args) throws IOException { Handle handle = null; MysqlDataSource ds = getMySQLDataSource(); DBI dbi = new DBI(ds); try { handle = dbi.open(); String sql = "SELECT Price FROM Cars WHERE Id = ?"; Query<Map<String, Object>> q = handle.createQuery(sql); q.bind(0, 1); Integer price = q.map(IntegerColumnMapper.WRAPPER).first(); System.out.println(price); } finally { if (handle != null) { handle.close(); } } } } ``` 該示例選擇通過 ID 查找的汽車價格。 ```java fis = new FileInputStream("src/main/Resources/db.properties"); props.load(fis); ``` 我們從`Resources`目錄加載屬性。 ```java ds = new MysqlConnectionPoolDataSource(); ds.setURL(props.getProperty("mysql.url")); ds.setUser(props.getProperty("mysql.username")); ds.setPassword(props.getProperty("mysql.password")); ``` 創建了`MysqlConnectionPoolDataSource`。 我們從屬性文件中設置參數。 ```java Integer price = q.map(IntegerColumnMapper.WRAPPER).first(); ``` 由于 SQL 查詢返回整數,因此我們使用`IntegerColumnMapper`類。 ### `withHandle()`方法 `DBI`類具有稱為`withHandle()`的便捷方法,該方法管理句柄的生命周期,并將其提供給回調以供客戶端使用。 `JDBIEx4.java` ```java package com.zetcode; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.util.IntegerColumnMapper; public class JDBIEx4 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); String sql = "SELECT Price FROM Cars WHERE Id = :id"; int id = 3; Integer price = dbi.withHandle((Handle h) -> { return h.createQuery(sql) .map(IntegerColumnMapper.WRAPPER) .bind("id", id) .first(); }); System.out.println(price); } } ``` 該示例選擇由其 ID 標識的汽車價格。 ```java String sql = "SELECT Price FROM Cars WHERE Id = :id"; ``` 此 SQL 查詢使用命名參數。 ```java Integer price = dbi.withHandle((Handle h) -> { return h.createQuery(sql) .map(IntegerColumnMapper.WRAPPER) .bind("id", id) .first(); }); ``` 創建和執行查詢時,我們不必擔心關閉句柄。 ### 映射自定義類 可以將自定義類映射到結果集。 映射類必須實現`ResultSetMapper<T>`接口。 `Car.java` ```java package com.zetcode; public class Car { private Long Id; private String Name; private int Price; public Car(Long Id, String Name, int Price) { this.Id = Id; this.Name = Name; this.Price = Price; } public Long getId() { return Id; } public void setId(Long Id) { this.Id = Id; } public String getName() { return Name; } public void setName(String Name) { this.Name = Name; } public int getPrice() { return Price; } public void setPrice(int Price) { this.Price = Price; } @Override public String toString() { return "Car{" + "Id=" + Id + ", Name=" + Name + ", Price=" + Price + '}'; } } ``` 這是一個自定義`Car`類,我們將結果集映射到該類。 `CarMapper.java` ```java package com.zetcode; import java.sql.ResultSet; import java.sql.SQLException; import org.skife.jdbi.v2.StatementContext; import org.skife.jdbi.v2.tweak.ResultSetMapper; public class CarMapper implements ResultSetMapper<Car> { @Override public Car map(int idx, ResultSet rs, StatementContext ctx) throws SQLException { return new Car(rs.getLong("Id"), rs.getString("Name"), rs.getInt("Price")); } } ``` 我們提供了映射類。 它返回一個新的`Car`對象,其中填充了結果集中的數據。 `JDBIEx5.java` ```java package com.zetcode; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; public class JDBIEx5 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); String sql = "SELECT * FROM Cars WHERE Id = :id"; int id = 3; Car car = dbi.withHandle((Handle h) -> { return h.createQuery(sql) .map(new CarMapper()) .bind("id", id) .first(); }); System.out.println(car); } } ``` 該示例從由其 ID 標識的表中選擇一個`Car`對象。 ```java Car car = dbi.withHandle((Handle h) -> { return h.createQuery(sql) .map(new CarMapper()) .bind("id", id) .first(); }); ``` 自定義`CarMapper`對象將傳遞給`map()`方法。 ### 批量操作 批處理允許我們將相關的 SQL 語句分組為批,然后通過一次調用將其提交到數據庫。 這可以大大提高我們的應用的性能。 批處理操作不是原子操作; 他們沒有提供全部或全部解決方案。 例如,如果我們創建不正確的`INSERT`語句,它將失敗,但是將執行其他`INSERT`語句。 `JDBIEx6.java` ```java package com.zetcode; import org.skife.jdbi.v2.Batch; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; public class JDBIEx6 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); Handle handle = dbi.open(); Batch batch = handle.createBatch(); batch.add("DROP TABLE IF EXISTS Friends"); batch.add("CREATE TABLE Friends(Id INT AUTO_INCREMENT PRIMARY KEY, Name TEXT)"); batch.add("INSERT INTO Friends(Name) VALUES ('Monika')"); batch.add("INSERT INTO Friends(Name) VALUES ('Tom')"); batch.add("INSERT INTO Friends(Name) VALUES ('Jane')"); batch.add("INSERT INTO Friends(Name) VALUES ('Robert')"); batch.execute(); } } ``` 該示例創建一個新的`Friends`表。 SQL 命令被分組為一個批處理操作。 ```java Batch batch = handle.createBatch(); ``` `Batch`代表一組未預備語句; 它是使用`createBatch()`方法創建的。 ```java batch.add("DROP TABLE IF EXISTS Friends"); ``` `add()`方法將語句添加到批處理中。 ```java batch.execute(); ``` 批處理通過`execute()`方法執行。 ### 事務 事務是針對一個或多個數據庫中數據的數據庫操作的基本單位。 事務中所有 SQL 語句的影響可以全部提交給數據庫,也可以全部回滾。 還要注意,在 MySQL 中,DDL 語句(例如`DROP TABLE`和`CREATE TABLE`)會導致對事務的隱式提交。 `JDBIEx7.java` ```java package com.zetcode; import org.skife.jdbi.v2.Batch; import org.skife.jdbi.v2.DBI; import org.skife.jdbi.v2.Handle; import org.skife.jdbi.v2.TransactionStatus; import org.skife.jdbi.v2.VoidTransactionCallback; public class JDBIEx7 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); dbi.inTransaction(new VoidTransactionCallback() { @Override protected void execute(Handle handle, TransactionStatus status) throws Exception { Batch batch = handle.createBatch(); batch.add("DROP TABLE IF EXISTS Friends"); batch.add("CREATE TABLE Friends(Id INT AUTO_INCREMENT PRIMARY KEY, Name TEXT)"); batch.add("INSERT INTO Friends(Name) VALUES ('Monika')"); batch.add("INSERT INTO Friends(Name) VALUES ('Tom')"); batch.add("INSERT INTO Friends(Name) VALUES ('Jane')"); batch.add("INSERT INTO Friends(Name) VALUES ('Robert')"); batch.execute(); } }); } } ``` 該示例將批處理操作置于事務中。 由于 MYSQL 中 DDL 語句的隱式提交,因此只有`INSERT`語句處于全有或全無模式。 ```java dbi.inTransaction(new VoidTransactionCallback() { @Override protected void execute(Handle handle, TransactionStatus status) throws Exception { ... } }); ``` 使用`inTransaction()`方法創建事務。 `VoidTransactionCallback`是不返回值的事務回調。 ## SQL 對象 API SQL 對象 API 為常見的 JDBI 操作提供了一種聲明性機制。 要使用 SQL 對象 API,我們創建帶有注解的接口或抽象類,例如`@SqlQuery`或`@SqlUpdate`。 ### 簡單的例子 我們創建了一個示例,其中將使用 SQL 對象 API 創建簡單查詢。 ```java <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.16.8</version> </dependency> ``` 在示例中,我們還使用了`lombok`庫,該庫減少了一些樣板代碼。 `Car.java` ```java package com.zetcode; import lombok.Data; @Data public class Car { private final Long Id; private final String Name; private final int Price; } ``` `Car`類裝飾有 Lombok 的`@Data`注解。 它將自動創建獲取器和設置器方法,`equals()`方法,`toString()`方法,`hashCode()`方法和參數構造器。 `CarMapper.java` ```java package com.zetcode; import java.sql.ResultSet; import java.sql.SQLException; import org.skife.jdbi.v2.StatementContext; import org.skife.jdbi.v2.tweak.ResultSetMapper; public class CarMapper implements ResultSetMapper<Car> { @Override public Car map(int idx, ResultSet rs, StatementContext ctx) throws SQLException { return new Car(rs.getLong("Id"), rs.getString("Name"), rs.getInt("Price")); } } ``` `CarMapper`將結果集映射到`Car`類。 `MyDAO.java` ```java package com.zetcode; import org.skife.jdbi.v2.sqlobject.Bind; import org.skife.jdbi.v2.sqlobject.SqlQuery; import org.skife.jdbi.v2.sqlobject.customizers.Mapper; public interface MyDAO { @SqlQuery("SELECT * FROM Cars WHERE Id = :id") @Mapper(CarMapper.class) Car findById(@Bind("id") int id); @SqlQuery("SELECT COUNT(Id) FROM Cars") int countCars(); } ``` 在這里,我們有一個`MyDAO`接口,裝飾有兩個`@SqlQuery`注解。 這些方法通過其 ID 查找汽車并計算表中的所有汽車。 ```java @SqlQuery("SELECT * FROM Cars WHERE Id = :id") ``` `@SqlQuery`注解指示該方法執行指定的查詢。 ```java @Mapper(CarMapper.class) ``` `@Mapper`指定查詢方法上的結果集映射器。 ```java Car findById(@Bind("id") int id); ``` `@Bind`注解將方法的參數綁定到 SQL 查詢參數。 `JDBIEx8.java` ```java package com.zetcode; import org.skife.jdbi.v2.DBI; public class JDBIEx8 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); int id = 3; MyDAO dao = dbi.onDemand(MyDAO.class); Car car = dao.findById(id); System.out.println(car); int nCars = dao.countCars(); System.out.printf("There are %d cars in the table", nCars); } } ``` 在此客戶端應用中,我們找到 ID 等于 3 的汽車,并計算表中的所有汽車。 ```java MyDAO dao = dbi.onDemand(MyDAO.class); ``` `onDemand()`方法創建一個新的 sql 對象,該對象將分別根據需要和可以從該 dbi 實例獲取和釋放連接。 我們不應該顯式關閉此 sql 對象。 ```java Car car = dao.findById(id); ``` 我們得到了具有指定 ID 的汽車。 ```java int nCars = dao.countCars(); ``` 我們在數據庫表中計算汽車的數量。 ### 事務 在 SQL 對象 API 中,我們可以使用`@Transaction`注解創建事務。 `authors_books.sql` ```java CREATE TABLE IF NOT EXISTS Authors(Id BIGINT PRIMARY KEY AUTO_INCREMENT, Name VARCHAR(25)) ENGINE=InnoDB; CREATE TABLE IF NOT EXISTS Books(Id BIGINT PRIMARY KEY AUTO_INCREMENT, AuthorId BIGINT, Title VARCHAR(100), FOREIGN KEY(AuthorId) REFERENCES Authors(Id) ON DELETE CASCADE) ENGINE=InnoDB; ``` 對于此示例,我們創建兩個表:`Authors`和`Books`。 `MyDAO.java` ```java package com.zetcode; import java.util.List; import org.skife.jdbi.v2.exceptions.TransactionFailedException; import org.skife.jdbi.v2.sqlobject.Bind; import org.skife.jdbi.v2.sqlobject.SqlQuery; import org.skife.jdbi.v2.sqlobject.SqlUpdate; import org.skife.jdbi.v2.sqlobject.Transaction; public abstract class MyDAO { @SqlUpdate("INSERT INTO Authors(Name) VALUES(:author)") public abstract void createAuthor(@Bind("author") String author); @SqlQuery("SELECT Id FROM Authors WHERE Name = :name") abstract long getAuthorId(@Bind("name") String name); @SqlUpdate("INSERT INTO Books(AuthorId, Title) VALUES(:authorId, :title)") abstract void insertBook(@Bind("authorId") Long authorId, @Bind("title") String title); @Transaction public void insertBooksForAuthor(String author, List<String> titles) { Long authorId = getAuthorId(author); if (authorId == null) { throw new TransactionFailedException("No author found"); } for (String title : titles) { insertBook(authorId, title); } } } ``` 我們有一個抽象的`MyDAO`類,其中利用了`@SqlUpdate`,`@SqlQuery`和`@Transaction`注解。 ```java @SqlUpdate("INSERT INTO Authors(Name) VALUES(:author)") public abstract void createAuthor(@Bind("author") String author); ``` 此方法添加了一個新作者。 ```java @SqlQuery("SELECT Id FROM Authors WHERE Name = :name") abstract long getAuthorId(@Bind("name") String name); ``` `getAuthorId()`用于獲取作者的 ID。 當我們將新書插入`Books`表時,需要 ID。 ```java @SqlUpdate("INSERT INTO Books(AuthorId, Title) VALUES(:authorId, :title)") abstract void insertBook(@Bind("authorId") Long authorId, @Bind("title") String title); ``` `insertBook()`方法將一本書插入`Books`表中。 ```java @Transaction public void insertBooksForAuthor(String author, List<String> titles) { Long authorId = getAuthorId(author); if (authorId == null) { throw new TransactionFailedException("No author found"); } for (String title : titles) { insertBook(authorId, title); } } ``` `@Transaction`注解使`insertBooksForAuthor()`在事務內運行。 因此,要么插入所有書籍,要么不插入任何書籍。 `JDBIEx9.java` ```java package com.zetcode; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; import org.skife.jdbi.v2.DBI; public class JDBIEx9 { public static void main(String[] args) { DBI dbi = new DBI("jdbc:mysql://localhost:3306/testdb", "testuser", "test623"); List<Map<String, List<String>>> authorsBooks = new ArrayList<>(); Map<String, List<String>> autMap1 = new HashMap<>(); List<String> books1 = new ArrayList<>(); books1.add("Call of the Wild"); books1.add("Martin Eden"); books1.add("The Iron Heel"); books1.add("White Fang"); autMap1.put("Jack London", books1); Map<String, List<String>> autMap2 = new HashMap<>(); List<String> books2 = new ArrayList<>(); books2.add("Father Goriot"); books2.add("Colonel Chabert"); books2.add("Cousing Pons"); autMap2.put("Honore de Balzac", books2); authorsBooks.add(autMap1); authorsBooks.add(autMap2); MyDAO dao = dbi.onDemand(MyDAO.class); for (Map<String, List<String>> map : authorsBooks) { Set<String> ks = map.keySet(); for (String author : ks) { dao.createAuthor(author); List<String> titles = map.get(author); dao.insertBooksForAuthor(author, titles); } } } } ``` 該示例將兩名作者及其書籍插入數據庫。 在本教程中,我們介紹了 JDBI 庫。 ZetCode 具有以下相關教程: [Java 教程](/lang/java/), [MySQL Java 教程](/db/mysqljava/)和 [MySQL 教程](/databases/mysqltutorial/)。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看