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>