Spring-MyBatis整合简单例子及个人的经验杂谈

所需jar包:Spring所需包、MyBatis所需包、mybatis-spring-1.x.x.jar(Spring与Mybatis整合包,需额外下载)

该文章主要分享一些自己的经验,所以一些配置可能不会解释

配置流程(个人觉得把逻辑顺序理清后需要记忆性的方面并不会太多):


以下是位于WEB-INF下的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:c="http://www.springframework.org/schema/c"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.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">

	<context:annotation-config></context:annotation-config>
	<!-- 只扫描Repository和Service注解的类 -->
	<context:component-scan base-package="pers"
		use-default-filters="false">
		<context:include-filter type="annotation"
			expression="org.springframework.stereotype.Repository" />
		<context:include-filter type="annotation"
			expression="org.springframework.stereotype.Service" />
	</context:component-scan>

	<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean"
		p:jndiName="java:comp/env/jdbc/mysql"></bean>

	<bean id="transactionManager"
		class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
		p:dataSource-ref="dataSource"></bean>

	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"
		p:dataSource-ref="dataSource" p:configLocation="classpath:mybatis-config.xml"></bean>

	<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate"
		c:_-ref="sqlSessionFactory"></bean>

	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
		p:basePackage="pers.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory"
		p:sqlSessionTemplateBeanName="sqlSessionTemplate">
	</bean>

	<tx:annotation-driven />
</beans>


 
①由于使用的是JNDI数据源所以还需在tomcat的context.xml文件中添加如下配置 

本以为配置数据源应该都该在spring-jdbc-xxx的jar下包找的(Eclipse ALT+SHIFT+T可以快捷查询具体类在哪个jar包下),但可能由于jndi的数据源配置需在服务器中配置(这里是Tomcat服务器中的context.xml负责配置),所以把它放到spring-context-xxx.jar包中了

②SqlSessionFactoryBean:负责生成SqlSessionFactory,位于整合的mybatis-spring整合包中(由于该整合包是由MyBatis开发所以以mybatis为前缀,因Spring3发布时Mybatis3尚未完成,所以MyBatis社区自己进行整合)

个人比较喜欢看着左侧的属性栏进行Spring的属性装配,因为觉得能找到就没必要去记那么多没必要的属性。看到该类的属性相信大家都发现了mybatis的配置文件中的所有标签这里都有,也就是说mybatis配置文件的所有标签属性都可以通过该类配置,但个人不推荐所以只说个人喜欢的方式。我配置时看到哪个属性是我在配置文件中已经配置好的就直接填充,如dataSource。

configLocation:mybatis配置文件的所在位置,配置该属性后会根据位置解析文件然后为相应的标签属性赋值,具体方法为该类中的buildSqlSessionFactory()方法,有兴趣的可以去看看。

谈一下FactoryBean:Spring中的xxxFactoryBean都继承了Spring的FactoryBean,生成的bean一般为实现时的泛型,如上图中泛型为SqlSessionFactory,固配置该SqlSessionFactoryBean的实际bean是SqlSessionFactory实例,所以配置SqlSessionTemplate中的sqlSessionFactory属性时将用bean id="sqlSessionFactory"将用该SqlSessionFactory实例填充,上面JndiObjectFactoryBean亦然。看一下源码注解:

粗略讲一下第一段大意:实现该接口的对象将会作为一个为了对象而公开的工厂,而不是直接作为一个bean实例进行公开(如配置class为SqlSessionFactoryBean后生成(公开)的bean为SqlSessionFactory而不是SqlSessionFactoryBean),返回bean的方法是getObject(),即getObject返回的bean是什么则工厂bean生成的bean就是什么,一般设定为泛型的实例

③SqlSessionTemplate:一个模板类,通过调用SqlSession来完成工作,SqlSession由SqlSessionFactory负责生成,在Mybatis-Spring项目中它是一个核心类,主要的2个属性:

sqlSessionFactory:该类没有无参构造函数,即代表该属性必须作为构造器参数配置

executeorType:执行器,取值范围为SIMPLE、REUSE、BATCH,等同于mybatis配置文件中的setting的defaultExecutorType,可作为构造函数的第二个参数,但个人建议还是在mybatis配置文件中配置

该类具体构造方法如下图:

