第五章 征服数据库

5.1 数据库的访问哲学

  DAO是数据访问对象(data access object)的缩写。

5.1.1 了解Spring的数据访问异常体系

 可能抛出的SQLException常见问题:

  • 应用程序无法连接数据库;
  • 要执行的查询有语法错误
  • 查询中所使用的表和列不存在
  • 视图插入或更新数据违反了数据库完整性约束

Spring的凭条无关持久化异常

spring的异常都继承自DataAccessException(他是一个非检查型异常)。

5.1.2 数据访问模板化

spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类:模板类(template)和回调(callback)。模板管理过程汇总固定的部分,回调处理自定义的数据访问代码。

5.1.3 使用DAO支持类

应用程序的DAO继承自JdbcDaoSupport,调用getJdbcTemplate()方法获得JcbcTemplate;可以直接处理JDBC连接;

5.2 配置数据源

spring提供了在Spring上下文配置数据源Bean的多种方式,包括:

  • 通过JDBC驱动成语定义的数据源
  • 通过JNDI查找数据源
  • 连接池的数据源

5.2.1 使用JNDI数据源

 先略过....

5.2.2 使用数据源连接池

首先配置pom.xml,用dbcp的jar提供连接池功能:

1 <!-- 配置数据源的链接dbcp( 提供链接池功能)-->
2       <dependency>
3         <groupId>commons-dbcp</groupId>
4         <artifactId>commons-dbcp</artifactId>
5         <version>1.3</version>
6     </dependency>
View Code

下载的jar包如下:

在springbean.xml中配置:

1 <!--基于dbcp 配置数据源 -->
2      <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
3          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
4          <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
5          <property name="username" value="root"></property>
6          <property name="password" value="mysql"></property>
7          <property name="initialSize" value="5"></property>
8          <property name="maxActive" value="10"></property>
9      </bean>
View Code

测试代码:

 1 package com.springinaction.test;
 2 
 3 import org.apache.commons.dbcp.BasicDataSource;
 4 import org.junit.Test;
 5 
 6 
 7 import org.springframework.context.ApplicationContext;
 8 import org.springframework.context.support.ClassPathXmlApplicationContext;
 9 
10 import com.springinaction.springidol.Auditorium;
11 import com.springinaction.springidol.Instrumentalist;
12 import com.springinaction.springidol.Magician;
13 import com.springinaction.springidol.MindReader;
14 import com.springinaction.springidol.OneManBand;
15 import com.springinaction.springidol.Performer;
16 import com.springinaction.springidol.PoeticJuggler;
17 import com.springinaction.springidol.Stage;
18 import com.springinaction.springidol.Thinker;
19 import com.springinaction.springidol.Ticket;
20 import com.springinaction.springidol.Volunteer;
21 
22 
23 public class TestCase {
24     
25     //这个ClassPathXmlApplicationContext是springframe-context中
26     //org.springframework.context.support包下的类
27     ApplicationContext ac = new ClassPathXmlApplicationContext("spring/springbean.xml");//注意路径
28     
29     //测试数据源配置
30     @Test
31     public void testData() throws Exception {
32         
33         BasicDataSource dataSource = (BasicDataSource)ac.getBean("dataSource");
34 
35         System.out.println(dataSource.getInitialSize());
36         
37         System.out.println(dataSource.getDriverClassName());
38 
39     }
40     
41     
42     
43 }
View Code

结果如下:

5.2.3 基于JDBC驱动的数据源

spring提供了两种数据源供选择(org.springframework,jdbc,datasource):

  • DriverManagerDataSource:在每个连接请求时都会范湖一个新建的链接。与DBCP的BasicDataSource不同,由DriverManagerDataSource提供的链接并没有进行池化管理。
  • SingleConnectionDataSource:在每个链接请求时都会返回同一个链接,

配置spring-jdbc,首先pom.xml中:

1 <!-- spring-jdbc配置数据源 -->
2     <dependency>
3         <groupId>org.springframework</groupId>
4         <artifactId>spring-jdbc</artifactId>
5         <version>4.2.9.RELEASE</version>
6     </dependency>
View Code

