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); } }
当然,在实际的开发过程中我们并不会这么写,因为如果后期我们需要修改数据库,那么不得不修改代码。这时候我们就需要利用到配置文件了,结合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>
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; } }
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()); } }
可是这样就结束了嘛?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>
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
<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>