Mybatis学习笔记之三:Mybatis的常用配置介绍

现在许多框架都提供了两种配置方式,文件配置和注解配置

文件配置主要使用xml文件,其他的还有properties,yml等。注解则是嵌入代码中。看到这儿应该明白,注解配置是与代码嵌在一起,没有解耦。而配置文件则是与代码分离开来,但是在实际开发中,很少有这种情况:修改配置文件但不修改代码的。

Mybatis也提供了注解和文件两种配置。这儿着重介绍文件配置的方式,因为Mybatis主要就是使用文件配置,如果使用注解,那么Myabtis的sql语句与代码分离这个优势就不存在了。

Mybatis的配置文件主要分为两部分,mybatis全局配置文件和mapper配置文件。

1、Mybatis的全局配置文件:Mybatis-config.xml




所有的配置都必须在configuration标签之间。

1.1、Properties配置。

 前面用到了properties这个标签,在resources属性中引入了db.properties。这个标签顾名思义就是配置属性的。


	
	
可以使用resource属性引入配置文件,也可以使用url属性引入,但注意resource和url两个属性不能同时指定,虽然你可以在配置文件中这样书写(不会报错),但是当初始化时就会抛出异常。初始化代码为org.apache.ibatis.builder.xml.XMLConfigBuilder的propertiesElement(XNode)方法,代码如下:

if (context != null) {
      Properties defaults = context.getChildrenAsProperties();
      String resource = context.getStringAttribute("resource");
      String url = context.getStringAttribute("url");
     //同时指定了resource和url会报错
      if (resource != null && url != null) {
        throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference.  Please specify one or the other.");
      }
      if (resource != null) {
        defaults.putAll(Resources.getResourceAsProperties(resource));
      } else if (url != null) {
        defaults.putAll(Resources.getUrlAsProperties(url));
      }
      Properties vars = configuration.getVariables();
      if (vars != null) {
        defaults.putAll(vars);
      }
      parser.setVariables(defaults);
      configuration.setVariables(defaults);
    }
也可以使用property指定单个属性,但注意代码中的property会覆盖resource或者url引入的配置,也会覆盖property标签配置的属性,这是因为解析顺序为:property标签-->引入的配置文件 --> 代码中的properties。且是使用Properties这个类来存储的,关于Properties类,可以自己使用一下。可以使用${}引用前面配置的属性。

值得注意的是:如果要使用properties这个标签,那么必须将该标签放在其他标签之前,且一个配置文件中只能出现一次properties标签。

1.2 settings全局的设置


  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
注意:settings里面至少包含一个setting

1.3 typeAliases别名配置,这个标签存在的意义仅是为了减少冗余。

      正如上篇看到的,如果不配置这个属性,那么配置文件中就必须使用类的全称限定名。例如配置这个属性前使用org.yamikaze.model.User,配置后使用User,大大减少了冗余。也可以使用typeAlias配置单个别名。如下所示:


	
    
	
	
	
注意:这个标签配置最多出现一次,且typeAlias必须在package前面,而且不能有相同的别名,否则报错。
1.4、配置开发环境environments。


		
		
			
			
			
			
			
				
				
				
				
			
		
		
		
			
			
			
			
			
				
				
				
				
			
		
	
可以配置多个环境,但是只能使用其中一个。环境一定要配置环境的id,事务管理器以及数据源。同时一定要指定默认的环境。事务管理器一般使用JDBC来提交回滚,数据源Mybatis内置了三种,POOLED、UNPOOLED、JNDI。当然你可以使用第三方数据源,比如DBCP、C3P0、Druid等。

1.5、映射器mappers。

        用于指定实体类对应的配置文件或者接口。


	
	
	
	
	
	
	
	

注意:如果你使用的是注解配置,那么指定接口,否则指定配置文件。一般使用resource指定配置文件。

configuration下面还有许多标签配置,单个人感觉不是很常用。更多配置参考http://www.mybatis.org/mybatis-3/zh/index.html。

