mybatis是dao层的一个框架,专门用来操作数据库
Spring是横贯三层的框架,Spring这个(容器),利用IOC、DI等机制,专门来管理其他的框架,可以对项目中的依赖关系做解耦,建立一个低耦合的应用架构增强系统开发和维护的灵活性,便于扩展。
lmybatis是使用核心对象SqlSession操作数据库
l要获得SqlSession实例,就需要SqlSessionFactory
l而SqlSessionFactory是SqlSessionFactoryBulider依据Mybatis核心配置文件中数据源、sql映射文件等信息构建的。
以前我们使用mybatis,就需要我们自己手动编写代码去创建这些对象
现在:让Spring容器帮我们去管理(创建对象)
l核心包
l依赖包
lmysql的驱动包
完整jar包如下
xml version="1.0" encoding="UTF-8"?><< span="">beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> |
---|
lspring和myabtis整合,不再使用jdbc默认连接池技术,使用 一些第三方的数据连接池技术
l常见的有dbcp、C3p0、Proxool等连接池技术
l导入dbcp连接池的jar包
l让spring管理dbcp数据连接池
对应类图
代码:
<< span="">bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> << span="">property name="driverClassName" value="com.mysql.jdbc.Driver">property> << span="">property name="url" value="jdbc:mysql://localhost:3306/smbms?Unicode=true&characterEncoding=utf-8">property> << span="">property name="username" value="root">property> << span="">property name="password" value="12345">property> bean> |
---|
【开发总结】:
lspring的bean标签中的class对应的类路径不要打错,更不能乱打。
lspring的bean标签中property元素中name属性对应的值,也不能乱打。
mybaits中SqlSessionFactory使用SqlsessionFactoryBulider构建
整合后,使用SqlSessionFactoryBean
代码:
<< span="">bean id="SqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> //数据源 << span="">property name="dataSource" ref="dataSource">property> //核心配置文件 << span="">property name="configLocation" value="classpath:mybatis-config.xml">property>、 //mapper映射文件 << span="">property name="mapperLocations"> << span="">list> << span="">value>classpath:cn/qn/dao/UserMapper.xmlvalue> list> property> bean> |
---|
传统mybatis开发,使用SqlSession,有了SqlSession可以帮助我们操作数据库
而在Spring整合mybatis后,Spring框架封装了SqlSession类,提供了一个SqlSessionTemplete
SqlSessionTemplete特点:
l实现了SqlSession
l融合spring并简化部分流程化工作
l保证和当前spring中事务自动相关联
l自动管理会话生命周期(关闭、提交、回滚)
类图:
<< span="">bean id="sqlsession" class="org.mybatis.spring.SqlSessionTemplate">bean> |
---|
<< span="">bean id="sqlsession" class="org.mybatis.spring.SqlSessionTemplate"> << span="">constructor-arg name="sqlSessionFactory" ref="SqlSessionFactory">constructor-arg>bean> |
---|
【开发小结】:
l传统的mybatis开发,sqlSession也是需要SqlSessionFactory对象才能得到session
l在SqlSessionTemplete的源码中,明确提供了一个构造函数
<< span="">bean name="userdao" class="com.shop.daotest.UserDao"> << span="">property name="sqlSessionTemplete" ref="SqlSessionTemplate">property> bean> |
---|
public class UserDao { SqlSessionTemplate sqlSessionTemplete; public ListgetUserList() { Listlist = sqlSessionTemplete.selectList("selectUserListInfo"); return list; } public User getUserById(Integer id) { User user = sqlSessionTemplete.selectOne("selectUserById",id); return user; } public SqlSessionTemplate getSqlSessionTemplete() { return sqlSessionTemplete; } public void setSqlSessionTemplete(SqlSessionTemplate sqlSessionTemplete) { this.sqlSessionTemplete = sqlSessionTemplete; }} |
---|
@Test public void fun1() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao dao = (UserDao) ac.getBean("userdao"); List<< span="">User> list = dao.getUserList(); for (User user : list) { System.out.println(user); } } |
---|
测试mybaits内部提供的查询方法
测试mapper接口方式开发
【开发小结】:使用spring整合之后,可以将数据源、SqlSessionFactoryBean、SqlSessionTemplete都交给spring管理,简化了开发
思考:以上程序有没有不好之处?
所以spring框架提供了一个SqlSessionDaoSupport
【整合中级阶段】:
SqlSessionDaoSupport类中内部封装了setter和gettter方法
需要注入
直接获取SqlSession public SqlSession getSqlSession() { return this.sqlSession; } |
---|
我们只要将自己的类继承这个类,那么就可以使用使用它的getSession()获取session
public class UserDao2 extends SqlSessionDaoSupport{} |
---|
<< span="">bean name="userdao2" class="com.shop.daotest.UserDao2"> << span="">property name="sqlSessionFactory" ref="SqlSessionFactoryBean">property> bean> |
---|
public class UserDao2 extends SqlSessionDaoSupport{ public ListgetUserList() { UserMapper mapper = getSqlSession().getMapper(UserMapper.class); Listlist = mapper.selectUserListInfo(); return list; }} |
---|
@Test public void fun1() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao2 dao = (UserDao2) ac.getBean("userdao2"); Listlist = dao.getUserList(); for (User user : list) { System.out.println(user); } } |
---|
【开发小结】:之前我们需要在dao的实现类中,提供sqlSessionTemplete的set和get方法,并将sqlTemp注入到dao实现类中
现在只需要让自己的类继承SqlSessionSupport,然后将SqlFac注入进来,就可以直接使用get()方法获取SqlSessionTemp (SqlSession),不需要创建sqlsession,也不需要提供setter方法
思考:以上程序的不妥之处?
1.使用sqlsession内部的方法,都是写死的字符串来获取,很容易产生错误且错误还不易被发觉
2.每次都要getMapper一下,繁琐,能不能让spring帮我们去getMapper操作,自己只提供一个接口呢?
所以Spring提供了MapperFactoryBean直接注入映射器
【整合高级阶段】:
mapperFactoryBean特点:
1.继承了SqlSessionDaoSupport
<< span="">bean name="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> << span="">property name="mapperInterface" value="com.shop.mapper.UserMapper">property> << span="">property name="sqlSessionFactory" ref="SqlSessionFactoryBean">property> bean> |
---|
@Test public void fun2() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper m = (UserMapper) ac.getBean("userMapper"); Listlist = m.selectUserListInfo(); for (User user : list) { System.out.println(user); } } |
---|
思考:以上代码可以简化吗?
在实际开发中,肯定会有多个mapper接口,从而定义多个模块的功能,那如果按照目前的情况,需要写多个mapper接口的xml配置
这时候,spring提供可以直接通过package名,指定扫描该package下的所有,mapper接口,直接注册为MapperFactoryBean
<< span="">bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> << span="">property name="basePackage" value="cn.qn.dao">property>bean> |
---|
思考:问题在哪?
在测试代码中,spring容器的getBean的name是哪个?
我们可以通过getBeanDefinitionNames()获取所有的bean名称
观察发现:
最终测试代码:
@Test public void fun4() { ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); String[] beanDefinitionNames = ac.getBeanDefinitionNames(); for (String beanName : beanDefinitionNames) { System.out.println("beanName:"+beanName); } OrderMapper m = (OrderMapper) ac.getBean("orderMapper"); Listlist = m.selectOrderList(); for (Orders orders : list) { System.out.println(orders); } } |
---|