Spring与Mybatis整合
Spring的作用? 帮我们管理项目中需要使用的几乎所有对象的生命周期
使用Mybatis用到了哪些关键对象需要交给Spring管理(全局)
1.核心对象SqlSessionFactory
2.SqlSession
3.Mapper映射器(全局)
整合就是把以上三个对象交给uSpring管理
1.导入两个框架需要的jar包
单独Mybatis的所有包
Spring的核心包 4个 + 1个日志 + AOP3个包 + tx事务一个包 + jdbc + test测试包 + 驱动包 + 连接池
注意:mybatis-Spring整合包需要单独下载 到gitgub中搜索
2.Spring配置文件
1.配置数据库相关参数(数据库连接池)
2.配置MyBatis的会话工厂 并给她注入连接池
3.Mybatis的映射文件
使用dao的实现类查询对象
db.properties
配置文件 记录数据库信息
driverClass=com.mysql.jdbc.Driver
jdbcUrl=jdbc:mysql:///MybatisDB
userName=root
password=12345
SqlMapConfig.xml
扫描com/lanou/dao包下接口与其对应的配置文件
<?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>
<mappers>
<package name="com/lanou/dao"/>
</mappers>
</configuration>
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${userName}"></property>
<property name="password" value="${password}"></property>
</bean>
<!-- 会话工厂 -->
<bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 注入连接池 -->
<property name="dataSource" ref="dataSource"></property>
<!-- 类别名 后面不用再写全限定类名了 -->
<property name="typeAliasesPackage" value="com.lanou.bean"></property>
<!-- 指定Mybatis的配置文件的路径 即上面的SqlMapConfig.xml的位置 -->
<property name="configLocation" value="classpath:SqlMapConfig.xml"></property>
</bean>
<!-- 打开注解扫描 扫描类中的注解 -->
<context:component-scan base-package="com.lanou"></context:component-scan>
</beans>
Dog.java
package com.lanou.bean;
public class Dog {
private int id;
private String nikename;
private String gender;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getNikename() {
return nikename;
}
public void setNikename(String nikename) {
this.nikename = nikename;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
@Override
public String toString() {
return "Dog [id=" + id + ", nikename=" + nikename + ", gender=" + gender + "]";
}
}
DogDao.java
package com.lanou.dao;
import java.util.List;
import com.lanou.bean.Dog;
public interface DogDao {
public List<Dog> selectAllDog();
}
DogDao.xml
<?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.lanou.dao.DogDao">
<select id="selectAllDog" resultType="Dog">
select * from Dog
</select>
</mapper>
DogDaoImpl.java
import java.util.List;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.support.SqlSessionDaoSupport;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import com.lanou.bean.Dog;
import com.lanou.dao.DogDao;
@Repository
public class DogDaoImpl extends SqlSessionDaoSupport implements DogDao{
@Autowired
@Override
public void setSqlSessionFactory(SqlSessionFactory sqlSessionFactory) {
// TODO Auto-generated method stub
super.setSqlSessionFactory(sqlSessionFactory);
}
@Override
public List<Dog> selectAllDog() {
List<Dog> list = getSqlSession().selectList("com.lanou.dao.DogDao.selectAllDog");
System.out.println(list);
return list;
}
}
MyTest.java
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.lanou.bean.Dog;
import com.lanou.dao.DogDao;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class MyTest {
@Autowired
private DogDao dogDao;
@Test
public void test1() {
List<Dog> list = dogDao.selectAllDog();
for (Dog dog : list) {
System.out.println(dog);
}
}
}
使用代理类实现查询操作
删除上面的DogDaoImpl类 用代理类实现时 就不需要自己创建实现类了
然后对配置applicationContext文件进行修改 其余不变
applicationContext.xml
可删除
<property name="configLocation" value="classpath:SqlMapConfig.xml" ></property>
再在里面添加上这段即可
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lanou.dao"></property>
</bean>
让Mybatis自动生成接口的代理实现类 该类用来扫描一堆映射文件 并生成代理
这时已经不再需要SqlMapConfig.xml映射文件了
也不再需要dao层接口的实现类
前提 接口类与映射文件在同一目录下并且名字一致 如果 如果不在同一级 或 名字不同
需要在sqlSessionFactory中使用mapperslocations来指定映射文件
运行结果不变
将配置文件与接口类非别放在不同包下
即DogDao放在.java放在com.lanou.dao包下
DogDao.xml 放在com.lanou.mappers包下
applicationContext.xml
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lanou.dao"></property>
</bean>
<bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.lanou.bean"></property>
<property name="mapperLocations" value="classpath:com/lanou/mappers/*.xml"></property>
</bean>
添加事务
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="user" value="${userName}"></property>
<property name="password" value="${password}"></property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lanou.dao"></property>
</bean>
<bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="typeAliasesPackage" value="com.lanou.bean"></property>
<property name="mapperLocations" value="classpath:com/lanou/mappers/*.xml"></property>
</bean>
<bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<tx:annotation-driven/>
<context:component-scan base-package="com.lanou"></context:component-scan>
</beans>
DogDao.java
public interface DogDao {
public List<Dog> selectAllDog();
public int insertDog(Dog dog);
}
DogDao.xml
<?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.lanou.dao.DogDao">
<select id="selectAllDog" resultType="Dog">
select * from Dog
</select>
<insert id="insertDog">
insert into dog values(
null,
#{nikename},
#{gender}
)
</insert>
</mapper>
MyTest.java
@Test
public void test2() {
Dog dog = new Dog();
dog.setGender("公");
dog.setNikename("小黑黑");
Dog dog2 = new Dog();
dog2.setGender("母");
dog2.setNikename("小红红");
dogDao.insertDog(dog);
int a = 1/0;
dogDao.insertDog(dog2);
}
@Transactional(添加事务注解)
未添加事务注解时 dog会被插入数据库 然后遇到错误 dog2不会插入数据库
当添加事务注解时 dog会被插入数据库 事务还没提交 然后遇到错误 事务回滚 dog与dog2都
不会插入数据库
示例
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<display-name>SpringMVC02</display-name>
<welcome-file-list>
<welcome-file>index.html</welcome-file>
<welcome-file>index.htm</welcome-file>
<welcome-file>index.jsp</welcome-file>
<welcome-file>default.html</welcome-file>
<welcome-file>default.htm</welcome-file>
<welcome-file>default.jsp</welcome-file>
</welcome-file-list>
<!-- 配置SpringMVC的核心控制器 -->
<servlet>
<servlet-name>spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定SpringMVC配置文件路径 注意:Spring配置文件写在最外层 用<context-param>
这里必须写Servlet标签中间 用<init-param> -->
<!-- 当创建DispatcherServlet类的时候 必须给其指定的参数 -->
<init-param>
<!-- 配置文件写的所有属性 都是java类中的属性 所有名字必须一样 -->
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC-servlet.xml</param-value>
</init-param>
</servlet>
<!-- 地址映射 哪些请求交给SpringMVC处理 -->
<servlet-mapping>
<servlet-name>spring</servlet-name>
<!--
1. /* 拦截所有请求 包括静态资源
2. *. action || *.do 拦截以.action结束的请求
3. / 拦截所有请求 jsp除外
-->
<!-- 拦截下来交给DispatcherServlet处理 -->
<url-pattern>*.action</url-pattern>
</servlet-mapping>
</web-app>
SpringMVC-servlet.xml
<?xml version="1.0" encoding="UTF-8"?>
<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: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-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- 整合SpringMVC和Mybatis -->
<!-- 数据库连接池 -->
<bean name="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql:///MVCDB" />
<property name="user" value="root" />
<property name="password" value="123456" />
</bean>
<!-- 会话工厂 -->
<bean name="sessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 连接池 -->
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 扫描接口与其对应的映射文件 同一目录 并且名字相同 -->
<bean name="mapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.lanou.dao"></property>
</bean>
<!-- 事务管理 -->
<bean name="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务注解 -->
<tx:annotation-driven/>
<context:component-scan base-package="com.lanou"></context:component-scan>
</beans>
Student.java
public class Student {
private int s_id;
private String s_name;
private String s_gender;
private int s_age;
public Student() {
super();
// TODO Auto-generated constructor stub
}
public Student(int s_id, String s_name, String s_gender, int s_age) {
super();
this.s_id = s_id;
this.s_name = s_name;
this.s_gender = s_gender;
this.s_age = s_age;
}
public int getS_id() {
return s_id;
}
public void setS_id(int s_id) {
this.s_id = s_id;
}
public String getS_name() {
return s_name;
}
public void setS_name(String s_name) {
this.s_name = s_name;
}
public String getS_gender() {
return s_gender;
}
public void setS_gender(String s_gender) {
this.s_gender = s_gender;
}
public int getS_age() {
return s_age;
}
public void setS_age(int s_age) {
this.s_age = s_age;
}
@Override
public String toString() {
return "User [s_id=" + s_id + ", s_name=" + s_name + ", s_gender=" + s_gender + ", s_age=" + s_age + "]";
}
}
StudentController.java
@Controller
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping("getStudent.action")
public ModelAndView test(int id) {
System.out.println("123");
ModelAndView mv = new ModelAndView();
Student student = studentService.selectStudentById(id);
mv.setViewName("2.jsp");
mv.addObject("student",student);
return mv;
}
}
StudentDao.java
public interface StudentDao {
public Student getStudentById(int id);
}
StudentDao.xml
<?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.lanou.dao.StudentDao">
<select id="getStudentById" resultType="com.lanou.bean.Student">
select * from Student where s_id = #{param}
</select>
</mapper>
StudentService.java
public interface StudentService {
public Student selectStudentById(int id);
}
StudentServiceImpl.java
@Service
public class StudentServiceImpl implements StudentService{
@Autowired
private StudentDao studentDao;
@Override
public Student selectStudentById(int id) {
// TODO Auto-generated method stub
Student student = studentDao.getStudentById(id);
return student;
}
}
2.jsp
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>${student.s_name }</h1>
<h2>${student.s_age }</h2>
</body>
</html>
SpringMVC的三大主键
1.映射处理器 HandleMapping
负责根据请求对象找到一个可以处理请求的Controller.
默认使用的是BeanNameUrlHandlerMapping
接收到请求地址作为name到容器中查找对应的bean
例如请求了 xxxx/getUsers.action
把getUser.action作为name到容器中找bean对象
2.处理适配器
负责映射参数 调用Controller 并返回ModelAndAction
3.视图解析器
负责解析ModelAndView中的视图物理地址
以及将modelAndView中参数放入request中
如果不行使用默认的映射处理器 可以到容器中手动指定(了解即可 无需掌握)
目前SpringMVC要想实现一个controller处理多个请求 只能使用注解
指定视图解析器
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<!-- 确定视图的具体路径 -->
<!-- 前缀prefix -->
<property name="prefix" value="views/jsp/"></property>
<!-- 后缀suffix -->
<property name="suffix" value=".jsp"></property>
</bean>
相当于views/jsp/ + test + .jsp
UserController
@Controller
public class UserController{
@RequestMapping("/getUsers.action")
public ModelAndView getUser() {
ModelAndView mv = new ModelAndView();
mv.setViewName("test");
return mv;
}
}
test.jsp
</head>
<body>
测试视图解析器 地址拼接
</body>
</html>
#### web.xml
<!-- 配置SpringMVC的核心控制器 -->
<servlet>
<servlet-name>Spring</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定SpringMVC配置文件路径 注意:Spring配置文件写在最外层用<context-param>
这里必须写到Servlet标签中间 用<init-param>
-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:SpringMVC-servlet.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>Spring</servlet-name>
<!--
1./* 拦截所有请求 包括静态资源
2.*.action || *.do 拦截一.action结束的请求
3./ 拦截所有请求 jsp除外
-->
<url-pattern>*.action</url-pattern>
</servlet-mapping>