2、实体类mapper文件配置。

      这个配置文件配置了实体类相关的所有sql语句以及返回结果集。

     所有的配置都应该放在mapper标签之间,如:




    
        insert into t_user(username,password,sex) values(#{username},#{password},#{sex})
    
    

2.1、insert标签、update标签、delete标签
         这几个标签用于向数据库插入数据、更新数据、删除数据。为什么要把他们放在一起?这是因为在配置文件中它们的配置几乎是一致的,差别在于sql语句的不同。如果你感兴趣的话,可以查看Mybatis的源代码,你会发现虽然可以调用session.insert()、session.delete(),但是最后实际调用的都是session的update方法。

        每个标签都共有的属性:

         id:每一个标签必须制定id,同一个配置文件不能指定相同的id,但不同的配置文件可以相同,例如,我们可以统一约定 插入语句id为save或者insert,更新语句id为update,删除语句id为delete。

         parameterType:参数类型,Mybatis内置了许多java类型,例如string、integer(int)、map等,你也可以使用你自己定义的实体类(注意配置别名)。实际上,你可以不在配置文件中配置这个属性,因为Myabtis可以通过TypeHandler判断具体传入的类型。但最好还是指定,这样比较好维护sql语句。还有一个parameterMap也可以指定参数类型,但这个属性在3版本已经被声明过时了。

         useGeneratedKeys和keyProperty,useGenerateKeys表示是否使用数据库自动生成的主键,默认是为false的,如果设置为true,同时指定了keyProperty,那么会将自动生成后的主键注入到指定的属性中,如下:

public static void main(String[] args) {
        IUserDao userDao = new UserDao();
        User u = new User();//u的Id为0,因为没有指定
        u.setUsername("tom");
        u.setSex("man");
        u.setPassword("951001");
        userDao.save(u); //save语句设置了useGeneratedKeys为true,keyProperty="id"
        System.out.print(u.getId()); //u的id为9,这是第9条数据
    }
      但是注意:这两个属性仅对insert和update语句有效。

     timeout属性:指定超时时间,会覆盖前面全局配置。

    statementType:指定使用statement还是preparedstatement还是callablestatement,默认为preparedstatement。

    一般可以这样配置:

    
        INSERT INTO t_user(username,password,sex) VALUES(#{username},#{password},#{sex})
    

    
        DELETE  FROM t_user WHERE id = #{id}
    
    
    
        UPDATE t_user SET username = #{username},password = #{password},sex = #{sex}
        WHERE id = #{id}
    
   注意:这三条语句可以有返回值,但是返回的是数据库数据的修改行数。

2.2、select标签。

          这个标签用于查找数据,使用频率最高的select语句。它的通用配置与insert是一致的,但不同于insert的是它有返回值。同时select语句的查询以及结果映射也是Mybatis研究的焦点。

          resultType:返回类型,如果是返回集合,那么应该是集合包含的具体类型,例如:返回List,那么应该填User,而不应该是List

          resultMap:如果需要返回更复杂的类型,那么请使用resultMap。resultMap需要在配置文件中手动配置。

     
2.3、sql标签。

         这个标签用于定义一些可重用的sql片段。比如,查找用户点赞或者收藏的文章列表时,查找出的数据类型是一样的,但是关联的表不一样,那么可以将查询的一部分提取出来重用。 例如:

    
        
        SELECT ${tableName1}.*,${tableName2}.*
    

    
2.4、resultMap标签。

         前面select标签的resultMap属性值必须是resultMap定义的。

         我们先来看下resultMap的简单结果映射。

    
       看着这条sql语句没有使用resultMap,但其实Mybatis会在幕后自动创建一个resultMap来映射。例如:数据库行名为username,对应的属性名为username那么就会精确到username属性中。也许你数据库的是user_name,那么你可以这样使用:
    
       或者配置resultMap:
    
        
    
       然后在select标签的返回值使用userResult就ok了,你注意到了autoMapping=true吗?设置为true会自动映射没有用result子标签指定的属性
       然而这是单张表的映射,如果有许多关联对象的呢?比如用户与IDCARD一一关联,而用户又与商品列表一对多关联。通过查询出一个用户以及用户相对应的IDCARD和消息列表来看看这个resultMap怎么配置吧。

       IDCard实体类:  

package org.yamikaze.model;

import java.util.Date;

/**
 * Created by yamikaze on 2017/7/12.
 */
public class IDCard {
    private Long no;         //卡的编号
    private Long uid;        //关联用户的id
    private Date createTime; //绑定卡的时间
    private String type;     //卡的类型

    //setter & getter方法略
}
      Message.java
package org.yamikaze.model;

import java.util.Date;

/**
 * Created by yamikaze on 2017/7/12.
 */
public class Message {

    private Long id;        //留言Id
    private Long uid;       //留言用户的id
    private String content; //留言内容
    private Date createTime;//留言时间
    private String ipAddress;//留言ip地址
    private Long mid;       //如果为null表示留言,不为null表示是对留言的留言
    //setter & getter方法略
}
     User.java

package org.yamikaze.model.model0;

import org.yamikaze.model.IDCard;
import org.yamikaze.model.Message;

import java.util.List;

/**
 * Created by yamikaze on 2017/7/12.
 */
public class User {

    private Long id;               //用户id
    private String username;       //用户名
    private String nickname;       //用户昵称
    private String password;       //用户密码
    private String sex;            //用户性别
    private IDCard idCard;         //用户关联的IDCard对象
    private List messages;//用户的留言

    public User(Long id,String username,String password) {
        this.id = id;
        this.username = username;
        this.password = password;
    }
    //setter & getter方法略

}
注意:记得在mybatis-config中配置别名,以及将相对应的实体类mapper文件加入到mappers中。

User表结构为:

Mybatis学习笔记之三:Mybatis的常用配置介绍_第1张图片
IDCard表结构:

Mybatis学习笔记之三:Mybatis的常用配置介绍_第2张图片
Message表结构:
Mybatis学习笔记之三:Mybatis的常用配置介绍_第3张图片

  开始编写Mapper文件吧!

  MessageMapper文件与IDCardMapper文件略(里面只用添加一个insert方法)

   UserMapper文件





    
        insert into t_user0(username,nickname,password,sex,id)
        value (#{username},#{nickname},#{password},#{sex},#{id})
    

    

    
        
        
            
            
            
            
            
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    

    
        
    

    

    
        
        
    
测试代码(请在测试前录入相应测试数据):

public static void load() {
        InputStream is = null;
        SqlSessionFactory factory = null;
        SqlSession session = null;
        try {
            is = Resources.getResourceAsStream("mybatis-config.xml");
            factory = new SqlSessionFactoryBuilder().build(is);
            session = factory.openSession();

            User0 user = (User0)session.selectOne("load",1L);
            System.out.println(user.getSex());
            System.out.println(user.getMessages().size());
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if(session!=null) session.close();
        }
    }
结果:
Mybatis学习笔记之三:Mybatis的常用配置介绍_第4张图片
看了userMapper的配置,我们发现有嵌套查询和结果嵌套两种方式映射。

嵌套查询会重新发sql语句查询,而结果嵌套需要我们手动为结果配置别名,比如测试的IDCard类与Message类都有no属性,那么要使用结果嵌套我们就需要这样指定别名

select card.no as card_no,message.no as message_no.......这样的方式。同时建议开启autoMapping=true,这样可以减少配置。

3、缓存配置。

在mapper映射文件中开启缓存只需要加入这一句:

关于cache标签:
所有 select 语句将会被缓存。默认useCache=true
所有 insert,update 和 delete 语句会刷新缓存。默认flashCache=true。
缓存会使用Least Recently Used(LRU,最近最少使用的)算法来收回。
根据时间表(比如 no Flush Interval,没有刷新间隔), 缓存不会以任何时间顺序 来刷新。
缓存会存储列表集合或对象(无论查询方法返回什么)的 1024 个引用。
缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。

flushInterval:刷新间隔。

size:引用对象的数量,必须是整数。

readOnly是否可读可写。
eviction:回收策略,默认为LRU

当然你可以自定义缓存,使用type属性来指定。例如:

这个类必须实现 org.mybatis.cache.Cache接口,如果要向实现类传值的话,可以使用property标签,如下:



注意:使用缓存不要忘了在mybatis-config.xml文件中开启全局缓存。


Mybatis常用的配置基本就这些了,因个人原因可能还有一些其他的配置没有提到的。

如果想了解Mybatis具体有哪些配置的话可以访问http://www.mybatis.org/mybatis-3/zh/index.html

你可能感兴趣的:(java)