即将交稿我的新作《Java EE互联网轻量级框架整合开发——Spring + Spring MVC + MyBatis(SSM框架)和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');好了 ,这样我们可以进行测试了。
瞧大功告成了