在Java的Spring框架的程序中使用JDBC API操作數(shù)據(jù)庫
同時與數(shù)據(jù)庫使用普通的舊JDBC的工作,它變得繁瑣寫不必要的代碼來處理異常,打開和關(guān)閉數(shù)據(jù)庫連接等,但Spring的JDBC框架需要的所有低層次細(xì)節(jié)從打開連接,準(zhǔn)備和執(zhí)行SQL語句,過程異常,處理事務(wù),最后關(guān)閉連接。
所以,你所要做的只是定義連接參數(shù),并指定要執(zhí)行的SQL語句,并做必要的工作,在每次迭代時從數(shù)據(jù)庫中獲取數(shù)據(jù)。
Spring JDBC提供了一些方法和相應(yīng)不同的類與數(shù)據(jù)庫進(jìn)行交互。我要采取經(jīng)典和最流行的做法,利用JdbcTemplateclass框架。這是管理的所有數(shù)據(jù)庫的通信和異常處理中心框架類。
JdbcTemplate 類
JdbcTemplate類執(zhí)行SQL查詢,更新語句和存儲過程調(diào)用,在結(jié)果集和提取返回參數(shù)值進(jìn)行迭代。它還捕捉JDBC的異常并將其轉(zhuǎn)換為通用的,信息更豐富,除了在org.springframework.dao包中定義的層次結(jié)構(gòu)。
JdbcTemplate類的實(shí)例是一次配置的線程。所以,你可以配置一個JdbcTemplate的一個實(shí)例,然后安全地注入這種共享引用到多個DAO。
使用JdbcTemplate類時,通常的做法是配置一個DataSource在Spring配置文件,然后依賴關(guān)系注入該共享數(shù)據(jù)源豆到DAO類,JdbcTemplate或者是在setter數(shù)據(jù)源創(chuàng)建。
配置數(shù)據(jù)源
讓我們一起創(chuàng)造數(shù)據(jù)庫test數(shù)據(jù)庫表的 student 。假設(shè)使用MySQL數(shù)據(jù)庫,如果使用其他數(shù)據(jù)庫,那么可以相應(yīng)地改變你的DDL和SQL查詢。
CREATE TABLE Student( ID INT NOT NULL AUTO_INCREMENT, NAME VARCHAR(20) NOT NULL, AGE INT NOT NULL, PRIMARY KEY (ID) );
現(xiàn)在,我們需要提供一個數(shù)據(jù)源給JdbcTemplate類,因此它可以自行配置,以獲得數(shù)據(jù)庫訪問。您可以配置數(shù)據(jù)源的XML文件中有一段代碼,如下圖所示:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/TEST"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean>
數(shù)據(jù)訪問對象 (DAO)
DAO表示這是通常用于數(shù)據(jù)庫交互的數(shù)據(jù)訪問對象。 DAO的存在是為了提供讀取和寫入數(shù)據(jù)到數(shù)據(jù)庫中,他們應(yīng)該通過該應(yīng)用程序的其余部分將訪問它們的接口公開此功能的一種手段。
在Spring的數(shù)據(jù)訪問對象(DAO)的支持使得它很容易與如JDBC,Hibernate,JPA和JDO以一致的方式進(jìn)行數(shù)據(jù)訪問技術(shù)。
執(zhí)行SQL語句
讓我們來看看如何使用SQL和的JdbcTemplate對象數(shù)據(jù)庫中的表執(zhí)行CRUD(創(chuàng)建,讀取,更新和刪除)操作。
查詢一個整數(shù):
String SQL = "select count(*) from Student"; int rowCount = jdbcTemplateObject.queryForInt( SQL );
查詢長整數(shù):
String SQL = "select count(*) from Student"; long rowCount = jdbcTemplateObject.queryForLong( SQL );
使用綁定變量的簡單查詢:
String SQL = "select age from Student where id = ?"; int age = jdbcTemplateObject.queryForInt(SQL, new Object[]{10});
在查詢字符串:
String SQL = "select name from Student where id = ?"; String name = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, String.class);
查詢并返回一個對象:
String SQL = "select * from Student where id = ?"; Student student = jdbcTemplateObject.queryForObject(SQL, new Object[]{10}, new StudentMapper()); public class StudentMapper implements RowMapper<Student> { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student student = new Student(); student.setID(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); return student; } }
查詢并返回多個對象:
String SQL = "select * from Student"; List<Student> students = jdbcTemplateObject.query(SQL, new StudentMapper()); public class StudentMapper implements RowMapper<Student> { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student student = new Student(); student.setID(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); return student; } }
插入一行到表:
String SQL = "insert into Student (name, age) values (?, ?)"; jdbcTemplateObject.update( SQL, new Object[]{"Zara", 11} );
String SQL = "update Student set name = ? where id = ?"; jdbcTemplateObject.update( SQL, new Object[]{"Zara", 10} );
從表中刪除行:
String SQL = "delete Student where id = ?"; jdbcTemplateObject.update( SQL, new Object[]{20} );
執(zhí)行DDL語句
您可以使用execute(...)方法的JdbcTemplate來執(zhí)行任何SQL語句或DDL語句。下面是一個示例使用CREATE語句創(chuàng)建一個表:
String SQL = "CREATE TABLE Student( " + "ID INT NOT NULL AUTO_INCREMENT, " + "NAME VARCHAR(20) NOT NULL, " + "AGE INT NOT NULL, " + "PRIMARY KEY (ID));" jdbcTemplateObject.execute( SQL );
SQL存儲過程
SimpleJdbcCall的類可以用來調(diào)用帶有IN和OUT參數(shù)的存儲過程。你可以使用這種方法,而與任何喜歡的Apache Derby,DB2,MySQL和微軟SQL服務(wù)器,Oracle和Sybase RDBMS中的工作。
其次,考慮以下的MySQL存儲過程這需要學(xué)生證和用OUT參數(shù)對應(yīng)的學(xué)生的姓名和年齡的回報。因此,讓我們使用MySQL命令提示符下在測試數(shù)據(jù)庫中創(chuàng)建該存儲過程:
DELIMITER $$ DROP PROCEDURE IF EXISTS `TEST`.`getRecord` $$ CREATE PROCEDURE `TEST`.`getRecord` ( IN in_id INTEGER, OUT out_name VARCHAR(20), OUT out_age INTEGER) BEGIN SELECT name, age INTO out_name, out_age FROM Student where id = in_id; END $$ DELIMITER ;
現(xiàn)在讓我們寫了Spring JDBC應(yīng)用程序,將執(zhí)行我們的學(xué)生桌簡單的創(chuàng)建和讀取操作。
來創(chuàng)建一個Spring應(yīng)用程序:
以下是數(shù)據(jù)訪問對象接口文件StudentDAO.java的內(nèi)容:
package com.yiibai; import java.util.List; import javax.sql.DataSource; public interface StudentDAO { /** * This is the method to be used to initialize * database resources ie. connection. */ public void setDataSource(DataSource ds); /** * This is the method to be used to create * a record in the Student table. */ public void create(String name, Integer age); /** * This is the method to be used to list down * a record from the Student table corresponding * to a passed student id. */ public Student getStudent(Integer id); /** * This is the method to be used to list down * all the records from the Student table. */ public List<Student> listStudents(); }
以下是Student.java文件的內(nèi)容:
package com.yiibai; public class Student { private Integer age; private String name; private Integer id; public void setAge(Integer age) { this.age = age; } public Integer getAge() { return age; } public void setName(String name) { this.name = name; } public String getName() { return name; } public void setId(Integer id) { this.id = id; } public Integer getId() { return id; } }
以下是StudentMapper.java文件的內(nèi)容:
package com.yiibai; import java.sql.ResultSet; import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; public class StudentMapper implements RowMapper<Student> { public Student mapRow(ResultSet rs, int rowNum) throws SQLException { Student student = new Student(); student.setId(rs.getInt("id")); student.setName(rs.getString("name")); student.setAge(rs.getInt("age")); return student; } }
下面是實(shí)現(xiàn)類文件StudentJDBCTemplate.java定義DAO接口StudentDAO:
package com.yiibai; import java.util.Map; import javax.sql.DataSource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.namedparam.MapSqlParameterSource; import org.springframework.jdbc.core.namedparam.SqlParameterSource; import org.springframework.jdbc.core.simple.SimpleJdbcCall; public class StudentJDBCTemplate implements StudentDAO { private DataSource dataSource; private SimpleJdbcCall jdbcCall; public void setDataSource(DataSource dataSource) { this.dataSource = dataSource; this.jdbcCall = new SimpleJdbcCall(dataSource). withProcedureName("getRecord"); } public void create(String name, Integer age) { JdbcTemplate jdbcTemplateObject = new JdbcTemplate(dataSource); String SQL = "insert into Student (name, age) values (?, ?)"; jdbcTemplateObject.update( SQL, name, age); System.out.println("Created Record Name = " + name + " Age = " + age); return; } public Student getStudent(Integer id) { SqlParameterSource in = new MapSqlParameterSource(). addValue("in_id", id); Map<String, Object> out = jdbcCall.execute(in); Student student = new Student(); student.setId(id); student.setName((String) out.get("out_name")); student.setAge((Integer) out.get("out_age")); return student; } public List<Student> listStudents() { String SQL = "select * from Student"; List <Student> students = jdbcTemplateObject.query(SQL, new StudentMapper()); return students; } }
關(guān)于上面的程序幾句話:你寫的調(diào)用的執(zhí)行代碼時,需要創(chuàng)建包含IN參數(shù)的一個SqlParameterSource。重要的是要配合提供與存儲過程中聲明的參數(shù)名的輸入值的名稱。 execute方法接收傳入的參數(shù),并返回包含任何列在存儲過程中指定的名稱鍵入?yún)?shù)的映射。現(xiàn)在讓我們修改主應(yīng)用程序文件MainApp.java,這是如下:
package com.yiibai; import java.util.List; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import com.yiibai.StudentJDBCTemplate; public class MainApp { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("Beans.xml"); StudentJDBCTemplate studentJDBCTemplate = (StudentJDBCTemplate)context.getBean("studentJDBCTemplate"); System.out.println("------Records Creation--------" ); studentJDBCTemplate.create("Zara", 11); studentJDBCTemplate.create("Nuha", 2); studentJDBCTemplate.create("Ayan", 15); System.out.println("------Listing Multiple Records--------" ); List<Student> students = studentJDBCTemplate.listStudents(); for (Student record : students) { System.out.print("ID : " + record.getId() ); System.out.print(", Name : " + record.getName() ); System.out.println(", Age : " + record.getAge()); } System.out.println("----Listing Record with ID = 2 -----" ); Student student = studentJDBCTemplate.getStudent(2); System.out.print("ID : " + student.getId() ); System.out.print(", Name : " + student.getName() ); System.out.println(", Age : " + student.getAge()); } }
以下是配置文件beans.xml文件:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd "> <!-- Initialization for data source --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/TEST"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <!-- Definition for studentJDBCTemplate bean --> <bean id="studentJDBCTemplate" class="com.yiibai.StudentJDBCTemplate"> <property name="dataSource" ref="dataSource" /> </bean> </beans>
創(chuàng)建源代碼和bean配置文件完成后,讓我們運(yùn)行應(yīng)用程序。如果一切順利,這將打印以下信息:
------Records Creation-------- Created Record Name = Zara Age = 11 Created Record Name = Nuha Age = 2 Created Record Name = Ayan Age = 15 ------Listing Multiple Records-------- ID : 1, Name : Zara, Age : 11 ID : 2, Name : Nuha, Age : 2 ID : 3, Name : Ayan, Age : 15 ----Listing Record with ID = 2 ----- ID : 2, Name : Nuha, Age : 2
相關(guān)文章
java使用poi讀取ppt文件和poi讀取excel、word示例
這篇文章主要介紹了java使用poi讀取ppt文件和poi讀取excel、word示例,需要的朋友可以參考下2014-03-03深入理解Java線程池從設(shè)計(jì)思想到源碼解讀
這篇文章主要介紹了深入理解Java線程池從設(shè)計(jì)思想到源碼解讀,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-03-03java編寫一個花名隨機(jī)抽取器的實(shí)現(xiàn)示例
這篇文章主要介紹了java編寫一個花名隨機(jī)抽取器的實(shí)現(xiàn)示例,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-03-03使用spring?data的page和pageable如何實(shí)現(xiàn)分頁查詢
這篇文章主要介紹了使用spring?data的page和pageable如何實(shí)現(xiàn)分頁查詢,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-12-12Maven的生命周期與自定義插件實(shí)現(xiàn)方法
Maven的生命周期就是對所有的構(gòu)建過程進(jìn)行抽象和統(tǒng)一。包含了項(xiàng)目的清理、初始化、編譯、測試、打包、集成測試、驗(yàn)證、部署和站點(diǎn)生成等幾乎所有的構(gòu)建步驟2022-12-12