Spring下的Mybatis配置

J2EE开发界中一个永远避免不了的争论就是HibernateMybatis哪个好。虽然我自己倾向Hibernate,但这两种ORM框架我也都没有在比较大型的场景上使用过,没有资格做评价。

最近公司有一个项目,主程让我用SpringMybatis搭建服务端框架,这里就做一下简单的学习记录。

Java Config方式的Mybatis启动配置

首先在maven中加上Mybatismybatis-spring的依赖:


   org.mybatis
   mybatis-spring
   1.2.2



   org.mybatis
   mybatis
   3.2.8

前一篇中提到,公司推荐Spring使用Java Config的方式进行配置,所以Mybatis也不例外。
先看一段网上找到比较常见的xml方式配置:


    
    



      
    
      
    
    

配置的核心是sqlSessionFactory,将dataSource数据源注入就完成了Mybatis会话工厂的实例化了。
接着把这段配置翻译成Java config版本:

@Configuration
@PropertySource("classpath:druid-config.properties")
public class JdbcConfig {
    @Value("${druid.driverClassName}")
    private String driverClassName;
    @Value("${druid.url}")
    private String url;
    @Value("${druid.user}")
    private String username;
    @Value("${druid.password}")
    private String password;
    @Value("${druid.maxActive}")
    private int maxActive;

    @Bean
    public DataSource dataSource(){
        DruidDataSource ds = new DruidDataSource();
        ds.setDriverClassName(driverClassName);
        ds.setUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        ds.setMaxActive(maxActive);
        ds.setMinIdle(0);
        return ds;
    }

    @Bean
    public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
        ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
        //加载匹配到的xml映射配置
        Resource[] resources =  resolver.getResources("classpath*:com/nd/mathlearning/server/*/dao/mapper/*.xml");
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource());
        bean.setMapperLocations(resources);
        //加载Mybatis配置
        bean.setConfigLocation(resolver.getResource("classpath:mybatis/mybatis-config.xml"));
        return bean;
    }

    @Bean
    public SqlSessionTemplate sqlSessionTemplate() throws Exception {
        SqlSessionTemplate bean = new SqlSessionTemplate(sqlSessionFactory().getObject());
        return bean;
    }
}
  • @Configuration表明此类用作Spring配置
  • @PropertySource说明读取哪个配置文件
  • @Valueproperties中的配置项注入进变量
  • @Bean注解的方法表明实例化对象。
  • ResourcePatternResolver是用来加载工程配置文件。

Mybatis的xml映射文件

Hibernate类似,Mybatis需要写xml配置来实现Java类与数据库表之间的映射关系,更多的,Mybatis框架执行的所有sql也都配置在xml中。
来看一段完整的xml配置:




  
    
    
    
  
  
    uc_user_id, user_id, user_name
  
  
  
    delete from uc_userid_map
    where uc_user_id = #{ucUserId,jdbcType=BIGINT}
  
  
    insert into uc_userid_map (uc_user_id, user_id, user_name
      )
    values (#{ucUserId,jdbcType=BIGINT}, #{userId,jdbcType=BIGINT}, #{userName,jdbcType=VARCHAR}
      )
  
  
    update uc_userid_map
    
      
        user_id = #{userId,jdbcType=BIGINT},
      
      
        user_name = #{userName,jdbcType=VARCHAR},
      
    
    where uc_user_id = #{ucUserId,jdbcType=BIGINT}
  

  • 根节点mapper中的namespace声明了此配置的唯一编号,在此后的javaapi调用就需要用到此属性
  • resultMap定义表到java实体类之间的字段映射关系
  • column是表字段
  • property是类属性
  • jdbcType是表字段类型。
  • sql节点在这里定义了一个sql查询片段,使用include语法拼接,用于简化配置。
  • selectinsertupdatedelete节点定义四种sql操作的方法。id定义方法的标识;
  • parameterType说明方法的参数类型,可以是javabean,但一个方法只能有一个输入参数。

更详细的mapper配置说明参考官网:

  • Mapper XML 文件

mapper与实体生成工具

既然Mybatis所有的逻辑操作都是配置在xml中,那就把原来在java中的sql开发工作转换到了xml上。
Hibernate一样,Mybatis提供了一个简易的逆向工程工具,帮助我们根据已有数据表生成对应的javabean和基本操作xml配置。
maven中增加生成器依赖:


    org.mybatis.generator
    mybatis-generator-core
    1.3.2

编写生成配置xml



    
    

    
    
        
        
        
        
            
            
        
        
        
        
        
            
        
        
        
        
            
            
        
        
            
        
    
        

有了生成配置xml后就可以调用api生成实体javabeandaomapper

public class MyBatisGenerator {
    public static void main(String args[]){
        String config ="";
        try {
            config = MyBatisGenerator.class.getResource("generator.xml").toURI().getPath();
        } catch (URISyntaxException e) {
            e.printStackTrace();
        }
        String[] arg = { "-configfile", config, "-overwrite" };
        ShellRunner.main(arg);
    }
}

