zoukankan      html  css  js  c++  java
  • 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(1)  
    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(3)  
    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);
    }

     

  • 相关阅读:
    网上找的,C# 小票打印机 直接打印,备用
    SlickUpload 破解方法
    全文索引的一点个人总结
    在ASP.NET中利用SlickUpload来上传大文件
    再谈iframe自适应高度 By 大米
    发送邮件到 163、Gmail、QQ 等邮箱时,全丢垃圾箱中怎么办?
    iis下Awstats的安装使用说明
    AutoCompleteExtender控件出现undefined和null现象
    IT业史上最棒的图片之一
    EnableViewState="false",取dropdownlist的值
  • 原文地址:https://www.cnblogs.com/a8457013/p/9074960.html
Copyright © 2011-2022 走看看