使用全注解配置Spring MVC+Spring +MyBatis框架,带事务配置。

Posted ykzhen2015

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用全注解配置Spring MVC+Spring +MyBatis框架,带事务配置。相关的知识,希望对你有一定的参考价值。

即将交稿我的新作《Java EE互联网轻量级框架整合开发——Spring  + Spring MVC + MyBatisSSM框架)和Redis实现》


写这本书 是不是一个比较疯狂的想法,这里先给大家预热,来一个全注解方式配置SSM框架。

首先我们配置Spring MVC的配置类,为了方便你可以继承AbstractAnnotationConfigDispatcherServletInitializer,关于这点我的文章已经说明使用全注解配置Spring MVC 

package com.ssm.chapter15.config;

import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration.Dynamic;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;

public class MyWebAppInitializer
        extends AbstractAnnotationConfigDispatcherServletInitializer 
	
	// Spring IoC容器配置
	@Override
	protected Class<?>[] getRootConfigClasses() 
		// 可以返回Spring的Java配置文件数组
		return new Class<?>[] RootConfig.class;
	

	// DispatcherServlet的URI映射关系配置
	@Override
	protected Class<?>[] getServletConfigClasses() 
		// 可以返回Spring的Java配置文件数组
		return new Class<?>[]  WebConfig.class ;
	

	// DispatcherServlet拦截请求匹配
	@Override
	protected String[] getServletMappings() 
		return new String[]  "*.do" ;
	
请注意:

在getRootConfigClasses方法上加入配置类RootConfig,用于加载Spring IoC容器的上下文

而在getServletConfigClasses方法上加入了WebConfig,用户加载Spring Servlet配置的上下文

而在getServletMappings方法上加入了拦截 *.do的请求,这样就意味着DispatcherServlet将拦截这样的请求。


接下来我们来看 RootConfig.java

package com.ssm.chapter15.config;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;

@Configuration
//定义Spring 扫描的包
@ComponentScan(value= "com.*", includeFilters= @Filter(type = FilterType.ANNOTATION, value =Service.class))
//使用事务驱动管理器
@EnableTransactionManagement
//实现接口TransactionManagementConfigurer,这样可以配置注解驱动事务
public class RootConfig implements TransactionManagementConfigurer 
    
    private DataSource dataSource = null;
    
    /**
     * 配置数据库.
     * @return 数据连接池
     */
    @Bean(name = "dataSource")
    public DataSource initDataSource() 
        if (dataSource != null) 
            return dataSource;
        
        Properties props = new Properties();
        props.setProperty("driverClassName", "com.mysql.jdbc.Driver");
        props.setProperty("url", "jdbc:mysql://localhost:3306/chapter15");
        props.setProperty("username", "root");
        props.setProperty("password", "123456");
        try 
            dataSource = BasicDataSourceFactory.createDataSource(props);
         catch (Exception e) 
            e.printStackTrace();
        
        return dataSource;
    
    
    /***
     * 配置SqlSessionFactoryBean
     * @return SqlSessionFactoryBean
     */
    @Bean(name="sqlSessionFactory")
    public SqlSessionFactoryBean initSqlSessionFactory() 
        SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
        sqlSessionFactory.setDataSource(initDataSource());
        //配置MyBatis配置文件
        Resource resource = new ClassPathResource("mybatis/mybatis-config.xml");
        sqlSessionFactory.setConfigLocation(resource);
        return sqlSessionFactory;
    
    
    
    /***
     * 通过自动扫描,发现MyBatis Mapper接口
     * @return Mapper扫描器
     */
    @Bean 
    public MapperScannerConfigurer initMapperScannerConfigurer() 
        MapperScannerConfigurer msc = new MapperScannerConfigurer();
        msc.setBasePackage("com.*");
        msc.setSqlSessionFactoryBeanName("sqlSessionFactory");
        msc.setAnnotationClass(Repository.class);
        return msc;
    
    
    
    /**
     * 实现接口方法,注册注解事务,当@Transactional 使用的时候产生数据库事务 
     */
    @Override
    @Bean(name="annotationDrivenTransactionManager")
    public PlatformTransactionManager annotationDrivenTransactionManager() 
        DataSourceTransactionManager transactionManager = new DataSourceTransactionManager();
        transactionManager.setDataSource(initDataSource());
        return transactionManager;
    
    
    




好了,上面的配置也比较清楚了,干什么用的,无非就是配置数据库,MyBatis和事务的信息,这里的注解式事务是通过实现TransactionManagementConfigurer接口的annotationDrivenTransactionManager方法得到的。

然后配置WebConfig.java

package com.ssm.chapter15.config;

import java.util.ArrayList;
import java.util.List;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.ComponentScan.Filter;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.http.MediaType;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.stereotype.Controller;
import org.springframework.web.servlet.HandlerAdapter;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;