④MapperScannerConfigurer(数目少的话可以用MapperFactoryBean,这里不做介绍):采用自动扫描形式配置映射器,主要属性:

basePackage:指定让Spring自动扫描什么包,它会逐层深入扫描

annotationClass:表示如果该类被这个注解标识的时候才进行扫描(我例子中设置的是Repository,该注解一般用于标识DAO层)

sqlSessionFactoryBeanName:指定在Spring中定义sqlSessionFactory的bean的名称。如果它被定义,sqlSessionFactory将不起作用。

sqlSessionTemplateBeanName:指定在Spring中定义sqlSessionTemplate的bean的名称。如果它被定义,sqlSessionTemplate将不起作用。

makerInterface:指定实现了什么接口就认为它是Mapper,需提供一个公共接口去标记。

该类中还有sqlSessionFactory与sqlSessionTemplate这两个属性,但个人建议以sqlSessionFactoryBeanName、sqlSessionTemplateBeanName替代,因:

这两个方法都已标识过时,代表着可能过几个版本就会消失掉。

以下是该例子的相关代码,如果只对流程有兴趣的可以直接跳到最底Spring MVC层的简单配置

Role.java

package pers.vo;

import java.io.Serializable;

public class Role implements Serializable{
	private static final long serialVersionUID = 1L;
	private Integer id;
	private String roleName;
	private String note;

	@Override
	public String toString() {
		return "Role [id=" + id + ", roleName=" + roleName + ", note=" + note + "]";
	}

	public Role() {
	}

	public Role(String roleName, String note) {
		super();
		this.roleName = roleName;
		this.note = note;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getRoleName() {
		return roleName;
	}

	public void setRoleName(String roleName) {
		this.roleName = roleName;
	}

	public String getNote() {
		return note;
	}

	public void setNote(String note) {
		this.note = note;
	}

}

RoleDAO.java

package pers.dao;

import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Repository;

import pers.vo.Role;

@Repository
public interface RoleDAO {
	Role findRoleById(int id);

	int insertRole(Role role);

	int deleteRoleById(int id);

	int updateRole(Role role);

	List<Role> findRolesByKeyName(String name);

	List<Role> findAllRoles(RowBounds rowBounds);
}
RoleService.java

package pers.service;

import java.util.List;

import pers.vo.Role;

public interface RoleService {
	Role findRoleById(int id);

	int insertRole(Role role);

	int deleteRoleById(int id);

	int updateRole(Role role);

	List<Role> findRolesByKeyName(String name);

	List<Role> findAllRoles(int start,int limit);
}
RoleServiceImpl.java

package pers.service.impl;

import java.util.List;

import org.apache.ibatis.session.RowBounds;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import pers.dao.RoleDAO;
import pers.service.RoleService;
import pers.vo.Role;

@Service
public class RoleServiceImpl implements RoleService {
	@Autowired(required=false)
	private RoleDAO roleDAO;
	
