Spring与Mybatis的整合
目的:
1) Spring管理SqlSessionFactory
2) Spring管理Mapper代理对象, 在Service层注入Mapper
3) 基于Spring的AOP, 进行事务的控制
1、搭建环境, 导入依赖
spring的jar:
spring-context
spring-test : spring与junit整合
spring-aspects : aop的实现的框架: aspectJ
spring-web : spring 与web的整合
spring-orm : spring与orm模型的整合
spring-tx : spring与事务的整合
mybatis与spring整合的jar:mybatis-spring
oracle的jar: ojdbc14
mybatis的jar : mybatis
c3p0连接池 : c3p0
servlet的jar : javax.servlet-api
jsp的jar : jsp-api
jstl的jar :jstl
junit测试 : junit
slf日志:org.slf4j
<!-- 项目设置 --> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- spring与junit整合 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- aop的实现的框架: aspectJ --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-aspects</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- spring 与web的整合 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- spring与orm模型整合的 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- 事务 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>4.3.3.RELEASE</version> </dependency> <!-- oracle的依赖 --> <dependency> <groupId>com.oracle</groupId> <artifactId>ojdbc14</artifactId> <version>10.2.0.2.0</version> </dependency> <dependency> <!-- mybatis与spring整合的jar --> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>2.0.2</version> </dependency> <!-- mybatis的jar --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.4</version> </dependency> <!-- c3p0连接池 --> <dependency> <groupId>com.mchange</groupId> <artifactId>c3p0</artifactId> <version>0.9.5.2</version> </dependency> <!-- servlet的jar --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> <scope>provided</scope> </dependency> <!-- jsp的jar --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jsp-api</artifactId> <version>2.0</version> <scope>provided</scope> </dependency> <!-- jstl的jar --> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- 日志 --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.25</version> </dependency> </dependencies> <!-- jdk设置为1.8的插件 --> <build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.8</source> <target>1.8</target> <encoding>UTF-8</encoding> </configuration> </plugin> </plugins> </build>
2、导入配置文件
- Spring的配置文件:applicationContext.xml
- Mybatis的配置文件: 两种 Mybatis-config.xml、XxxMapper.xml
- Db.properties 数据库参数文件
- Log4j的配置文件
log4j.properties
log4j.rootCategory=debug, CONSOLE
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=%d{ISO8601} %-6r [%15.15t] %-5p %30.30c %x - %m\n
db.properties
#properties显示中文 右击此文件,点击properties,设置编码为utf-8
jdbc.driverClassName= oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.username=scott
jdbc.password=tiger
#当连接池中的连接耗尽的时候c3p0一次同时获取的连接数。Default: 3
jdbc.acquireIncrement=5
#初始化时获取的连接数,取值应在minPoolSize与maxPoolSize之间。Default: 3
jdbc.initialPoolSize=5
#连接池中保留的最小连接数。
jdbc.minPoolSize=5
#连接池中保留的最大连接数。Default: 15
jdbc.maxPoolSize=10
mybatis-config.xml(都交给spring管理,可以不用写内容)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> </configuration>
applicationContext.xml
1、加载db.properties 文件
<!-- spring配置文件中,属性名 带的location, 在路径前加classpath: 如果不带location, 不加--> <!-- 1、加载db.properties 文件--> <context:property-placeholder location="classpath:db.properties" file-encoding="UTF-8"/>
2、配置一个数据源
<!-- 2、配置一个数据源 --> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <!-- 配置相应的数据 --> <property name="driverClass" value="${jdbc.driverClassName}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="acquireIncrement" value="${jdbc.acquireIncrement}"/> <property name="initialPoolSize" value="${jdbc.initialPoolSize}"/> <property name="maxPoolSize" value="${jdbc.maxPoolSize}"/> <property name="minPoolSize" value="${jdbc.minPoolSize}"/> </bean>
3、创建一个SqlSessionFactorybean ,用于产生SessionFactory (类似于是mybatis的配置文件)
<!-- 3、创建一个SqlSessionFactorybean ,用于产生SessionFactory , 需要注入数据源--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 加载数据源 --> <property name="dataSource" ref="dataSource"/> <!-- 加载mybatis 的全局配置文件 --> <property name="configLocation" value="classpath:mybatis-config.xml"/> <!-- 加载sql映射文件 classpath类路径*固定写法,容易出问题,--> <property name="mapperLocations" value="classpath*:mapper/*Mapper.xml"/> <!-- 别名设置 --> <property name="typeAliasesPackage" value="com.zl.springMybatis.entity"/> </bean>
4、mapper扫描器(将Mapper层的对象通过basePackage属性,将所有方法添加到spring容器中;扫描sqlSessionFactory)
<!--sqlSession =sqlSessionFactory.openSession() sqlSession.getMapper() --> <!-- 4、mapper扫描器:通过mapper代理,创建mapper代理对象,保存到spring容器中 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 配置Mapper接口所在包 --> <property name="basePackage" value="com.zl.springMybatis.mapper"/> <!-- 加载 sqlSessionFactory :--> <!-- SqlSessionFactory对象 , 弃用, 使用这个sqlSessionFactory作为属性, 造成context:property-placeholder 不能加载properties文件 --> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
5、扫描其他类中的注解
<!-- 5、扫描其他类中的注解 --> <context:component-scan base-package="com.zl.springMybatis"/>
6、配置事务
<!-- 6、配置事务 使用的tx前缀的标签, 导入tx的命名空间--> <!-- 配置事务管理器,并把事务交给spring管理 --> <!-- 通知类 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <!-- 注入DataSource --> <property name="dataSource" ref="dataSource"/> </bean> <!-- 事务的策略 transaction-manager: 事务增强基于那个事务管理器, 默认值: transactionManager(bean的id) 如果事务管理器的id为transactionManager, 在tx:advice标签中不需要添加transaction-manager属性 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <!-- 声明事务的规则 : 针对业务层的不同的方法,采用不同的规则--> <tx:attributes> <tx:method name="find*" read-only="true" propagation="SUPPORTS" /> <tx:method name="query*" read-only="true" propagation="SUPPORTS"/> <tx:method name="get*" read-only="true" propagation="SUPPORTS"/> <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="del*" propagation="REQUIRED" rollback-for="java.lang.Exception" timeout="2"/> <tx:method name="update*" propagation="REQUIRED" rollback-for="java.lang.Exception"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice>
事务的织入
<!-- 事务的织入 --> <aop:config> <!-- 切入点 --> <aop:pointcut expression="execution( * com.zl.springMybatis.service..*.*(..) )" id="pointcut1"/> <!-- 织入 --> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut1"/> </aop:config>
代码的实现:
entity.java实体类:
public class User { private Integer id; private String username; private String password; private String sex; private Date brithday; private String address;
mapper接口:
public interface IUserMapper { //查询所有 List<User> findAllUser();
XxxMapper.xml存在于resources源文件下,新家一个mapper的包
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zl.springMybatis.mapper.IUserMapper"> <!-- 查询所有 --> <select id="findAllUser" resultType="user"> select * from t_user </select> </mapper>
service接口:
public interface IUserService { // 查询所有 List<User> findAllUser();
serviceImpl实现类:
@Service("IUserService") //将UserService添加到spring容器 public class UserServiceImpl implements IUserService { @Autowired //根据类型注入UserMapper private IUserMapper userMapper; @Override public List<User> findAllUser() { return userMapper.findAllUser(); }
web:servlet:
ApplicationContext applicationContext = (ApplicationContext) this.getServletContext() .getAttribute(WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE); IUserService userService = applicationContext.getBean(IUserService.class); userService.findAllUser();
web.xml:创建监听器
<!-- 创建Spring容器的监听器: 在Tomcat启动的时候创建 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param>
整合报错可能出现的问题:
1、org.springframework.web.context.ConfigurableWebApplicationContext.<init>()
applicationContext.xml这个配置文件有没有 ,有的话看下配置是否正确
2、空指针异常
检查是否 xml路径缺少WEB-INF,没加载到服务器
3、org.apache.ibatis.session.Configuration.setVfsImpl(Ljava/lang/Class;)V
mybatis 版本太低
4、java.lang.AbstractMethodError: Method com/mchange/v2/c3p0/impl/NewProxyResultSet.isClosed()Z is abstract
c3p0版本问题:https://blog.csdn.net/TXNull/article/details/81043486