参考文章:

  • 使用Mybatis-Generator自动生成Dao、Model、Mapping相关文件

与Spring整合

j2ee的各种开源框架中,我们最关心的可能就是怎么与Spring做整合。

数据映射器 MapperFactoryBean

Mybatis提供了一种简易的整合方式,使用class的方式定义mapper,而不需要配置xml
例如定义一个interfacemapper

public interface UserMapper {
    @Select("SELECT * FROM user WHERE id = #{userId}")
    User getUser(@Param("userId") long id);
}

然后在spring中定义:


      
      

Spring容器中就产生了userMapper实例可以来执行我们想要的数据操作。这种方式有点类似spring dataCrudRepository@Query用法。

抽象类SqlSessionDaoSupport的整合方式

从前面的启动配置我们知道了,Mybatisapi入口是sqlSessionFactoryMybatis提供SqlSessionDaoSupport抽象类来方便获取sqlSession
先看一个UserDao的实现:

public class UserDao extends SqlSessionDaoSupport{  
  @Autowired
  public void setSqlSessionTemplate(SqlSessionTemplate sqlSessionTemplate) {
    super.setSqlSessionTemplate(sqlSessionTemplate);
  }

  public User getUserById(User user) {  
     return (User) getSqlSession().selectOne("com.xxt.ibatis.dbcp.domain.User.getUser", user);  
  }  
}  

继承SqlSessionDaoSupport可以获得getSqlSession方法来得到sqlSession。然后通过sqlSessionapi最终调用到mapper里配置的sql程序。
sqlSession几个常用的api:

 T selectOne(String statement, Object parameter)  
 List selectList(String statement, Object parameter)  
 Map selectMap(String statement, Object parameter, String mapKey)  
int insert(String statement, Object parameter)  
int update(String statement, Object parameter)  
int delete(String statement, Object parameter)

第一个参数表示mapper中方法的唯一标识,结构为:mapper标识 + . + 方法标识

mybatis-spring 1.2版本中SqlSessionDaoSupport的变化

首先看1.2版本中SqlSessionDaoSupport的注释信息:

/**
 * Convenient super class for MyBatis SqlSession data access objects.
 * It gives you access to the template which can then be used to execute SQL methods.
 * 

* This class needs a SqlSessionTemplate or a SqlSessionFactory. * If both are set the SqlSessionFactory will be ignored. *

* {code Autowired} was removed from setSqlSessionTemplate and setSqlSessionFactory * in version 1.2.0. * * @author Putthibong Boonbong * * @see #setSqlSessionFactory * @see #setSqlSessionTemplate * @see SqlSessionTemplate * @version $Id$ */

之前版本中setSqlSessionTemplatesetSqlSessionFactoryAutowired,1.2之后需要我们手动注入。
这个改动应该是为了支持一个项目中建立多数据源的场景,我们可以用SqlSessionDaoSupport创建多个DAO层基类,选择不同的数据源注入。

参考文章:

  • spring与mybatis三种整合方法
  • Java API sqlSeesion

Mybatis插件配置

Mybatis提供了插件机制实现了功能扩展

分页插件PageHelper

数据库列表查询少不了分页功能,怎么在代码级别上简单有效地处理分页逻辑总是一大挑战。
实现分页功能关键是根据 两个参数 得到 两个数据

  • 两个参数:数据偏移量页面大小(或者通过 当前页码页面大小 进行转换)
  • 两个数据:当前页面的列表数据总记录数

sql层面上讲,需要两次查询:

  1. 根据查询条件用limit参数(在oraclerownum)得到当前请求页面数据。
  2. 用相同的条件count(*)查询数据库中存在的总数。

回到Mybatis,我们可以利用它的插件机制实现分页功能。
首先加上PageHelpermaven配置:


    com.github.pagehelper
    pagehelper
    3.7.1

在初始化sqlSessionFactory时加上插件配置:

@Bean
public SqlSessionFactoryBean sqlSessionFactory() throws IOException {
    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
    Resource[] resources =  resolver.getResources("classpath*:com/nd/mathlearning/server/*/dao/mapper/*.xml");
    Interceptor[] plugings = new Interceptor[1];

    PageHelper pageHelper = new PageHelper();//mybatis分页插件
    Properties p = new Properties();//插件属性配置
    p.put("dialect", "mysql"); //数据库言
    p.put("reasonable", "true");//参数合理化,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页
    p.put("offsetAsPageNum", "trsue"); //将RowBounds第一个参数offset当成pageNum页码使用
    pageHelper.setProperties(p);
    plugings[0] = pageHelper;

    SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
    bean.setDataSource(dataSource());
    bean.setMapperLocations(resources);
    bean.setPlugins(plugings); //插件注入到sqlSessionFactory
    bean.setConfigLocation(resolver.getResource("classpath:mybatis/mybatis-config.xml"));
    return bean;
}

其中属性配置详细信息参考项目主页。

在调用Mybatisapi时增加RowBounds参数实现分页:

List list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));

项目主页:

  • Mybatis-PageHelper

你可能感兴趣的:(Spring下的Mybatis配置)