1. 引言
- Spring最重要的功能是操作数据。在Java互联网项目中,数据大部分存储在数据库或者NoSQL工具中。本篇博客主要介绍Spring如何操作数据库。Spring为开发者提供了JDBC模板模式,就是自身的jdbcTemplate,他可以简化许多代码的编程,但是在实际工作中并不常用。
- 在工作中更多的是使用Hibernate和MyBatis框架,对于Hibernate矿架,Spring提供了HibernateTemplate给与支持,有效简化了Hibernate的编程。对于MyBatis,MyBatis社区开发了接入Spring的开发包,该包提供了SqlSessionTemplate给开发者使用,该包还可以屏蔽SqlSessionTemplate这样的功能性代码,可以在编程中擦除SqlSessionTemplate让开发者直接使用接口编程,大大提高了编程的可读性。
- 个人理解:推荐使用mybatis框架,并且使用接口编程
2. 传统JDBC代码的弊端
- 传统的JDBC代码过程太过复杂,执行一条简单的SQL语句时,先打开数据库连接执行SQL,然后组装结果,最后关闭数据源,中间有太多的try…catch…finally…语句,造成代码的泛滥。
- 当发生异常时就会回滚,否自提交数据,模式比较固定。
3. 配置数据源
在Sping中配置数据库资源很简单,在实际工作中,大部分会配置为数据库连接池,我们既可以使用Spring内部提供的类,也可以使用第三方数据库连接池或者从web服务器中通过JNDI获取数据源。一般在工程中会采用XML方式进行配置,但是也可以使用注解方式进行配置。对于项目的公共资源,建议采用XML方式进行配置,方便查找公共源。
先简单介绍一下 连接池的原理:当一个应用要操作数据库时就要连接数据库,可以事先在连接池中创建几个数据库连接放着,当我们要操作数据库时,从数据库连接池中直接拿来用,并且标记为忙,使用完之后,放回连接池,标记为空闲。如果连接池中的数据库连接不够用时,可以在连接池中创建连接,连接的数量可以进行控制。
3.1. 使用spring自带的数据源
Spring中提供了一个类org.springframework.jdbc.datasource.SimpleDriverDataSource,此类不支持数据库连接池,可以用XMl方式进行配置。
配置完成之后就是一个简单的数据源,一般用于测试。
<!-- 配置SimpleDriverDataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.SimpleDriverDataSource">
<property name="username" value="root"/>
<property name="password" value="123"/>
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/springmvc"/>
</bean>
注意:
- 使用此数据源需要导入的jar包为spring-jdbc.jar
- property属性中name的值与DBCP数据源name值有所不同。
- 注意value值前后不能有空格
3.2. 使用DBCP数据源
<!-- 配置datasource -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.username}" />
<property name="password" value="${database.password}" />
</bean>
注意:
- DBCP的配置依赖于2个jar包commons-dbcp.jar,commons-pool.jar。
- property属性中name的值与其他数据源name值有所不同。
- 注意value值前后不能有空格
3.3. 使用c3p0数据源
C3P0是一个开放源代码的JDBC数据源实现项目,C3P0依赖于jar包c3p0.jar
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver"/>
<property name="jdbcUrl" value="jdbc:mysql://localhost:3306/springmvc"/>
<property name="user" value="root"/>
<property name="password" value="root"/>
</bean>
c3p0比DBCP有更丰富的配置属性。
3.4. 使用JNDI数据库连接池
如果应用配置在高性能的应用服务器(如WebLogic或Websphere,tomcat等)上,我们可能更希望使用应用服务器本身提供的数据源。应用服务器的数据源 使用JNDI开放调用者使用,Spring为此专门提供引用JNDI资源的JndiObjectFactoryBean类。
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName" value="java:comp/env/jdbc/orclight"/>
</bean>
4. MyBatis-Spring项目配置
目前大部分的Java互联网项目采用的SpringMVC-Spring-MyBatis搭建平台的。使用Spring IoC可以有效管理各类java资源,通过AOP框架,数据库事物可以委托给Spring来处理。
4.1. 配置Spring-MyBatis项目的步骤(5步)
- 配置数据源datasource
- 配置SqlSessionFactory(可以配置SqlSessionTemplate,在同时配置SqlSessionTemplate和SqlSessionFactory的情况下,优先采用SqlSessionTemplate,此中配置不推荐使用,会使用即可)
- 配置Mapper,可以配置单个Mapper,也可以通过扫描的方法生成Mapper,比较灵活。
- 事物管理
4.2. 配置SqlSessionFactoryBean
在MyBatis项目中,要通过SqlSessionFactory生成SqlSession。
在MyBatis-Spring项目中使用SqlSessionFactoryBean去支持SqlSessionFactory的配置。
<!--在Spring的配置文件(生成IoC容器的xml文件)中进行配置-->
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!--dataSource属性指定要用到的连接池-->
<property name="dataSource" ref="dataSource" />
<!--configLocation属性指定mybatis的核心配置文件-->
<property name="configLocation" value="MyBatis_Spring/mybatis-config.xml" />
</bean>
4.3. mapper的配置
MyBatis的运行只需要提供一个类似于RoleMapper.java的接口,无需提供一个实现类,通过学习MyBatis的运行原理,可以知道这个实现类由MyBatis体系创建的动态代理对象运行的,所以Spring也没有办法为其生成实现类。
有三种配置方法:
- 原始dao接入的配置方法
- 配置MapperFactoryBean的bean对象,写好dao接口,让spring生成代理对象,此种方法的缺点是:当有很多个mapper需要配置时,需要一个个配置文件去手动配置。
- 批量配置mapper,使用MapperScannerConfigurer(推荐使用)
4.3.1. 配置MapperFactoryBean
我们可以通过配置MapperFactoryBean类作为中介,来实现Mapper。
<!--项目比较大的时候,会有很大的配置量-->
<!-- 配置mapperFactoryBean -->
<bean id="role" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- Mapper接口将被扫描为Mapper -->
<property name="mapperInterface" value="Mapper接口的全限类名称"/>
<property name="SqlSessionFactory" ref="sqlSessionFactory"/>
<!-- 如果同时注入SqlSessionFactory和SqlSessionTemplate,则会使用SqlSessionTemplate -->
<!--
<property name="SqlSessionTemplate" ref="sqlSessionTemplate"/>
-->
</bean>
当这样配置后,使用下面代码获取映射器:
RoleMapper roleMapper = ctx.getBean(RoleMapper.class);
//在MyBatis中使用下面这种方式
//获取mapper接口的代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
4.3.2. 配置MapperScannerConfigurer
这是通过扫描的形式配置Mapper的类。
<!--配置MapperScannerConfigurer-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basepackage" value="Mapper接口的包路径"/>
<property name="SqlsessionFactoryBeanName"value="指定的上面配置的SqlSessionFactory"/>
<!-- 指定标注才扫描成Mapper -->
<property name="annotationClass" value="org.springframework.sterotype.Repository"/>
</bean>
- annotationClass:表示如果类被这个注解标识的时候,才进行扫描。在Spring中常常使用@Repository注解表示数据访问层(DAO).
- basePackage:指定让Spring自动扫描什么包,他会逐层深入扫描,如果遇到多个包,可以使用半角逗号分割。mapper接口要与对应的mapper.xml文件放在同一个目录下,并且名称相同。
- SqlSessionFactoryBeanName:指定在Spring中定义的SqlSessionFactory的Bean的名称。
- MapperInterface:指定实现了什么接口就认为他是Mapper
对于Mapper接口,使用@Repository注解,它标志这是一个DAO层。然后指定扫描那个包,就能扫描出对应的Mapper到Spring IoC容器中。
接口的编写方式:
//注意注解@Repository是用在接口上
@Repository
public interface RoleMapper {
//添加数据
public int insertRole(Role role);
}