在Java的Spring框架的程序中使用JDBC API操作数据库
同时与数据库使用普通的旧JDBC的工作,它变得繁琐写不必要的代码来处理异常,打开和关闭数据库连接等,但Spring的JDBC框架需要的所有低层次细节从打开连接,准备和执行SQL语句,过程异常,处理事务,最后关闭连接。
所以,你所要做的只是定义连接参数,并指定要执行的SQL语句,并做必要的工作,在每次迭代时从数据库中获取数据。
SpringJDBC提供了一些方法和相应不同的类与数据库进行交互。我要采取经典和最流行的做法,利用JdbcTemplateclass框架。这是管理的所有数据库的通信和异常处理中心框架类。
JdbcTemplate类
JdbcTemplate类执行SQL查询,更新语句和存储过程调用,在结果集和提取返回参数值进行迭代。它还捕捉JDBC的异常并将其转换为通用的,信息更丰富,除了在org.springframework.dao包中定义的层次结构。
JdbcTemplate类的实例是一次配置的线程。所以,你可以配置一个JdbcTemplate的一个实例,然后安全地注入这种共享引用到多个DAO。
使用JdbcTemplate类时,通常的做法是配置一个DataSource在Spring配置文件,然后依赖关系注入该共享数据源豆到DAO类,JdbcTemplate或者是在setter数据源创建。
配置数据源
让我们一起创造数据库test数据库表的student。假设使用MySQL数据库,如果使用其他数据库,那么可以相应地改变你的DDL和SQL查询。
CREATETABLEStudent( IDINTNOTNULLAUTO_INCREMENT, NAMEVARCHAR(20)NOTNULL, AGEINTNOTNULL, PRIMARYKEY(ID) );
现在,我们需要提供一个数据源给JdbcTemplate类,因此它可以自行配置,以获得数据库访问。您可以配置数据源的XML文件中有一段代码,如下图所示:
<beanid="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/> <propertyname="url"value="jdbc:mysql://localhost:3306/TEST"/> <propertyname="username"value="root"/> <propertyname="password"value="password"/> </bean>
数据访问对象(DAO)
DAO表示这是通常用于数据库交互的数据访问对象。DAO的存在是为了提供读取和写入数据到数据库中,他们应该通过该应用程序的其余部分将访问它们的接口公开此功能的一种手段。
在Spring的数据访问对象(DAO)的支持使得它很容易与如JDBC,Hibernate,JPA和JDO以一致的方式进行数据访问技术。
执行SQL语句
让我们来看看如何使用SQL和的JdbcTemplate对象数据库中的表执行CRUD(创建,读取,更新和删除)操作。
查询一个整数:
StringSQL="selectcount(*)fromStudent"; introwCount=jdbcTemplateObject.queryForInt(SQL);
查询长整数:
StringSQL="selectcount(*)fromStudent"; longrowCount=jdbcTemplateObject.queryForLong(SQL);
使用绑定变量的简单查询:
StringSQL="selectagefromStudentwhereid=?";
intage=jdbcTemplateObject.queryForInt(SQL,newObject[]{10});
在查询字符串:
StringSQL="selectnamefromStudentwhereid=?";
Stringname=jdbcTemplateObject.queryForObject(SQL,newObject[]{10},String.class);
查询并返回一个对象:
StringSQL="select*fromStudentwhereid=?";
Studentstudent=jdbcTemplateObject.queryForObject(SQL,
newObject[]{10},newStudentMapper());
publicclassStudentMapperimplementsRowMapper<Student>{
publicStudentmapRow(ResultSetrs,introwNum)throwsSQLException{
Studentstudent=newStudent();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
returnstudent;
}
}
查询并返回多个对象:
StringSQL="select*fromStudent";
List<Student>students=jdbcTemplateObject.query(SQL,
newStudentMapper());
publicclassStudentMapperimplementsRowMapper<Student>{
publicStudentmapRow(ResultSetrs,introwNum)throwsSQLException{
Studentstudent=newStudent();
student.setID(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
returnstudent;
}
}
插入一行到表:
StringSQL="insertintoStudent(name,age)values(?,?)";
jdbcTemplateObject.update(SQL,newObject[]{"Zara",11});
更新一行到表:
StringSQL="updateStudentsetname=?whereid=?";
jdbcTemplateObject.update(SQL,newObject[]{"Zara",10});
从表中删除行:
StringSQL="deleteStudentwhereid=?";
jdbcTemplateObject.update(SQL,newObject[]{20});
执行DDL语句
您可以使用execute(...)方法的JdbcTemplate来执行任何SQL语句或DDL语句。下面是一个示例使用CREATE语句创建一个表:
StringSQL="CREATETABLEStudent("+
"IDINTNOTNULLAUTO_INCREMENT,"+
"NAMEVARCHAR(20)NOTNULL,"+
"AGEINTNOTNULL,"+
"PRIMARYKEY(ID));"
jdbcTemplateObject.execute(SQL);
SQL存储过程
SimpleJdbcCall的类可以用来调用带有IN和OUT参数的存储过程。你可以使用这种方法,而与任何喜欢的ApacheDerby,DB2,MySQL和微软SQL服务器,Oracle和SybaseRDBMS中的工作。
其次,考虑以下的MySQL存储过程这需要学生证和用OUT参数对应的学生的姓名和年龄的回报。因此,让我们使用MySQL命令提示符下在测试数据库中创建该存储过程:
DELIMITER$$ DROPPROCEDUREIFEXISTS`TEST`.`getRecord`$$ CREATEPROCEDURE`TEST`.`getRecord`( INin_idINTEGER, OUTout_nameVARCHAR(20), OUTout_ageINTEGER) BEGIN SELECTname,age INTOout_name,out_age FROMStudentwhereid=in_id; END$$ DELIMITER;
现在让我们写了SpringJDBC应用程序,将执行我们的学生桌简单的创建和读取操作。
来创建一个Spring应用程序:
以下是数据访问对象接口文件StudentDAO.java的内容:
packagecom.yiibai;
importjava.util.List;
importjavax.sql.DataSource;
publicinterfaceStudentDAO{
/**
*Thisisthemethodtobeusedtoinitialize
*databaseresourcesie.connection.
*/
publicvoidsetDataSource(DataSourceds);
/**
*Thisisthemethodtobeusedtocreate
*arecordintheStudenttable.
*/
publicvoidcreate(Stringname,Integerage);
/**
*Thisisthemethodtobeusedtolistdown
*arecordfromtheStudenttablecorresponding
*toapassedstudentid.
*/
publicStudentgetStudent(Integerid);
/**
*Thisisthemethodtobeusedtolistdown
*alltherecordsfromtheStudenttable.
*/
publicList<Student>listStudents();
}
以下是Student.java文件的内容:
packagecom.yiibai;
publicclassStudent{
privateIntegerage;
privateStringname;
privateIntegerid;
publicvoidsetAge(Integerage){
this.age=age;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicStringgetName(){
returnname;
}
publicvoidsetId(Integerid){
this.id=id;
}
publicIntegergetId(){
returnid;
}
}
以下是StudentMapper.java文件的内容:
packagecom.yiibai;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importorg.springframework.jdbc.core.RowMapper;
publicclassStudentMapperimplementsRowMapper<Student>{
publicStudentmapRow(ResultSetrs,introwNum)throwsSQLException{
Studentstudent=newStudent();
student.setId(rs.getInt("id"));
student.setName(rs.getString("name"));
student.setAge(rs.getInt("age"));
returnstudent;
}
}
下面是实现类文件StudentJDBCTemplate.java定义DAO接口StudentDAO:
packagecom.yiibai;
importjava.util.Map;
importjavax.sql.DataSource;
importorg.springframework.jdbc.core.JdbcTemplate;
importorg.springframework.jdbc.core.namedparam.MapSqlParameterSource;
importorg.springframework.jdbc.core.namedparam.SqlParameterSource;
importorg.springframework.jdbc.core.simple.SimpleJdbcCall;
publicclassStudentJDBCTemplateimplementsStudentDAO{
privateDataSourcedataSource;
privateSimpleJdbcCalljdbcCall;
publicvoidsetDataSource(DataSourcedataSource){
this.dataSource=dataSource;
this.jdbcCall=newSimpleJdbcCall(dataSource).
withProcedureName("getRecord");
}
publicvoidcreate(Stringname,Integerage){
JdbcTemplatejdbcTemplateObject=newJdbcTemplate(dataSource);
StringSQL="insertintoStudent(name,age)values(?,?)";
jdbcTemplateObject.update(SQL,name,age);
System.out.println("CreatedRecordName="+name+"Age="+age);
return;
}
publicStudentgetStudent(Integerid){
SqlParameterSourcein=newMapSqlParameterSource().
addValue("in_id",id);
Map<String,Object>out=jdbcCall.execute(in);
Studentstudent=newStudent();
student.setId(id);
student.setName((String)out.get("out_name"));
student.setAge((Integer)out.get("out_age"));
returnstudent;
}
publicList<Student>listStudents(){
StringSQL="select*fromStudent";
List<Student>students=jdbcTemplateObject.query(SQL,
newStudentMapper());
returnstudents;
}
}
关于上面的程序几句话:你写的调用的执行代码时,需要创建包含IN参数的一个SqlParameterSource。重要的是要配合提供与存储过程中声明的参数名的输入值的名称。execute方法接收传入的参数,并返回包含任何列在存储过程中指定的名称键入参数的映射。现在让我们修改主应用程序文件MainApp.java,这是如下:
packagecom.yiibai;
importjava.util.List;
importorg.springframework.context.ApplicationContext;
importorg.springframework.context.support.ClassPathXmlApplicationContext;
importcom.yiibai.StudentJDBCTemplate;
publicclassMainApp{
publicstaticvoidmain(String[]args){
ApplicationContextcontext=
newClassPathXmlApplicationContext("Beans.xml");
StudentJDBCTemplatestudentJDBCTemplate=
(StudentJDBCTemplate)context.getBean("studentJDBCTemplate");
System.out.println("------RecordsCreation--------");
studentJDBCTemplate.create("Zara",11);
studentJDBCTemplate.create("Nuha",2);
studentJDBCTemplate.create("Ayan",15);
System.out.println("------ListingMultipleRecords--------");
List<Student>students=studentJDBCTemplate.listStudents();
for(Studentrecord:students){
System.out.print("ID:"+record.getId());
System.out.print(",Name:"+record.getName());
System.out.println(",Age:"+record.getAge());
}
System.out.println("----ListingRecordwithID=2-----");
Studentstudent=studentJDBCTemplate.getStudent(2);
System.out.print("ID:"+student.getId());
System.out.print(",Name:"+student.getName());
System.out.println(",Age:"+student.getAge());
}
}
以下是配置文件beans.xml文件:
<?xmlversion="1.0"encoding="UTF-8"?> <beansxmlns="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"> <!--Initializationfordatasource--> <beanid="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <propertyname="driverClassName"value="com.mysql.jdbc.Driver"/> <propertyname="url"value="jdbc:mysql://localhost:3306/TEST"/> <propertyname="username"value="root"/> <propertyname="password"value="password"/> </bean> <!--DefinitionforstudentJDBCTemplatebean--> <beanid="studentJDBCTemplate" class="com.yiibai.StudentJDBCTemplate"> <propertyname="dataSource"ref="dataSource"/> </bean> </beans>
创建源代码和bean配置文件完成后,让我们运行应用程序。如果一切顺利,这将打印以下信息:
------RecordsCreation-------- CreatedRecordName=ZaraAge=11 CreatedRecordName=NuhaAge=2 CreatedRecordName=AyanAge=15 ------ListingMultipleRecords-------- ID:1,Name:Zara,Age:11 ID:2,Name:Nuha,Age:2 ID:3,Name:Ayan,Age:15 ----ListingRecordwithID=2----- ID:2,Name:Nuha,Age:2