会引进两个包,一个jdbc包,一个事物处理包:

1  <!--基于dbcp 配置数据源 -->
2      <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
3          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
4          <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
5          <property name="username" value="root"></property>
6          <property name="password" value="mysql"></property>
7          <!-- <property name="initialSize" value="5"></property>
8          <property name="maxActive" value="10"></property> -->
9      </bean>
View Code

在pom.xml配置中引入mysql数据库的驱动包:

1 <!-- mysql的链接的驱动包 -->
2     <dependency>
3         <groupId>mysql</groupId>
4         <artifactId>mysql-connector-java</artifactId>
5         <version>5.1.40</version>
6     </dependency>
View Code

 1 //测试spring数据源配置
 2     @Test
 3     public void testSpringData() throws Exception {
 4         
 5         DriverManagerDataSource dataSource = (DriverManagerDataSource)ac.getBean("dataSource");
 6         
 7         Connection connection = dataSource.getConnection();
 8     
 9         Statement createStatement = connection.createStatement();
10         
11         ResultSet rs = createStatement.executeQuery("select * from  user");
12         
13         while(rs.next()){
14             System.out.println(rs.getString("username"));
15         }
16         
17     }
View Code

结果:

5.3 在Spring中使用JDBC

5.3.1 失控的JDBC代码

原生的jdbc代码,创建链接和处理异常,以及关闭链接等都是一样的操作。可以将其提取出来成为一个模板。

5.3.2 使用JDBC模板

spring将数据访问的样板式代码提取到模板类中。Spring为JDBC提供了3个模板类使用:

  • JdbcTemplate:最基本的Spring JDBC模板,这个模板支持最简单的JDBC数据库访问功能以及简单的索引参数查询。
  • NameParameterJDbcTeplate:使用该模板类执行查询时,可以将查询值以命名参数的形式绑定带SQL中,而不是见到你的索引参数。
  • SimpleJdbcTemplate:该模板类利用Java5的一些特性,如自定装箱、泛型以及可变参数列表来简化JDBC模板使用;

使用SimpleJdbcTemplate访问数据库(写完之后发现Spring3.0.0左右的版本有SimpleJdbcTemplate这个类,而我之前一直用的4.2.9这个版本,于是,为了配合这本书,又换成了老版本,技术更新的快,这本书老了):

用法不难:

首先数据库表(创建如下的表,我用的mysql,数据随便写):

需要下面几个类:

model:

 1 package com.springinaction.model;
 2 
 3 /**
 4  * 
 5  * @ClassName: User 
 6  * @Description: 用户的model类
 7  * @author mao
 8  * @date 2017年3月29日 下午11:57:39 
 9  *
10  */
11 public class User {
12     
13     private int id;
14     private String userName;
15     private String birthday;
16     private String sex;
17     private String address;
18     
19     public User() {
20         
21     }
22 
23     public int getId() {
24         return id;
25     }
26 
27     public void setId(int id) {
28         this.id = id;
29     }
30 
31     public String getUserName() {
32         return userName;
33     }
34 
35     public void setUserName(String userName) {
36         this.userName = userName;
37     }
38 
39     public String getBirthday() {
40         return birthday;
41     }
42 
43     public void setBirthday(String birthday) {
44         this.birthday = birthday;
45     }
46 
47     public String getSex() {
48         return sex;
49     }
50 
51     public void setSex(String sex) {
52         this.sex = sex;
53     }
54 
55     public String getAddress() {
56         return address;
57     }
58 
59     public void setAddress(String address) {
60         this.address = address;
61     }
62 
63     @Override
64     public String toString() {
65         return "User [id=" + id + ", userName=" + userName + ", birthday="
66                 + birthday + ", sex=" + sex + ", address=" + address + "]";
67     }
68     
69     
70     
71     
72     
73 }
View Code

