mybatis与Spring的整合
一、整合思路
1、SqlSessionFactory对象应该放到spring容器中作为单例存在。
2、传统dao的开发方式中,应该从spring容器中获得sqlsession对象。
、Mapper代理形式中,应该从spring容器中直接获得mapper的代理对象。
4、数据库的连接以及数据库连接池事务管理都交给spring容器来完成。
二、所需的jar包
1、spring的jar包
2、Mybatis的jar包
3、Spring+mybatis的整合包。
4、Mysql的数据库驱动jar包。
5、数据库连接池的jar包。
三、步骤
1、创建工程Java工程
2、导入jar包
3、新键mybatis的核心配置文件sqlMapConfig.xml
4、编写Spring的配置文件
a、数据库连接及连接池
b、事务管理(暂时可以不配置)
c、sqlsessionFactory对象,配置到spring容器中
d、mapeer代理对象或者是dao实现类配置到spring容器中。
5、编写dao或mapper文件
四:1、sqlMapConfig.xml
<?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> <!-- <properties resource="db.properties"/> --> <typeAliases> <!-- 定义单个pojo类别名 type=类的全路径名称 alias=别名 --> <typeAlias type="com.wang.pojo.User" alias="User"/> <!-- 使用包扫描的方式批量定义别名 别名就是类名,不区分大小写 --> <package name="com.wang.pojo"/> </typeAliases> <!-- 和spring整合后 environments配置将废除 --> <!-- <environments default="development"> <environment id="development"> 使用jdbc事务管理 <transactionManager type="JDBC" /> 数据库连接池 <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> --> <mappers> <mapper resource="user.xml"/> <!-- <mapper class="com.wang.mapper.UserMapper"/> --> <!-- 使用包扫描的方式批量引入Mapper接口 1、接口名称和映射文件名称除扩展名外要完全相同 2、接口和映射文件要放在同一个目录下 --> <!-- <package name="com.wang.mapper"/> --> </mappers> </configuration>
2、applictionContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd"> <!-- 加载配置文件 --> <context:property-placeholder location="classpath:db.properties"/> <!-- 数据库连接池 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> <property name="maxActive" value="10"/> <property name="maxIdle" value="5"/> </bean> <!-- 凡是Spring的配置文件就要加classpath,不是不要加 --> <!-- 整合后会话工厂归Spring管理 --> <!-- 位于mybatis-spring-1.2.2.jar中org.mybatis.spring包中--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--指定 mybatis的核心配置文件 --> <property name="configLocation" value="classpath:SqlMapConfig.xml"/> <!-- 指定会话 工厂使用的数据源--> <property name="dataSource" ref="dataSource"/> </bean> <!-- 配置原生dao实现 --> <!--注意: class必须指定实现类 --> <bean id="userDao" class="com.wang.dao.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean> <!-- Mapper接口代理的实现 --> <!-- <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> 配置mapper接口的全路径名称 <property name="mapperInterface" value="com.wang.mapper.UserMapper"></property> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean> --> <!-- 使用包扫描的方式批量引入Mapper 扫描后引用的时候可以使用类名,导入bean,首字母小写 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定扫描的包的全路径名称,如果要有多个包用英文状态下的逗号分隔 --> <property name="basePackage" value="com.wang.mapper"></property> </bean> </beans>
注意:
1、数据源归Spring管理
2、配置会话工厂
4、由于Spring引入了一次,所以sqlMapConfig就不需要在引入了
<!-- <package name="com.wang.mapper"/>-->
五、测试代码
在applicationContext.xml中
<!-- 配置原生dao实现 --> <!--注意: class必须指定实现类 --> <bean id="userDao" class="com.wang.dao.UserDaoImpl"> <property name="sqlSessionFactory" ref="sqlSessionFactory" /> </bean>
1、原生Dao测试:
Dao层接口:
public interface UserDao { public User findUserById(Integer id); public List<User> findUserByName(String userName); }
Dao实现:
public class UserDaoImpl extends SqlSessionDaoSupport implements UserDao { @Override public User findUserById(Integer id) { //sesion是线程不安全的,最佳在方法体内 SqlSession session = this.getSqlSession(); User user = session.selectOne("test.findUserById", id); session.close(); return user; } @Override public List<User> findUserByName(String userName) { SqlSession sqlSession = this.getSqlSession(); List<User> selectList= sqlSession.selectList("test.findUserByUserName",userName); return selectList; } }
注意:在实现Dao的时候继承了SqlSessionDaoSupport,且无需在进行SQLSessionFactory的创建,直接调用即可(this.getSqlSession())
public class UserDaoTest { private ApplicationContext applicationContext; @Before public void setUp() throws Exception { String configLocation = "applictionContext.xml"; applicationContext = new ClassPathXmlApplicationContext(configLocation); } @Test public void testFindUserById() throws Exception{ UserDao userDao = (UserDao) applicationContext.getBean("userDao"); User user = userDao.findUserById(1); System.out.println(user); } }
2、Mapper接口代理
<!-- 使用包扫描的方式批量引入Mapper 扫描后引用的时候可以使用类名,导入bean,首字母小写 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 指定扫描的包的全路径名称,如果要有多个包用英文状态下的逗号分隔 --> <property name="basePackage" value="com.wang.mapper"></property> </bean>
测试:
Mapper接口
public interface UserMapper { public com.wang.pojo.User findUserById(java.lang.Integer id); //动态代理形式中如果返回结果集为list,那么mybatis会生成实现类的使用 //会自动调用selectList方法 public List<User> findUserByUserName(String name); public void insertUser(User user); public Integer findUserCount(); public List<User> findUserByUserNameAndSex(User user); public List<User> findUserByIds(QueryVo vo); public List<CustomOrders> findOrdersAndUser1(); public List<Orders> findOrdersAndUser2(); public List<User> findUserAndOrders(); }
测试:
public class UserMapperTest { private ApplicationContext applicationContext; @Before public void setUp() throws Exception { String configLocation = "applictionContext.xml"; applicationContext = new ClassPathXmlApplicationContext(configLocation); } @Test public void testFindUserById() throws Exception{ UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper"); User user = userMapper.findUserById(1); System.out.println(user); } }
a、对于原生的DAO需要定义为bean,且实现类继承SqlSessionDaoSupport(位于整合包中)
实现的DaoImpl就不用再创建SQLSessionFactory工厂,直接用this.openSession(),即可
b、整合后,会话已经归Spring管理,就不必自己在关闭,否则出错
java.lang.UnsupportedOperationException: Manual close is not allowed over a Spring managed SqlSession
目录结构: