Spring+MyBatis纯注解零XML整合(4)
不得不说,利用XML作为配置文件是一个非常好的想法,它可以轻松地实现配置集中化,而且修改之后无需再次编译。然而,由于大多数情况下开发者基本都会拿到程序的源码,加之对于各种XML配置文件一般情况下也只有开发者会去动,可以说XML在一定程度上也相当于程序代码,只是不用编译而已。因此很多人并不是很喜欢XML这种东西。早在Spring 2.5之前就有很多人对满天飞的XML配置叫苦不迭。从Spring 3开始,Java config开始出现,这一特性使得Spring能够摆脱XML配置文件。但是大多数人仍然通过XML文件配置注解,这样的用法并未完全摆脱XML。实际上,从这时候开始就完全可以通过Java Config而非XML来对Spring进行配置了。加上MyBatis也完全可以通过注解来配置mapper,因此对于不喜欢XML配置的读者,这篇文章可以说是值得一看。本文以Spring 4为例介绍Spring与MyBatis纯注解整合。
首先你需要:
- 了解传统的通过XML配置Spring+MyBatis的方法
- Spring 4 + MyBatis 3
- Servlet 3.0
- Java 8
- 20分钟的时间
对于传统的Web项目自然少不了web.xml。然而从Servlet 3.0开始,这个东西已经被WebApplicationInitializer取代。顾名思义,WebApplicationInitializer是对Web应用进行初始化的一个东东。不过WebApplicationInitializer是一个接口,所以你需要提供一个WebApplicationInitializer的实现类。当你把实现类写好之后,Servlet 3.0可以自动发现它并对servlet进行初始化(当然也可以是多个实现类),可以说这个接口的实现类一定程度上等价于web.xml的配置。下面的WebApplicationInitializer实现类为Servlet的根配置,并指定该配置的加载顺序为所有配置之前(由@Order注解控制,数值越小优先级越高)。本例中该配置为空,可通过清单1中的方式来配置Filter、Listener和Servlet。
清单1 配置根WebApplicationInitializer
package org.fhp.springmybatis.config; import org.springframework.core.annotation.Order;
import org.springframework.web.WebApplicationInitializer; import javax.servlet.*; @Order()
public class BasicWebInitializer implements WebApplicationInitializer { @Override
public void onStartup(ServletContext servletContext) throws ServletException {
// servletContext.addFilter("filterName", AFilter.class).addMappingForUrlPatterns(EnumSet.allOf(DispatcherType.class), false, "/");
// servletContext.addListener(EventListener.class);
// servletContext.addServlet("servletName", AServlet.class);
}
}
接下来需要进行Spring的Servlet配置。Spring提供了AbstractAnnotationConfigDispatcherServletInitializer类(也是WebApplicationInitializer的子类),实现之即可进行Spring的servlet配置。这里需要把加载顺序放在BasicWebInitializer之后。
清单2 配置Spring的WebApplicationInitializer
package org.fhp.springmybatis.config; import org.springframework.core.annotation.Order;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.filter.CharacterEncodingFilter;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer; import javax.servlet.Filter; @Order()
public class SpringInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { //配置Spring根上下文配置类
@Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] {SpringRootConfig.class};
} //配置Spring Web上下文配置类
@Override
protected Class<?>[] getServletConfigClasses() {
return new Class[] {SpringWebConfig.class};
} //配置在什么路径下使用Spring的DispatcherServlet。等价于给DispatchServlet指定对应的url-mapping
@Override
protected String[] getServletMappings() {
return new String[] { "/" };
} //配置与Spring相关的Filter。这里规定Spring MVC的编码为UTF-8。
@Override
protected Filter[] getServletFilters() {
CharacterEncodingFilter characterEncodingFilter = new CharacterEncodingFilter();
characterEncodingFilter.setEncoding("UTF-8");
characterEncodingFilter.setForceEncoding(true);
return new Filter[] { characterEncodingFilter };
}
}
这里Servlet的配置,等价于XML配置中的web.xml就完成了。下面开始Spring的ApplicationContext配置。
首先进行Web的上下文配置。进行Web的上下文配置需要继承WebMvcConfigurerAdapter类,同时配置类也要有@Configuration,@EnableWebMvc和@ComponentScan注解。这里配置一个对静态文件访问的支持,在WebMvcConfigurerAdapter可以看到其他的配置,这里就不多说了。
清单3 Spring Web ApplicationContext配置
package org.fhp.springmybatis.config; import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter; import java.util.List; @Configuration
@EnableWebMvc
@ComponentScan(basePackages = "org.fhp.springmybatis")
public class SpringWebConfig extends WebMvcConfigurerAdapter { @Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
registry.addResourceHandler("*.html").addResourceLocations("/");
}
}
其次进行根上下文的配置。这里通过@Bean注解来取代XML中的<bean>标签。
清单4 Spring Root ApplicationContext配置
package org.fhp.springmybatis.config; import org.springframework.context.annotation.*;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.beans.factory.config.PropertyPlaceholderConfigurer;
import org.springframework.core.io.ClassPathResource; @Configuration
@ComponentScan("org.fhp.springmybatis")
@EnableAspectJAutoProxy(proxyTargetClass=true)
@EnableTransactionManagement
@Import(DaoConfig.class)
public class SpringRootConfig { @Bean
public PropertyPlaceholderConfigurer getTestPpc() {
PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer();
ppc.setLocations(new ClassPathResource("jdbc.properties"));
return ppc;
}
}
其中jdbc.properties内容如下:
清单5 jdbc.properties配置
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/test_mysql
jdbc.user=root
jdbc.password=root
然后是DAO层的上下文。
清单6 DAO上下文配置
package org.fhp.springmybatis.config; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.DriverManagerDataSource; import javax.sql.DataSource; @Configuration
@MapperScan(value="org.fhp.springmybatis.dao")
public class DaoConfig { @Value("${jdbc.driverClass}")
private String driverClass; @Value("${jdbc.user}")
private String user; @Value("${jdbc.password}")
private String password; @Value("${jdbc.jdbcUrl}")
private String jdbcUrl; @Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driverClass);
dataSource.setUsername(user);
dataSource.setPassword(password);
dataSource.setUrl(jdbcUrl);
return dataSource;
} @Bean
public DataSourceTransactionManager transactionManager() {
return new DataSourceTransactionManager(dataSource());
} @Bean
public SqlSessionFactory sqlSessionFactory() throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
return sessionFactory.getObject();
}
} 至此Spring的配置完成。
现在,我们假设有如下实体类。 清单7 实体类定义 [java] view plain copy
package org.fhp.springmybatis.entity; public class Person {
private long id;
private String name;
private String nick; public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getNick() {
return nick;
}
public void setNick(String nick) {
this.nick = nick;
}
}
由于在清单6中@MapperScan规定了扫描Mapper的包为org.fhp.springmybatis.dao,因此我们只要将mapper配置类放在这个包下,MyBatis即可自动识别。
清单8 Mapper的配置
package org.fhp.springmybatis.dao; import java.util.List; import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.Update;
import org.fhp.springmybatis.entity.Person; public interface PersonDao { @Insert(value="insert into t_person(name, nick) values (#{name}, #{nick})")
void add(Person person); @Delete(value="delete from t_person where id=#{id}")
void delete(long id); @Update(value="update t_person set name=#{name}, nick=#{nick} where id=#{id}")
void update(Person person); @Select(value="select * from t_person where id=#{id}")
Person select(long id);
}
可以看到,通过@Insert,@Delete,@Update,@Select注解加SQL语句的配置,即可实现MyBatis对数据库的增删改查操作。
那么假如需要动态地生成SQL语句,该怎么办呢?答案是使用MyBatis提供的@InsertProvider,@DeleteProvider,@UpdateProvider,@SelectProvider注解,当然也是对应数据库的增删改查。这里以@SelectProvider为例。
首先定义一个Provider类。
清单9 Provider类
public class PersonSqlProvider {
public String selectByNameAndNick(@Param("name") String name, @Param("nick") String nick) {
StringBuffer sb = new StringBuffer();
sb.append("select * from t_person where ");
sb.append("name=#{name}");
sb.append(" and ");
sb.append("nick=#{nick}");
return sb.toString();
}
}
然后就要有请我们的@SelectProvider出场了。
清单10 使用@SelectProvider
@SelectProvider(type=PersonSqlProvider.class, method="selectByNameAndNick")
List<Person> selectByNameAndNick(@Param("name") String name, @Param("nick") String nick);
当然,在本例当中即使不用Provider也是能够实现的,这里只是为了演示Provider的效果。我们可以看到,SQL语句由程序拼接,自然可以实现动态SQL中if条件判断以及SQL当中in语句等复杂语句的拼接,而且一定程度上比用XML更灵活。
综上,本文介绍了Spring与MyBatis整合的另一种思路——纯注解无XML的配置方法。随着越来越多的框架都逐渐采用注解进行配置,可以说无XML配置已经成为一种趋势。如果你已经用上了Spring 4,不妨尝试一下这样的方法,你一定会感到很满意的。
/**
* 城市 DAO 接口类
* Created by wanglu-jf on 17/6/27.
* @Mapper 标志接口为 MyBatis Mapper 接口
* @Select 是 Select 操作语句
* @Results 标志结果集,以及与库表字段的映射关系
*/
@Mapper
public interface CityDao {
/**
* 查询城市信息
*/
@Select(" SELECT * FROM city WHERE id = #{id}")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "provinceId", column = "province_id"),
@Result(property = "cityName", column = "city_name"),
@Result(property = "description", column = "description")
})
public City queryCityById(@Param("id") int id);
}
Spring+MyBatis纯注解零XML整合(4)的更多相关文章
- Spring+Mybatis基于注解整合Redis
基于这段时间折腾redis遇到了各种问题,想着整理一下.本文主要介绍基于Spring+Mybatis以注解的形式整合Redis.废话少说,进入正题. 首先准备Redis,我下的是Windows版,下载 ...
- spring boot纯注解开发模板
简介 spring boot纯注解开发模板 创建项目 pom.xml导入所需依赖 点击查看源码 <dependencies> <dependency> <groupId& ...
- spring与hibernate注解及XML方式集成
spring与hibernate注解及XML方式集成 Hibernate Xml方式 该种方式需要在sessionFactory中引入对应的hbm.xml文件,样例如下: <!-- spring ...
- mybatis使用注解替代xml配置,动态生成Sql
mybatis使用注解替代xml配置时,遇到判断条件是否为null或者为空时,@Select很难搞定,不知道怎么办? mybatis3中增加了使用注解来配置Mapper的新特性,使用 SelectPr ...
- SpringMvc+Spring+MyBatis 基于注解整合
最近在给学生们讲Spring+Mybatis整合,根据有的学生反映还是基于注解实现整合便于理解,毕竟在先前的工作中团队里还没有人完全舍弃配置文件进行项目开发,由于这两个原因,我索性参考spring官方 ...
- springMVC,spring,mybatis全注解搭建框架--第一步,让框架跑起来
自己从事java开发工作也有一年多了,自己却没有亲手搭建一个完整的框架.于是今天自己动手搭建一个,过程中遇到一些问题,倒腾了大半天终于搞定了. 现在给大家分享一下过程,自己也记录下来,以后学习参考使用 ...
- 10 Spring框架--基于注解和xml的配置的应用案例
1.项目结构 2.基于xml配置的项目 <1>账户的业务层接口及其实现类 IAccountService.java package lucky.service; import lucky. ...
- Spring MVC4 纯注解配置教程
阅读本文需要又一定的sping基础,最起码要成功的运行过一个SpringMvc项目. 在传统的Spring项目中,我们要写一堆的XML文件.而这些XML文件格式要求又很严格,很不便于开发.而网上所谓的 ...
- 玩转SSH(五):Struts + Spring + MyBatis(注解版)
本文将在 玩转SSH(四):Struts + Spring + MyBatis 的基础上进行一些小的改动,将原本是 xml 配置方式的项目,改成注解的配置方式. 要将项目改成注解方式,一般是将在 Sp ...
随机推荐
- Select、Poll与Epoll比較
(1)select select最早于1983年出如今4.2BSD中,它通过一个select()系统调用来监视多个文件描写叙述符的数组.当select()返回后,该数组中就绪的文件描写叙述符便会被内核 ...
- webrtc fec
转自:http://www.cnblogs.com/webrtc/p/7402570.html WebRTC::FEC [TOC] Tags: WebRTC FEC WebRTC中的 FEC 实现分为 ...
- svn各种箭头的含义
黄色感叹号(有冲突): 有冲突了,冲突就是你对某个文件进行了修改,别人也对这个文件进行了修改,别人抢在你提交之前先提交了,这时你再提交就会被提示发生冲突,而不允许 你提交,防止你的提交覆盖了 ...
- Java并发编程的艺术(八)——闭锁、同步屏障、信号量详解
1. 闭锁:CountDownLatch 1.1 使用场景 若有多条线程,其中一条线程需要等到其他所有线程准备完所需的资源后才能运行,这样的情况可以使用闭锁. 1.2 代码实现 // 初始化闭锁,并设 ...
- Generalized normal distribution and Skew normal distribution
Density Function The Generalized Gaussian density has the following form: where (rho) is the " ...
- java实时监听日志写入kafka(转)
原文链接:http://www.sjsjw.com/kf_cloud/article/020376ABA013802.asp 目的 实时监听某目录下的日志文件,如有新文件切换到新文件,并同步写入kaf ...
- C++对带有分隔符的字符串 分割为数字的通用解决方案
需求: 数据库取出的字段类似于 "1,3,4" 然后用数字处理后,,比如 "1,2,3" 再存回去 #include<stdio.h> #inclu ...
- emouse思·睿—评论与观点整理之一
虽说我主要做的硬件,平时的兴趣爱好比较关注移动互联网,混迹于虎嗅.爱范儿.雷锋网.36Kr.cnBeta.瘾科技.i黑马.TechWeb等这类科技以及创业媒体,遗憾的是系统的去写的并不多,好在还算充分 ...
- Log Shipping搭建
1. 概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据库”内的事务日志备份发送到单独“辅助服务器”实例上的一个或多个“辅助数据库”.事务日志备份分别应用于每个辅助 ...
- opengl 教程(24) shadow mapping (2)
原帖地址:http://ogldev.atspace.co.uk/www/tutorial24/tutorial24.html 本篇教程中,我们通过shadowmap来实现阴影渲染. 我们知道shad ...