JDBC,对于所有的JAVA开发人员来说,是很熟悉的一项JAVA 技术。大多数Java程序员都曾使用JDK中的JDBC Api进行数据库的程序编程。由于JDBC API过程过于底层,所以开发者不但需要编写数据操作代码,还需要编写获取JDBC连接、处理异常,释放资源等代码。这些代码对于程序员实现业务功能并没有什么帮助,还会影响开发效率。Spring Jdbc为我们提供了一个数据库操作框架Spring JDBC,将我们不需要关系的代码封装起来,将我们的关注点放在业务实现上。
下面我们看看Spring JDBC是怎么实现操作数据库操作的。
package com.majing.jdbc.all;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
/**
* 直接通过代码实现SpringJDBC功能
* @author majing
*
*/
public class FirstLesson {
public static void main(String[] args) {
DriverManagerDataSource ds = new DriverManagerDataSource();
ds.setDriverClassName("com.mysql.jdbc.Driver");
ds.setUrl("jdbc:mysql://localhost:3306/translateoffice");
ds.setUsername("root");
ds.setPassword("19880927");
JdbcTemplate jdbcTemplate = new JdbcTemplate();
jdbcTemplate.setDataSource(ds);
String sql = "select * from user";
final List<User> users = new ArrayList<User>();
jdbcTemplate.query(sql, new RowCallbackHandler() {
@Override
public void processRow(ResultSet resultSet) throws SQLException {
if (resultSet != null) {
do {
User each = new User();
each.setId(resultSet.getInt("id"));
each.setUsername(resultSet.getString("username"));
each.setPassword(resultSet.getString("password"));
each.setRole(resultSet.getInt("role"));
each.setPhone(resultSet.getString("phone"));
each.setEmail(resultSet.getString("email"));
each.setExtras(resultSet.getString("extras"));
users.add(each);
resultSet.next();
} while (resultSet.isLast());
}
}
});
System.out.println(users);
}
}
在上述代码中,我们直接在代码中设置数据库驱动、数据库连接URL,用户名和密码等。
当然,在实际的开发过程中我们并不会这么写,因为如果后期我们需要修改数据库,那么不得不修改代码。这时候我们就需要利用到配置文件了,结合Spring的自动注入相关功能。
我们将刚才上面的例子,通过配置文件的方式实现一下。首先自己创建一个配置文件applicationContext.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" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.majing.jdbc.all" />
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName"
value="com.mysql.jdbc.Driver">
</property>
<property name="url"
value="jdbc:mysql://localhost:3306/translateoffice">
</property>
<property name="username" value="root"></property>
<property name="password" value="19880927"></property>
</bean>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
lazy-init="false">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="userDao" class="com.majing.jdbc.all.UserDao">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
</bean>
</beans>
我们还需要编写一个操作数据库的UserDao类,内容如下:
package com.majing.jdbc.all;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowCallbackHandler;
import org.springframework.stereotype.Repository;
@Repository
public class UserDao {
@Autowired
private JdbcTemplate jdbcTemplate;
public JdbcTemplate getJdbcTemplate() {
return jdbcTemplate;
}
public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
this.jdbcTemplate = jdbcTemplate;
}
public User queryUserByName(String username){
String sql = "select * from user where username = ? ";
Object[] params = new Object[]{username};
final User user= new User();
jdbcTemplate.query(sql, params, new RowCallbackHandler(){
@Override
public void processRow(ResultSet rs) throws SQLException {
user.setId(rs.getInt("id"));
user.setUsername(rs.getString("username"));
user.setPassword(rs.getString("password"));
user.setRole(rs.getInt("role"));
user.setPhone(rs.getString("phone"));
user.setEmail(rs.getString("email"));
user.setExtras(rs.getString("extras"));
}
});
return user;
}
}
上述代码中使用到的User类定义如下:
package com.majing.jdbc.all;
import java.io.Serializable;
/**
* @author majing
* 用户实体
*/
public class User implements Serializable{
private static final long serialVersionUID = 4982996394229149942L;
/**
* 主键id,自增长
*/
private int id;
/**
* 用户名
*/
private String username;
/**
* 密码
*/
private String password;
/**
* 用户角色
*/
private int role;
/**
* 电子邮件
*/
private String email = "";
/**
* 手机号码
*/
private String phone = "";
/**
* 额外说明
*/
private String extras = "";
public User(){
super();
}
public User(String username, String password, int role, String email, String phone, String extras){
super();
this.username = username;
this.password = password;
this.role = role;
this.email = email;
this.phone = phone;
this.extras = extras;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getRole() {
return role;
}
public void setRole(int role) {
this.role = role;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getExtras() {
return extras;
}
public void setExtras(String extras) {
this.extras = extras;
}
@Override
public String toString() {
return "User [username=" + username + ", password=" + password
+ ", role=" + role + ", email=" + email + ", phone=" + phone
+ ", extras=" + extras + "]";
}
}
接下来我们需要编写个测试类,看看能否正常运行:
package com.majing.jdbc.all;
import junit.framework.TestCase;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class UserDaoTest extends TestCase{
public void testQueryUserByName(){
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao userdao = (UserDao)ctx.getBean("userDao");
assertEquals("19880927", userdao.queryUserByName("majing").getPassword());
}
}
运行上述测试代码,结果如下:
测试代码运行通过。
当然这里我们既然使用了Spring的自动注入,加上我们这里使用的是Junit4,那么我们在编写测试类的时候使用下面的写法更加简便:
package com.majing.jdbc.all;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"/applicationContext.xml"})
public class TestUserDao {
@Autowired
private UserDao dao;
@Test
public void testQueryUserByName() {
User user = dao.queryUserByName("majing");
assertEquals("19880927", user.getPassword());
}
}
需要注意的是,这里的locations可以加载多个配置文件,在这里“/applicationContext.xml”不能把前面反斜杠“/”给漏掉,否则将出错。
可是这样就结束了嘛?NO!
我们一般在操作数据库的时候,为了提高效率,会使用到连接池,避免频繁的创建和回收数据库连接。解析来我们修改一下上面的配置文件,添加连接池的功能,这里我们使用的是apache提供的dbcp数据库连接池,当然你也可以使用其他连接池。修改后的applicatonContext.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" xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.majing.jdbc.all" />
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:mysql-config-translateoffice.properties" />
</bean>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${driverClassName}" />
<property name="url" value="${url}" />
<property name="username" value="${username}" />
<property name="password" value="${password}" />
<!-- 初始化连接大小 -->
<property name="initialSize" value="${initialSize}"></property>
<!-- 连接池最大数量 -->
<property name="maxActive" value="${maxActive}"></property>
<!-- 连接池最大空闲 -->
<property name="maxIdle" value="${maxIdle}"></property>
<!-- 连接池最小空闲 -->
<property name="minIdle" value="${minIdle}"></property>
<!-- 获取连接最大等待时间 -->
<property name="maxWait" value="${maxWait}"></property>
</bean>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
lazy-init="false">
<property name="dataSource">
<ref bean="dataSource" />
</property>
</bean>
<bean id="userDao" class="com.majing.jdbc.all.UserDao">
<property name="jdbcTemplate">
<ref bean="jdbcTemplate" />
</property>
</bean>
</beans>
在这个配置文件中,我们看到我们新增了一块配置:
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:mysql-config-translateoffice.properties" />
</bean>
这块配置其实就是让我们配置需要连接的数据库连接配置文件的路径,因此还需要在根目录下添加一个mysql-config-translateoffice.properties的配置文件,然后将数据库连接的相关属性进行设置。
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/translateoffice
username=root
password=19880927
initialSize=0
maxActive=20
maxIdle=20
minIdle=1
maxWait=60000
到此为止,我们对如何使用Spring JDBC进行数据库操作的环境搭建进行了一个简单的描述,希望对想了解的朋友有点帮助。下面列出相关的maven依赖:
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>4.0.2.RELEASE</spring.version>
</properties>
<dependencies>
<dependency>
<groupId>commons-dbcp</groupId>
<artifactId>commons-dbcp</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>commons-lang</groupId>
<artifactId>commons-lang</artifactId>
<version>2.6</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.36</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>