@Configuration
//定义Spring MVC扫描的包
@ComponentScan(value="com.*", includeFilters= @Filter(type = FilterType.ANNOTATION, value = Controller.class))
//启动Spring MVC配置
@EnableWebMvc
public class WebConfig  

	/***
	 * 通过注解 @Bean 初始化视图解析器
	 * @return ViewResolver 视图解析器
	 */
	@Bean(name="internalResourceViewResolver")
	public ViewResolver initViewResolver() 
		InternalResourceViewResolver viewResolver =new InternalResourceViewResolver();
		viewResolver.setPrefix("/WEB-INF/jsp/");
		viewResolver.setSuffix(".jsp");
		return viewResolver;
	
	
	/**
	 * 初始化RequestMappingHandlerAdapter,并加载Http的Json转换器
	 * @return  RequestMappingHandlerAdapter 对象
	 */
	@Bean(name="requestMappingHandlerAdapter") 
	public HandlerAdapter initRequestMappingHandlerAdapter() 
		//创建RequestMappingHandlerAdapter适配器
		RequestMappingHandlerAdapter rmhd = new RequestMappingHandlerAdapter();
		// HTTP JSON转换器
		MappingJackson2HttpMessageConverter  jsonConverter 
	        = new MappingJackson2HttpMessageConverter();
		//MappingJackson2HttpMessageConverter接收JSON类型消息的转换
		MediaType mediaType = MediaType.APPLICATION_JSON_UTF8;
		List<MediaType> mediaTypes = new ArrayList<MediaType>();
		mediaTypes.add(mediaType);
		//加入转换器的支持类型
		jsonConverter.setSupportedMediaTypes(mediaTypes);
		//往适配器加入json转换器
		rmhd.getMessageConverters().add(jsonConverter);
		return rmhd;
	

好了上面的注释也比较清楚了,那么我们的配置就完了,接下来,你可能需要开发一些关于MyBatis的东西了,首先是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>
    <mappers>
        <mapper resource="com/ssm/chapter15/mapper/RoleMapper.xml"/>
    </mappers>
</configuration>

RootConfig.java中,它被加载了进来,那么我们要定义它RoleDao接口和RoleMapper.xml

package com.ssm.chapter15.dao;

import org.springframework.stereotype.Repository;

import com.ssm.chapter15.pojo.Role;
//在Mapper扫描器中注册的注解类,因此它会被扫描
@Repository
public interface RoleDao 
	public Role getRole(Long id);

还有我们的提供SQL的XML文件RoleMapper.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.ssm.chapter15.dao.RoleDao">
	<select id="getRole" resultType="com.ssm.chapter15.pojo.Role">
		select id, role_name as
		roleName, note from t_role where id = #id
	</select>
</mapper>


里面用了一个POJO,其实很简单了

package com.ssm.chapter15.pojo;

public class Role 

	private Long id;
	private String roleName;
	private String note;

	public Long getId() 
		return id;
	

	public void setId(Long 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;
	



这样 关于MyBatis的东西就完结了,跟着就是Service层,对于Service层肯定是使用事务的了。其实也不难。分别是RoleService接口和其实现类RoleServiceImpl

package com.ssm.chapter15.service;

import com.ssm.chapter15.pojo.Role;

public interface RoleService 
	//获取角色
	public Role getRole(Long id);

跟着就是实现类RoleServiceImpl.java

package com.ssm.chapter15.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.ssm.chapter15.dao.RoleDao;
import com.ssm.chapter15.pojo.Role;
import com.ssm.chapter15.service.RoleService;

@Service
public class RoleServiceImpl implements RoleService 

	@Autowired
	private RoleDao roleDao = null;

	@Override
	@Transactional(isolation = Isolation.READ_COMMITTED, propagation = Propagation.REQUIRED)
	public Role getRole(Long id) 
		return roleDao.getRole(id);
	




这样MyBatis和Service包含的事务都搞定了,那么我们再开发控制器

package com.ssm.chapter15.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.ResponseBody;

import com.ssm.chapter15.pojo.Role;
import com.ssm.chapter15.service.RoleService;

@Controller
@RequestMapping("role")
public class RoleController 

    @Autowired 
    RoleService roleService = null;
    
    @RequestMapping("getRole")
    @ResponseBody
    public Role getRole(Long id) 
        Role role = roleService.getRole(id);
        return role;
    



这样就完成了控制器的开发,为了更好的展示,博主再给你们展示目录

除了MyBatis的配置文件使用XML外,其他都不使用哦,其中log4j.properties文件是为了显示日志的,下面是一个显示debug级别的日志配置

log4j.rootLogger=DEBUG , stdout  
log4j.logger.org.mybatis=DEBUG   
log4j.logger.org.springframework=DEBUG  
log4j.appender.stdout=org.apache.log4j.ConsoleAppender   
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout   
log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n  

下面建表(MySQL):

create database chapter15;
use chapter15;

create table t_role (
id int(12) auto_increment,
role_name varchar(60) not null,
note varchar(256) null,
primary key (id)
);

truncate t_role ;

insert into t_role(role_name, note) values('role_name_1', 'note_1'); 
insert into t_role(role_name, note) values('role_name_2', 'note_2'); 
insert into t_role(role_name, note) values('role_name_3', 'note_3'); 
insert into t_role(role_name, note) values('role_name_4', 'note_4'); 
好了 ,这样我们可以进行测试了。

瞧大功告成了

以上是关于使用全注解配置Spring MVC+Spring +MyBatis框架,带事务配置。的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC学习—基于注解的Controller控制器的配置全解一万字

SpringMVC的全注解开发

Spring MVC学习—Validation基于注解的声明式数据校验机制全解一万字

spring mvc 必须使用注解配置吗?可不可使用xml配置?求高手详解

如何在带有注解配置的spring mvc中使用spring数据

spring中aop全注解时配置类怎么写