dao接口:

 1 package com.springinaction.dao;
 2 
 3 import com.springinaction.model.User;
 4 
 5 /**
 6  * 
 7  * @ClassName: UserDao 
 8  * @Description: 用户dao的接口
 9  * @author mao
10  * @date 2017年3月29日 下午11:58:50 
11  *
12  */
13 public interface UserDao {
14     
15     public void addUser(User user);
16     
17 }
View Code

dao的实现类(可以看到里面的东西都过时了,被划了横线):

 1 package com.springinaction.dao.impl;
 2 
 3 import org.springframework.jdbc.core.simple.SimpleJdbcTemplate;
 4 
 5 import com.springinaction.dao.UserDao;
 6 import com.springinaction.model.User;
 7 
 8 /**
 9  * 
10  * @ClassName: JdbcUserDao 
11  * @Description: UserDao的实现类
12  * @author mao
13  * @date 2017年3月29日 下午11:59:45 
14  *
15  */
16 public class JdbcUserDao implements UserDao{
17     
18     //过时了都,4.2.9版本都没有这个类,哎,这书太老了
19     private SimpleJdbcTemplate jdbcTemplate;
20     
21     public void setJdbcTemplate(SimpleJdbcTemplate jdbcTemplate) {
22         this.jdbcTemplate = jdbcTemplate;
23     }
24     
25     public void addUser(User user){
26         
27         jdbcTemplate.update("update user set username=? where id=?",
28                 user.getUserName(),
29                 user.getId()
30                 );
31     }
32 }
View Code

springbean.xml

 1 <?xml version="1.0" encoding="UTF-8"?>
 2 <beans xmlns="http://www.springframework.org/schema/beans"
 3     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 4     xmlns:context="http://www.springframework.org/schema/context"
 5     xmlns:aop="http://www.springframework.org/schema/aop" 
 6     xmlns:p="http://www.springframework.org/schema/p"
 7     xsi:schemaLocation="http://www.springframework.org/schema/beans 
 8         http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
 9         http://www.springframework.org/schema/context
10         http://www.springframework.org/schema/context/spring-context-4.0.xsd
11         http://www.springframework.org/schema/aop 
12         http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
13     
14     
15      <!--注解形式的 组件扫描 -->
16      <context:component-scan 
17         base-package="com.springinaction.springidol"></context:component-scan>
18      
19      
20      <!--基于dbcp 配置数据源 -->
21      <!-- <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
22          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
23          <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
24          <property name="username" value="root"></property>
25          <property name="password" value="mysql"></property>
26          <property name="initialSize" value="5"></property>
27          <property name="maxActive" value="10"></property>
28      </bean> -->
29      
30      <!--基于dbcp 配置数据源 -->
31      <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
32          <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
33          <property name="url" value="jdbc:mysql://localhost:3306/test"></property>
34          <property name="username" value="root"></property>
35          <property name="password" value="mysql"></property>
36          <!-- <property name="initialSize" value="5"></property>
37          <property name="maxActive" value="10"></property> -->
38      </bean>
39     
40     <!-- 使用SimpleJdbcTemplate -->
41     <bean id="jdbcTemplate" class="org.springframework.jdbc.core.simple.SimpleJdbcTemplate">
42         <constructor-arg ref="dataSource"/>
43     </bean>
44     
45     <!-- dao层 -->
46     <bean id="jdbcUserDao" class="com.springinaction.dao.impl.JdbcUserDao">
47         <property name="jdbcTemplate" ref="jdbcTemplate"></property>
48     </bean>
49     
50 </beans>
View Code

测试代码:

 1 //测试SimpleJdbcTemplate
 2     //测试spring数据源配置
 3     @Test
 4     public void testTemplate() throws Exception {
 5         
 6         UserDao userDao = (UserDao)ac.getBean("jdbcUserDao");
 7         
 8         User user = new User();
 9         user.setId(1);
10         user.setUserName("测试用户");
11         userDao.addUser(user);
12         
13         
14     }
View Code

测试是是成功的,整个过程也可以用注解扫面的方式,不是很难,就是过时了;

 源码下载地址

posted @ 2017-03-28 23:16  花雪依蒿  阅读(142)  评论(0编辑  收藏  举报