	@Override
	@Transactional(propagation = Propagation.SUPPORTS)
	public Role findRoleById(int id) {
		return roleDAO.findRoleById(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int insertRole(Role role) {
		return roleDAO.insertRole(role);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int deleteRoleById(int id) {
		return roleDAO.deleteRoleById(id);
	}

	@Override
	@Transactional(propagation = Propagation.REQUIRED)
	public int updateRole(Role role) {
		return roleDAO.updateRole(role);
	}

	@Override
	@Transactional(propagation = Propagation.SUPPORTS)
	public List<Role> findRolesByKeyName(String name) {
		return roleDAO.findRolesByKeyName(name);
	}

	@Override
	@Transactional(propagation = Propagation.SUPPORTS)
	public List<Role> findAllRoles(int start, int limit) {
		return roleDAO.findAllRoles(new RowBounds(start, limit));
	}

}
RoleController.java

package pers.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import pers.service.RoleService;
import pers.vo.Role;

@Controller
public class RoleController {
	@Autowired
	private RoleService roleService;

	public void setRoleService(RoleService roleService) {
		this.roleService = roleService;
	}

	public RoleController() {
	}
	
	@RequestMapping("/role/getRole")
	@ResponseBody
	public Role getRole(@RequestParam("id") int id) {
		Role role = roleService.findRoleById(id);
		System.out.println(role);
		return role;
	}
}

mybatis-config.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>
	<settings>
		<setting name="mapUnderscoreToCamelCase" value="true" />
		<setting name="aggressiveLazyLoading" value="false" />
		<setting name="lazyLoadingEnabled" value="true" />
		<setting name="useGeneratedKeys" value="true" />
		<setting name="defaultExecutorType" value="REUSE" />
		<setting name="defaultStatementTimeout" value="25000" />
	</settings>
	<typeAliases>
		<package name="pers.vo" />
	</typeAliases>
	<mappers>
		<mapper resource="mapper/role.xml" />
	</mappers>
</configuration>

Role.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="pers.dao.RoleDAO">
	<cache eviction="LRU" flushInterval="100000"></cache>
	<select id="findRoleById" resultType="role">
 		<![CDATA[select id,role_name,note from tb_role where id=#{id}]]>
	</select>
	<select id="findRolesByKeyName" resultType="role">
		<bind name="name_pattern" value="'%'+ name + '%'"/>
		<![CDATA[select id,role_name,note from tb_role where role_name like #{name_pattern}]]>
	</select>
	<select id="findAllRoles" resultType="role">
		<![CDATA[select id,role_name,note from tb_role]]>
	</select>
	<insert id="insertRole" parameterType="role">
		<![CDATA[insert into tb_role(role_name,note) values (#{roleName},#{note})]]>
	</insert>
	<update id="updateRole" parameterType="role">
		<![CDATA[select role_name,note from tb_role where id=#{id}]]>
	</update>
	<delete id="deleteRoleById">
		<![CDATA[delete from tb_role where id=#{id}]]>
	</delete>
</mapper>

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>SM_Integration</display-name>

	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>

	<servlet>
		<servlet-name>springDispatcherServlet</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
	<servlet-mapping>
		<servlet-name>springDispatcherServlet</servlet-name>
		<url-pattern>/</url-pattern>
	</servlet-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
</web-app>

MVC配置文件dispatcher-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:aop="http://www.springframework.org/schema/aop"
	xmlns:c="http://www.springframework.org/schema/c" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
	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/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd
		http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
		http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
	<mvc:annotation-driven></mvc:annotation-driven>
	<context:component-scan base-package="pers.*"></context:component-scan>
	<context:annotation-config></context:annotation-config>
	
	<!-- <bean
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
		<property name="messageConverters">
			<list>
				<ref bean="mappingJacksonHttpMessageConverter" />
			</list>
		</property>
	</bean> -->
	<!-- Spring视图拦截器 -->
	<bean
		class="org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter">
		<property name="messageConverters">
			<list>
				<!-- JSON视图拦截器,读取到@ResponseBody的时候触发 -->
				<ref bean="mappingJacksonHttpMessageConverter" />
			</list>
		</property>
	</bean>
	
	<!-- json转换器,可将结果转化 -->
	<bean id="mappingJacksonHttpMessageConverter"
		class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter">
		<property name="supportedMediaTypes">
			<list>
				<value>application/json;charset=UTF-8</value>
			</list>
		</property>
	</bean>
</beans>

 
 

我的mybatis入门书中视图拦截器使用的是注释中的 AnnotationMethodHandlerAdapter,但根据注解 AnnotationMethodHandlerAdapter在3.2版本后已过时,现在支持使用RequestMappingHandlerAdapter,下图是两个类的属性图:

图放不下RequestMappingHandlerAdapter所有属性。
可以看出AnnotationMethodHandlerAdapter中的大部分属性RequestMappingHandlerAdapter都有,且增加了不少属性,AnnotationMethodHandlerAdapter继承了WebContentGenerator,而RequestMappingHandlerAdapter继承了AbstractHandlerMethodAdapter,AbstractHandlerMethodAdapter继承了WebContentGenerator,由于我要设置的属性两者都有所以进行了替换,程序依然能正常允许。

index.jsp为空页面,网址后缀添加/role/getRole?id=xx  获取要查询的数据并以json格式下载,图如下:

保存的json文件:


Spring MVC使用json还需添加jackson-databind-x.x.x、jackson-annotations-x.x.x、jackson-core-x.x.x 3个jar包

我的数据库tb_role就只有id,role_name,note 3个属性,便于实践,就不讲太多


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值