MyBatis使用總結

iBatis從3.x開始改名爲MyBatis。除了Java之外,還有可用於.Net的Mybatis.Nethtml

相關依賴包(maven)java

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.2.2</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.2.7</version>
</dependency>

映射相關文件自動生成(mybatis-generator)mysql

iBatis提供了Abator用於生成映射相關文件。Mybatis能夠用mybatis generator實現相似功能。web

生成配置文件

mybatis默認使用的路徑和文件名(無需配置):src/main/resources/generatorConfig.xml算法

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- classPathEntry:數據庫的JDBC驅動-->
    <classPathEntry location="target\assist\WEB-INF\lib\mysql-connector-java-5.1.32.jar"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 去除自動生成的註釋 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
        </commentGenerator>
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/testdb?autoReconnect=true" userId="xxxx" password="xxxxx"/>
        <!-- 生成Model類,targetProject:自動生成代碼的位置 -->
        <javaModelGenerator targetPackage="com.demo.models" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
     <!-- 生成XML映射文件 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
     <!-- 生成Mapper接口(DAO) -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.demo.mappers" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
     <!-- 經過javaTypeResolver元素控制類型轉化,也能繼承JavaTypeResolver接口實現本身的類型轉換器。 -->
     <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/> <!--將 JDBC DECIMAL和NUMERIC解析爲Integer,而不是BigDecimal-->
        </javaTypeResolver>
     <!-- 要生成映射代碼的數據表,tableName爲表名;domainObjectName爲對應的javaBean類名, enablexxxxx是與Example類相關的配置 -->
        <table tableName="person" domainObjectName="Person"/>
        <table tableName="my_table" domainObjectName="myTable" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false">
      <!--<columnRenamingRule searchString="^D_" replaceString=""/>
           <property name="useActualColumnNames" value="false"/>
           -->
        </table>
    ......
    </context>
</generatorConfiguration>
  • Example類實現了查詢條件的對象化。
  • "_"分隔的字段名會自動轉化爲駝峯形式。
  • oracle nvarchar/nvarchar2類型會轉化成Object類型。
  • oracle指定精度的數值型字段默認轉爲BigDecimal,不指定精度的數值型默認轉爲Long。
  • targetProject屬性能夠設置爲MAVEN,代碼將生成在target/generatored-source目錄下。
  • generatorConfiguration節點下添加 <properties resource="jdbc.properties" />,能夠在配置中的${...}表示的佔位符。獲取文件的方式爲:Thread.currentThread().getContextClassLoader().getResource(resource)
  • context節點下添加<plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin> 生成的pojo類implements Serializable。
  • 經過enableCountByExample, enableUpdateByExample, enableDeleteByExample, enableSelectByExample, selectByExampleQueryId等屬性能夠控制是否生成和使用xxxExample類在查詢中替代模型類。

 

從屬性文件中加載配置

generatorConfig.properties文件spring

# 數據庫驅動jar 路徑
driver.class.path=target/assist/WEB-INF/lib/mysql-connector-java-5.1.32.jar

# 數據庫鏈接參數 
jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql://localhost:3306/dbname?useUnicode=true&characterEncoding=utf-8 
jdbc.username=uname 
jdbc.password=pwd 

# 包路徑配置 
model.package=com.demo.modules.entity 
dao.package=com.demo.modules.mapper 
xml.mapper.package=com.demo.modules.mapper 
target.project=src/main/java
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <properties url="${mybatis.generator.generatorConfig.properties}"> <!--maven pom文件properties中配置的屬性-->
    <classPathEntry location="${driver.class.path}"/>
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <jdbcConnection driverClass="${jdbc.driver}" connectionURL="${jdbc.url}" userId="${jdbc.username}" password="${jdbc.password}"/>
        <!-- 生成Model類,targetProject:自動生成代碼的位置 -->
        <javaModelGenerator targetPackage="${model.package}" targetProject="${target.project}">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
    ......
    </context>
</generatorConfiguration>

構建時自動生成

<plugin>
        <groupId>org.mybatis.generator</groupId>
        <artifactId>mybatis-generator-maven-plugin</artifactId>
        <version>1.3.2</version>
        <configuration>
       <!-- 省缺值爲:src/main/resources/generatorConfig.xml
       <configurationFile>src/main/resources/mybatis-generator/generatorConfig.xml</configurationFile>-->
            <verbose>true</verbose>
            <overwrite>true</overwrite>
        </configuration>
      <executions>
            <execution>
               <id>Generate MyBatis Artifacts</id>
               <goals>
                  <goal>generate</goal>
               </goals>
            </execution>
        </executions>
   </plugin>

 

經過命令行調用

mvn  mybatis-generator:generate 
mvn  mybatis-generator:generate -Dmybatis.generator.overwrite=true

 

直接執行

使用mybatis-generator-core-xxxx.jar包sql

java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite

 

自定義類型轉換 

http://blog.csdn.net/lele2426/article/details/38794399 數據庫

 

MyBatis映射相關文件

(1). model類 xxx.java

生成的model類是普通的java類,包含與數據庫表各個字段對應的屬性極其setter和getter方法。express

 

(2). 查詢條件類 xxxExample.java

http://openwares.net/database/mybatis_generator_example.htmlapache

Example類用於構造複雜的篩選條件。

Criterion

  Criterion是最基本,最底層的Where條件,用於字段級的篩選。主要有如下這些:

  • field IS NULL
  • field IS NOT
  • field > value
  • field >= value
  • field =value
  • field <> value
  • field <= value
  • field < value
  • field LIKE value
  • field NOT LIKE value
  • field BETWEEN value1 AND value2
  • field IN (item1, item2,...)
  • field NOT IN (item1, item2, ...)

  LIKE模糊查詢的%,?字符只能在構造查詢條件是手動指定。

  Mybatis Generator會爲每一個字段生成如上所示的Criterion,理論上能夠構造任何篩選條件,若是字段較多生成的Example類會很大。

Criteria

  Criteria包含了Cretiron的集合,同一個Criteria中的各個Cretiron之間爲邏輯與(AND)關係。

oredCriteria

  Example內有一個成員叫oredCriteria,是Criteria的集合,集合中的各個Criteria直接爲邏輯或(OR)的關係。

用法

http://mybatis.org/generator/generatedobjects/exampleClassUsage.html

TestTableExample example = new TestTableExample();
example.or()
    .andField1EqualTo(5)
    .andField2IsNull();
 
  example.or()
    .andField3NotEqualTo(9)
    .andField4IsNotNull();
 
  List<Integer> field5Values = new ArrayList<Integer>();
  field5Values.add(8);
  field5Values.add(11);
  field5Values.add(14);
  field5Values.add(22);
 
  example.or()
    .andField5In(field5Values);
 
  example.or()
    .andField6Between(3, 7);
  • or()方法會產生一個新的Criteria對象,添加到oredCriteria中,並返回這個Criteria對象,從而能夠鏈式表達,爲其添加Criterion。
  • Example類的distinct字段用於指定DISTINCT查詢。
  • orderByClause字段用於指定ORDER BY條件,這個條件沒有構造方法,直接經過傳遞字符串值指定。

產生的SQL語句以下:

where (field1 = 5 and field2 is null)
     or (field3 <> 9 and field4 is not null)
     or (field5 in (8, 11, 14, 22))
     or (field6 between 3 and 7)

 

(3). xxxMapper.xml文件

sql語句映射配置文件。

  • mapper元素須要有一個惟一的namespace屬性,必須爲對應的Mapper接口全名。
  • 每一個sql語句定義都有一個id,必須與對應的Mapper接口中方法同名,能夠指定參數類型和返回類型。
  • 每一個sql語句能夠定義parameterType和resultType指定參數和返回值類型,也可單獨定義parameterMap(見後面的存儲過程部分)和resultMap元素而後在sql語句元素中引用。 
<?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.demo.mappers.PersonMapper">
  <resultMap id="BaseResultMap" type="com.demo.models.Person">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="name" jdbcType="VARCHAR" property="name" />
    ......
  </resultMap>
  <resultMap extends="BaseResultMap" id="ResultMapWithBLOBs" type="com.demo.models.Person">
    <result column="content" jdbcType="LONGVARCHAR" property="content" />
  </resultMap>

  <sql id="Update_By_Example_Where_Clause">
    <where>
      <foreach collection="example.oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <sql id="Base_Column_List">
    id, name
  </sql>
  <sql id="Blob_Column_List">
    content
  </sql>

  <select id="selectByExampleWithBLOBs" parameterType="com.demos.models.PersonExample" resultMap="ResultMapWithBLOBs">
    select
    <if test="distinct">
      distinct
    </if>
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from person
    <if test="_parameter != null">
      <include refid="Example_Where_Clause" />
    </if>
    <if test="orderByClause != null">
      order by $orderByClause$
    </if>
  </select>
  <select id="selectByPrimaryKey" parameterType="java.lang.Integer" resultMap="ResultMapWithBLOBs">
    select 
    <include refid="Base_Column_List" />
    ,
    <include refid="Blob_Column_List" />
    from person
    where id = #{id,jdbcType=INTEGER}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Integer">
    delete from person
    where id = #{id,jdbcType=INTEGER}
  </delete>
  
  <insert id="insert" parameterType="com.demo.models.Person">
    insert into person(id, name, content)
    values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR},#{content,jdbcType=LONGVARCHAR})
  </insert>
  <insert id="insertSelective" parameterType="com.demo.models.Person">
    insert into t_certstore
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="name != null">
        identityName,
      </if>
      <if test="content != null">
        content,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=INTEGER},
      </if>
      <if test="name!= null">
        #{name,jdbcType=VARCHAR},
      </if>
      <if test="content != null">
        #{content,jdbcType=LONGVARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByExampleSelective" parameterType="map">
    update person
    <set>
      <if test="record.id != null">
        id = #{record.id,jdbcType=INTEGER},
      </if>
      <if test="record.name!= null">
        name = #{record.name,jdbcType=VARCHAR},
      </if>
      <if test="record.content != null">
        content = #{record.content,jdbcType=LONGVARCHAR},
      </if>
    </set>
    <if test="_parameter != null">
      <include refid="Update_By_Example_Where_Clause" />
    </if>
  </update>
  <select id="countByExample" parameterType="com.demo.models.Person" resultType="java.lang.Integer">
   select count(*) from person
   <if test="_parameter != null">
    <include refid="Example_Where_Clause" />
   </if>
  </select>
  ......
</mapper>

xxxMapper.java(接口)

定義與Mapper.xml中sql語句對應的方法,方法名就是sql語句的id屬性,參數和返回值也要對應。

public interface PersonMapper {
    int countByExample(PersonExample example);int deleteByPrimaryKey(Integer id);
    int insert(Personrecord);
    int insertSelective(Person record);
    List<CertStore> selectByExampleWithBLOBs(PersonExample example);
    CertStore selectByPrimaryKey(Integer id);
    int updateByExampleSelective(@Param("record") Person record, @Param("example") PersonExample example);
    ......
}

使用了多個參數的時候,能夠用@Param註解給參數設置名字以區分不一樣參數,xml文件中sql語句的參數類型爲map,經過參數名訪問參數對象的屬性。如@Param(record), 可用#{record.id}訪問。還能夠指定類型,如#{record.id,jdbcType=INTEGER}。

若是隻有一個參數則不須要指定參數的名字,#{...}會直接訪問這個參數對象的屬性,若是沒有適合的屬性則直接表明當前參數。

  • #{token}   會被預編譯,能防止SQL注入
  • ${token}    動態執行,不能防止SQL注入

 

Mybatis使用

mybatis配置文件

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/testdb?autoReconnect=true" />
                <property name="username" value="xxxx" />
                <property name="password" value="xxxx" />
            </dataSource>
        </environment>
    </environments>
   <settings>......</settings>
    <!-- 全局別名設置,在映射文件中只需寫別名,而沒必要寫出整個類路徑  --> 
    <typeAliases>......</typeAliases>  
    <!-- 非註解的sql映射文件配置,若是使用mybatis註解,該mapper無需配置,可是若是mybatis註解中包含@resultMap註解,則mapper必須配置,給resultMap註解使用 -->  
    <mappers>
        <mapper resource="mapper/Person.xml" />
        <mapper class="com.demo.mapper.CustomPersonMapper" />
     ......
    </mappers>
</configuration>

能夠自行建立額外的sql映射xml文件或基於註解Mapper接口,可是都須要加入到Mybatis配置中的mappers元素裏。 

settings

<!-- 全局映射器啓用緩存 -->  
<setting name="cacheEnabled" value="true" />  

<!-- 查詢時,關閉關聯對象即時加載以提升性能 -->  
<setting name="lazyLoadingEnabled" value="true" />  

<!-- 設置關聯對象加載的形態,此處爲按需加載字段(加載字段由SQL指              定),不會加載關聯表的全部字段,以提升性能 -->  
<setting name="aggressiveLazyLoading" value="false" />  

<!-- 對於未知的SQL查詢,容許返回不一樣的結果集以達到通用的效果 -->  
<setting name="multipleResultSetsEnabled" value="true" />  

<!-- 容許使用列標籤代替列名 -->  
<setting name="useColumnLabel" value="true" />  

<!-- 容許使用自定義的主鍵值(好比由程序生成的UUID 32位編碼做爲鍵值),數據表的PK生成策略將被覆蓋 -->  
<setting name="useGeneratedKeys" value="true" />  

<!-- 給予被嵌套的resultMap以字段-屬性的映射支持 -->  
<setting name="autoMappingBehavior" value="FULL" />  

<!-- 對於批量更新操做緩存SQL以提升性能  -->  
<setting name="defaultExecutorType" value="BATCH" />  

<!-- 數據庫超過25000秒仍未響應則超時 -->  
<setting name="defaultStatementTimeout" value="25000" /> 

......

typeHandlers用來自定義映射規則,如你能夠自定義將Character映射爲varchar,plugins元素則放了一些攔截器接口,你能夠繼承他們並作一些切面的事情。更多配置如如properties,objectFactory等,能夠參考ibatis-3-config.dtd文檔。

使用Spring時,不須要此配置文件,而是使用針對Spring的專門的配置文件(配置bean)。

初始化

InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory   sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sqlSessionFactory .openSession(true);
/**
         * 映射sql的標識字符串,
         * com.demo.mappers.personMapper是personMapper.xml文件中mapper標籤的namespace屬性的值,
         * getPerson是select標籤的id屬性值,經過select標籤的id屬性值就能夠找到要執行的SQL
 */
String statement = "com.demo.mappers.personMapper.getPerson";//映射sql的標識字符串
//執行查詢返回一個惟一user對象的sql
Person person = session.selectOne(statement, 1);
System.out.println(person);
PersonMapper personMapper = session.getMapper(PersonMapper.class);
personMapper.insert(new Pserson(......));
......
session.commit();
session.close();

SqlSessionManager sessionManager=SqlSessionManager.newInstance(inputStream);

Configuration configuration = sessionManager.getConfiguration();
MapperRegistry mapperRegistry = configuration.getMapperRegistry();

if(!sessionManager.isManagedSessionStarted())
sessionManager.startManagedSession(true);

使用SqlSession類進行數據庫操做

SqlSession接口提供了經常使用的數據庫操做方法。全部的statement參數爲xml文件中namespace加上sql語句id,如com.demo.mappers.PersonMapper.selectByPrimaryKey。

  • <T> T selectOne(String statement);
  • <T> T selectOne(String statement, Object parameter);
  • <E> List<E> selectList(String statement);
  • <E> List<E> selectList(String statement, Object parameter);
  • <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
  • <K, V> Map<K, V> selectMap(String statement, String mapKey);
  • <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
  • <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
  • void select(String statement, Object parameter, ResultHandler handler);
  • void select(String statement, ResultHandler handler);
  • void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
  • int insert(String statement);
  • int insert(String statement, Object parameter);
  • int update(String statement);
  • int update(String statement, Object parameter);
  • int delete(String statement);
  • int delete(String statement, Object parameter);

以上這些方法只須要用到XML映射文件,不須要Mapper接口。

其餘操做

  • void commit();
  • void commit(boolean force);
  • void rollback();
  • void rollback(boolean force);
  • List<BatchResult> flushStatements();
  • void close();
  • void clearCache();
  • Configuration getConfiguration();
  • Connection getConnection();
  • <T> T getMapper(Class<T> type);

經過Mapper實例操做數據庫

能夠同過SqlSession生成Mapper類實例,經過Mapper實例調用Mapper中定義的各類數據庫操做方法。

PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person p=mapper.selectByPrimaryKey(1);
......

 

經過註解的方式定義數據庫操做方法

能夠直接在生成的Mapper類中額外加入自定義的數據庫操做方法。使用註解能夠沒有XML映射文件。

@Select("select * from person where name like #{name}")  
public Person selectPersonByName(String name);

@Select("select * from person where content is not null") 
public List<Person> selectPersonWithContent();

 

註解詳解

註解Mapper示例 

@CacheNamespace(size = 512)  
public interface TestMapper {   
    @SelectProvider(type = TestSqlProvider.class, method = "getSql")  
    @Options(useCache = true, flushCache = false, timeout = 10000)  
    @Results(value = {  
      @Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR),  
      @Result(property = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR) })  
    public TestBean get(@Param("id") String id);  
  
    @SelectProvider(type = TestSqlProvider.class, method = "getAllSql")  
    @Options(useCache = true, flushCache = false, timeout = 10000)  
    @Results(value = {  
       @Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR),  
       @Result(property = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR) })  
    public List<TestBean> getAll();  
   
    @SelectProvider(type = TestSqlProvider.class, method = "getByTestTextSql")  
    @Options(useCache = true, flushCache = false, timeout = 10000)  
    @ResultMap(value = "getByTestText")  
    public List<TestBean> getByTestText(@Param("testText") String testText);  
  
    @InsertProvider(type = TestSqlProvider.class, method = "insertSql")  
    @Options(flushCache = true, timeout = 20000)  
    public void insert(@Param("testBean") TestBean testBean);  
  
    @UpdateProvider(type = TestSqlProvider.class, method = "updateSql")  
    @Options(flushCache = true, timeout = 20000)  
    public void update(@Param("testBean") TestBean testBean);  
  
    @DeleteProvider(type = TestSqlProvider.class, method = "deleteSql")  
    @Options(flushCache = true, timeout = 20000)  
    public void delete(@Param("id") String id);  
}

註解說明

  • @CacheNamespace(size = 512)     定義在該命名空間內容許使用內置緩存,最大值爲512個對象引用,讀寫默認是開啓的,緩存內省刷新時間爲默認3600000毫秒,寫策略是拷貝整個對象鏡像到全新堆(如同CopyOnWriteList)所以線程安全。
  • @SelectProvider(type = TestSqlProvider.class, method = "getSql") : 提供查詢的SQL語句,若是你不用這個註解,你也能夠直接使用@Select("select * from ....")註解,把查詢SQL抽取到一個類裏面,方便管理,同時複雜的SQL也容易操做,type = TestSqlProvider.class就是存放SQL語句的類,而method = "getSql"表示get接口方法須要到TestSqlProvider類的getSql方法中獲取SQL語句。
  • @Options(useCache = true, flushCache = false, timeout = 10000) : 一些查詢的選項開關,好比useCache = true表示本次查詢結果被緩存以提升下次查詢速度,flushCache = false表示下次查詢時不刷新緩存,timeout = 10000表示查詢結果緩存10000秒。更新數據庫的操做,須要從新刷新緩存flushCache = true使緩存同步
  • @Results(value = { @Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR), @Result(property = "testText", column = "test_text", javaType = String.class, jdbcType = JdbcType.VARCHAR) }) : 表示sql查詢返回的結果集,@Results是以@Result爲元素的數組,@Result表示單條屬性-字段的映射關係,如:@Result(id = true, property = "id", column = "test_id", javaType = String.class, jdbcType = JdbcType.VARCHAR)能夠簡寫爲:@Result(id = true, property = "id", column = "test_id"),id = true表示這個test_id字段是個PK,查詢時mybatis會給予必要的優化,應該說數組中全部的@Result組成了單個記錄的映射關係,而@Results則單個記錄的集合。 
  • @Param("paramName") :全侷限定別名,定義查詢參數在sql語句中的位置再也不是順序下標0,1,2,3....的形式,而是對應名稱,該名稱就在這裏定義。 若是參數類型爲模型類,要在sql中引用對象裏面的屬性,使用相似paramName.id,paramName.textText的形式,mybatis會經過反射找到這些屬性值。
  • @ResultMap(value = "getByTestText") :重要的註解,能夠解決複雜的映射關係,包括resultMap嵌套,鑑別器discriminator等等。注意一旦你啓用該註解,你將不得不在你的映射文件中配置你的resultMap,而value = "getByTestText"即爲映射文件中的resultMap ID(注意此處的value = "getByTestText",必須是在映射文件中指定命名空間路徑)。@ResultMap在某些簡單場合能夠用@Results代替,可是複雜查詢,好比聯合、嵌套查詢@ResultMap就會顯得解耦方便更容易管理。 映射文件示例以下,文件中的namespace路徑必須是使用@resultMap的類路徑,此處是TestMapper,文件中 id="getByTestText"必須和@resultMap中的value = "getByTestText"保持一致。@ResultMap("mapper_namespace.resultMap_id")
<?xml version="1.0" encoding="UTF-8" ?>    
<!DOCTYPE mapper    
PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"    
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">  
  
<mapper namespace="com.wotao.taotao.persist.test.mapper.TestMapper">  
    <resultMap id="getByTestText" type="TestBean">  
        <id property="id" column="test_id" javaType="string" jdbcType="VARCHAR" />  
        <result property="testText" column="test_text" javaType="string" jdbcType="VARCHAR" />  
    </resultMap>  
</mapper>   
  • @InsertProvider(type = TestSqlProvider.class, method = "insertSql") :用法和含義@SelectProvider同樣,只不過是用來插入數據庫而用的。
  • @UpdateProvider(type = TestSqlProvider.class, method = "updateSql") :用法和含義@SelectProvider同樣,只不過是用來更新數據庫而用的。 
  • @DeleteProvider(type = TestSqlProvider.class, method = "deleteSql") :用法和含義@SelectProvider同樣,只不過是用來刪除數據而用的。 

 

Java映射文件

使用註解後,能夠再也不用XML映射文件編寫SQL,而是在java類中編寫。示例以下:

public class TestSqlProvider {  
    private static final String TABLE_NAME = "test";  
    public String getSql(Map<String, Object> parameters) {  
        String uid = (String) parameters.get("id");  
        BEGIN();  
        SELECT("test_id, test_text");  
        FROM(TABLE_NAME);  
        if (uid != null) {  
            WHERE("test_id = #{id,javaType=string,jdbcType=VARCHAR}");  
        }  
        return SQL();  
    }  
  
    public String getAllSql() {  
        BEGIN();  
        SELECT("test_id, test_text");  
        FROM(TABLE_NAME);  
        return SQL();  
    }  
  
    public String getByTestTextSql(Map<String, Object> parameters) {  
        String tText = (String) parameters.get("testText");  
        BEGIN();  
        SELECT("test_id, test_text");  
        FROM(TABLE_NAME);  
        if (tText != null) {  
            WHERE("test_text like #{testText,javaType=string,jdbcType=VARCHAR}");  
        }  
        return SQL();  
    }  
  
    public String insertSql() {  
        BEGIN();  
        INSERT_INTO(TABLE_NAME);  
        VALUES("test_id", "#{testBean.id,javaType=string,jdbcType=VARCHAR}");  
        VALUES("test_text", "#{testBean.testText,javaType=string,jdbcType=VARCHAR}");  
        return SQL();  
    }  
  
    public String updateSql() {  
        BEGIN();  
        UPDATE(TABLE_NAME);  
        SET("test_text = #{testBean.testText,javaType=string,jdbcType=VARCHAR}");  
        WHERE("test_id = #{testBean.id,javaType=string,jdbcType=VARCHAR}");  
        return SQL();  
    }  
  
    public String deleteSql() {  
        BEGIN();  
        DELETE_FROM(TABLE_NAME);  
        WHERE("test_id = #{id,javaType=string,jdbcType=VARCHAR}");  
        return SQL();  
    }  
}

SqlBuilder和SelectBuilder

mybatis提供SelectBuilder和SqlBuilder這2個小工具來幫助咱們生成SQL語句。SelectBuilder專門用來生成select語句,而SqlBuilder則是通常性的工具,能夠生成任何SQL語句。可經過import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN的方式引入SqlBuilder提供的靜態方法。

  • BEGIN()方法表示刷新本地線程,某些變量爲了線程安全,會先在本地存放變量,此處須要刷新。
  • SELECT,FROM,WHERE等方法拼湊sql字符串
  • SQL()方法將返回最終append結束的字符串
  • 更復雜的標籤還有JOIN,INNER_JOIN,GROUP_BY,ORDER_BY等

參數

經過Map<String, Object> parameters接收Mapper接口中定義的參數。Mapper接口方法中定義使用了命名的參數如@Param("testId"),@Param("testText"),Map中的key爲參數名,若是參數沒有命名,key爲基於0的順序下標。

 

在Spring中使用

@Repository("testBaseDAO")  
public class TestBaseDAO {
    ......
    @Autowired  
    public void setTestMapper(@Qualifier("testMapper") TestMapper testMapper) {  
        this.testMapper = testMapper;  
    }  
    ......
}

關聯查詢

模型|數據表

Clazz 

int id int c_id
String name varchar c_name
Teacher teacher int teacher_id
List<Student> students  

 

Teacher

int id int t_id
String name varchar t_name

 

Student

int id  int s_id
String name varchar s_name
  int class_id

 

 

一對一關係(A實體類中有一個B實體類的屬性 )

使用association標籤,可用屬性:

  • property     對象屬性名
  • javaType    對象屬性類型
  • column      對應外鍵字段名稱
  • select        使用另外一個查詢封裝的結果

方式一:嵌套結果

<select id="getClazz" parameterType="int" resultMap="ClazzResultMap">
        select * from Clazz c, Teacher t where c.teacher_id=t.t_id and c.c_id=#{id}
    </select>
    <!-- 使用resultMap映射實體類和字段之間的一一對應關係 -->
    <resultMap type="com.demo.models.Clazz" id="ClassResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" javaType="com.demo.models.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
    </resultMap>

方式二:嵌套查詢

<select id="getClazz" parameterType="int" resultMap="ClazzResultMap">
        select * from Clazz where c_id=#{id}
     </select>
     <!-- 使用resultMap映射實體類和字段之間的一一對應關係 -->
     <resultMap type="com.demo.Clazz" id="ClazzResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="refB" column="teacher_id" select="getTeacher"/>
     </resultMap>
     <select id="getTeacher" parameterType="int" resultType="com.demo.Teacher">
        SELECT t_id id, t_name name FROM Teacher WHERE t_id=#{id}
     </select>

 

一對多關聯(A實體類中有一個B實體類的集合)

使用collection標籤

  • ofType    集合中元素對象類型

方式一:嵌套結果

<select id="getClazz" parameterType="int" resultMap="ClazzResultMap">
        select * from Class c, Teacher t, Student s where c.teacher_id=t.t_id and c.c_id=s.c_id and c.c_id=#{id}
    </select>
    <resultMap type="com.demo.Clazz" id="ClazzResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" javaType="com.demo.Teacher">
            <id property="id" column="t_id"/>
            <result property="name" column="t_name"/>
        </association>
        <!-- ofType指定students集合中的對象類型 -->
        <collection property="students" ofType="com.demo.Student">
            <id property="id" column="s_id"/>
            <result property="name" column="s_name"/>
        </collection>
    </resultMap>

方式二:嵌套查詢

<select id="getClazz" parameterType="int" resultMap="ClazzResultMap">
        select * from class where c_id=#{id}
     </select>
     <resultMap type="com.demo.Clazz" id="ClazzResultMap">
        <id property="id" column="c_id"/>
        <result property="name" column="c_name"/>
        <association property="teacher" column="teacher_id" javaType="com.demo.Teacher" select="getTeacher"></association>
        <collection property="students" ofType="com.demo.Student" column="c_id" select="getStudent"></collection>
     </resultMap>
     <select id="getTeacher" parameterType="int" resultType="com.demo.Teacher">
        SELECT t_id id, t_name name FROM teacher WHERE t_id=#{id}
     </select>
     <select id="getStudent" parameterType="int" resultType="com.demo.Student">
        SELECT s_id id, s_name name FROM student WHERE class_id=#{id}
     </select>

 

調用存儲過程

定義存儲過程

-- 建立存儲過程(查詢獲得男性或女性的數量, 若是傳入的是0就女性不然是男性)
DELIMITER $
CREATE PROCEDURE mybatis.ges_user_count(IN sex_id INT, OUT user_count INT)
BEGIN  
IF sex_id=0 THEN
SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='女' INTO user_count;
ELSE
SELECT COUNT(*) FROM mybatis.p_user WHERE p_user.sex='男' INTO user_count;
END IF;
END 
$

-- 調用存儲過程
DELIMITER ;
SET @user_count = 0;
CALL mybatis.ges_user_count(1, @user_count);
SELECT @user_count;

sql映射配置

<!-- 查詢獲得男性或女性的數量, 若是傳入的是0就女性不然是男性 -->
    <select id="getUserCount" parameterMap="getUserCountMap" statementType="CALLABLE">
        CALL mybatis.ges_user_count(?,?)
    </select>
    <parameterMap type="java.util.Map" id="getUserCountMap">
        <parameter property="sexid" mode="IN" jdbcType="INTEGER"/>
        <parameter property="usercount" mode="OUT" jdbcType="INTEGER"/>
    </parameterMap>

查詢

Map<String, Integer> parameterMap = new HashMap<String, Integer>();
parameterMap.put("sexid", 1);
parameterMap.put("usercount", -1);
sqlSession.selectOne("getUserCount", parameterMap);
Integer result = parameterMap.get("usercount");

 

緩存

Mybatis同時提供了一級緩存和二級緩存的支持。

  • 一級緩存:基於PerpetualCache的HashMap本地緩存,存儲做用域爲SqlSession,當SqlSession flush或close後,該Session的全部Cache會被清空。一級緩存默認開啓。
  • 二級緩存:默認也是採用PerpetualCache HashMap存儲,做用域爲Mapper(Namespace),能夠自定義存儲源,如Ehcache。
  • 開啓二級緩存,Mybatis配置中加入<cache/>元素可開啓二級緩存。二級緩存從cache(mapper.xml中定義)中取得,須要調用session.commit(),數據纔會放入chache中,二級緩存纔有效。
  • 緩存的數據更新機制爲:當某做用域(一級緩存Session/二級緩存Namespaces)進行了C/U/D操做後,默認該做用域下全部select中的緩存會被clear。
  • 映射語句文件中全部select語句都會被緩存,映射文件中全部insert,update,delete語句都會刷新緩存。
<cache 
eviction="FIFO"       <!--回收策略爲先進先出,默認使用LRU算法(最近最少使用)-->
flushInterval="60000" <!--自動刷新時間60s-->
size="512"            <!--可緩存512個引用對象,最大爲1024-->
readOnly="true"/>     <!--只讀-->

 

Mybatis3.x與Spring4.x整合

有3種經常使用的整合方式及關鍵配置

http://blog.csdn.net/bluesky5219/article/details/7066174

  • 數據映射器(MapperFactoryBean),可不用寫映射文件,全採用註解方式提供sql語句和輸入參數。
<!--建立數據映射器,數據映射器必須爲接口-->
      <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> 
        <property name="mapperInterface" value="com.xxt.ibatis.dbcp.dao.UserMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" /> 
      </bean>
  • 採用SqlSession的實現類SqlSessionTemplate。Mybatis-Spring中可用SqlSessionFactoryBean代替SqlSessionFactoryBuilder建立sessionFactory。
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
      <property name="dataSource" ref="dataSource" /> 
      <!-- 指定sqlMapConfig總配置文件,訂製的environment在spring容器中不在生效-->
      <property  name="configLocation"  value="classpath:sqlMapConfig.xml"/>
      <!--指定實體類映射文件,能夠指定同時指定某一包以及子包下面的全部配置文件,mapperLocations和configLocation有一個便可,當須要爲實體類指定別名時,可指定configLocation屬性,再在mybatis總配置文件中採用mapper引入實體類映射文件 -->
      <property  name="mapperLocations"  value="classpath*:com/xxt/ibatis/dbcp/**/*.xml"/> 
  </bean>
  • 採用抽象類org.mybatis.spring.support.SqlSessionDaoSupport提供SqlSession
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate"> 
      <constructor-arg index="0" ref="sqlSessionFactory" /> 
</bean>

 

-------------------

mybatis相關依賴

  • mybatis
  • mybatis-spring
  • Spring相關依賴

spring-mybatis.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">
  <!-- 配置數據源 -->
  <bean name="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <property name="url" value="${jdbc_url}" />
        <property name="username" value="${jdbc_username}" />
        <property name="password" value="${jdbc_password}" />
        ......
  </bean>
    
  <!-- 配置Mybatis sqlSessionFactory -->
  <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!-- 實例化sqlSessionFactory時須要使用上述配置好的數據源 -->
        <property name="dataSource" ref="dataSource" />
        <!-- 自動掃描me/gacl/mapping/目錄下的全部SQL映射xml文件, 無需Configuration.xml裏的手工配置-->
        <property name="mapperLocations" value="classpath:com/demo/mappers/*.xml" />
     <!-- <property name="configLocation" value="classpath:configuration.xml" /> -->
  </bean>

  <!-- 配置Mybatis Mapper映射接口掃描器 -->
  <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 掃描com.demo.mappers包以及它的子包下的全部映射接口 -->
        <property name="basePackage" value="com.demo.mappers" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
  </bean>
   
  <!-- 另外一種配置方式:data OR mapping interface,此處忽略-->  
   <!--<bean id="testMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">  
     <property name="sqlSessionFactory" ref="testSqlSessionFactory" />  
      <property name="mapperInterface" value="com.wotao.taotao.persist.test.mapper.TestMapper" />  
   </bean> --> 
<!-- 配置Spring的事務管理器 -->
  <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
  </bean>

  <!-- 註解方式配置事務 -->
  <!-- <tx:annotation-driven transaction-manager="transactionManager" /> -->

  <!-- 攔截器方式配置事務 -->
  <tx:advice id="transactionAdvice" transaction-manager="transactionManager">
    <tx:attributes>
        <tx:method name="delete*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" no-rollback-for="java.lang.RuntimeException" />
        <tx:method name="insert*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.RuntimeException" />
        <tx:method name="update*" propagation="REQUIRED" read-only="false" rollback-for="java.lang.Exception" />
        <tx:method name="find*" propagation="SUPPORTS" />
        <tx:method name="get*" propagation="SUPPORTS" />
        <tx:method name="select*" propagation="SUPPORTS" />
        <!-- <tx:method name="*" propagation="SUPPORTS" /> -->
    </tx:attributes>
  </tx:advice>

  <!--把事務控制在Service層 -->
  <aop:config>
   <!-- execution( public * com.demo.service.*.*(..) ) -->
   <aop:pointcut id="transactionPointcut" expression="execution(* com.demo.service..*Impl.*(..))" />   
   <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />
  </aop:config>
</beans>

建立Service接口

public interface PersonService
{
  List<Person> getAllPerson();  
}

建立Service實現類

@Service("IdOfPersonService")   //自動在DI容器中註冊成Service組件
public class PersonServiceImpl implements PersonService
{
      @Autowired  PersonMapper personMapper;   //dao依賴注入
      @Override public List<User> getAllPerson() 
       {
            return personMapper.selectByExampleWithBLOBs(null);
       }  
}

建立控制器類(不使用Spring Servlet進行分發控制)

@WebServlet("/persons")  //Servlet3.0提供的註解,將一個繼承了HttpServlet類的普通java類標註爲一個Servlet,不須要在web.xml中配置
public class PersonServlet extends HttpServlet 
{
    private PersonService personService;
    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException 
    {
        //獲取全部的用戶信息
        List<Person> persons = userService.getAllPersons();
        request.setAttribute("persons", persons);
        request.getRequestDispatcher("/index.jsp").forward(request, response);
    }

    public void init() throws ServletException {
        //在Servlet初始化時獲取Spring上下文對象(ApplicationContext)
        ApplicationContext ac = WebApplicationContextUtils.getWebApplicationContext(this.getServletContext());
        //從ApplicationContext中獲取userService
        userService = (UserServiceI) ac.getBean("IdOfPersonService");
    }
}

Spring註解的控制器(Web.xml中配置Spring Servlet,其中Spring分發控制)

@Controller
@RequestMapping("/persons")
public class CaseResultAnalyzeController {
    @Autowried private PersonService personService;
    @RequestMapping
    public ModelAndView index()
    {
        ModelAndView mv=new ModelAndView();
        mv.addObject("persons", personService.getAllPersons());
        mv.setViewName("/index.jsp");
        return mv;
    }
}

 

更多配置

Mybatis配置文件和數據庫鏈接配置分離

單首創建db.properties文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/testdb
name=xxxx
password=xxxx

mybatis 配置文件中引入db.properties文件

<?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>
    <properties resource="db.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${name}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
  ......
</configuration>

定義實體類別名

mybatis配置文件的configuration節點下加入typeAliases元素

<typeAliases>
    <!-- 爲單個類設置別名 -->
    <typeAlias type="com.demo.Person" alias="_Person"/>
    <!-- 爲整個包下的類設置別名,默認的別名就是不帶包名的類名 -->
    <package name="com.demo"/>
</typeAliases>

而後在sql映射的XML中就可使用別名代替model類名了

<insert id="addUser" parameterType="_Person">
    insert into person(id,name) values(#{id},#{name})
</insert>

 

模型類和數據表字段名不一致

方式一:

在Mapper的XML文件中使用resultMap元素定義映射關係。sql語句定義中引用映射關係。

<resultMap type="com.demo.Person" id="personResultMap">
    <!-- 主鍵字段映射 -->
    <id property="id" column="person_id"/>
    <!-- 非主鍵字段映射 -->
    <result property="name" column="person_no"/>
</resultMap>
<select id="selectPersonResult" parameterType="int" resultMap="personResultMap">
  select * from person where person_id=#{id}
</select>

方式二:

使用sql語句生成和模型對象屬性名相同的字段別名

<select id="selectOrder" parameterType="int" resultType="com.demo.Person">
    select person_id id, person_name name from person where person_id=#{id}
</select>

 

模糊查詢判斷參數非空

<isNotEmpty prepend="and" property="name">
    NAME like '%'||#name#||'%'
</isNotEmpty>

這種方式沒法走索引(走索引只限於like 'xxx%'的形式,%xxx和%xxx%都不行),也有說有時候會遇到檢索不到數據的(參考

 

 

參考文檔

http://www.cnblogs.com/xdp-gacl/tag/MyBatis%E5%AD%A6%E4%B9%A0%E6%80%BB%E7%BB%93/

http://www.cnblogs.com/ibook360/archive/2012/07/16/2594056.html

http://www.cnblogs.com/fsjohnhuang/category/618850.html   (MyBatis魔法堂)

 

------------------------

 從Ibatis過渡到Mybatis-比較Mybaits較與Ibatis有哪些方面的改進

1.全局文件的配置

         MyBatis 全局配置文件的各主要元素基本和 iBatis 相同,只是在用法和個別名稱上作了調整。

DTD 約束不一樣

MyBatis 的 DTD 文件已經包含在發佈包下的 mybatis-3.0.x.jar 包中。iBatis 配置文件的根元素是 <sqlMapConfig>,MyBatis 使用的是 <configuration>。

   <?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>
   ......
    </configuration>

SqlSessionFactory代替SqlMapClient

      MyBatis 可以根據配置信息和數據庫創建鏈接,並應用給定的鏈接池信息和事務屬性。MyBatis 封裝了這些操做,最終暴露一個 SqlSessionFactory 實例供開發者使用,從名字能夠看出來,這是一個建立 SqlSession 的工廠類,經過 SqlSession 實例,開發者可以直接進行業務邏輯的操做,而不須要重複編寫 JDBC 相關的樣板代碼。根據全局配置文件生成 SqlSession 的代碼以下:

   Reader reader = Resources.getResourceAsReader("Configuration.xml");
   SqlSessionFactory sqlSessionFactory =
   new SqlSessionFactoryBuilder().build(reader);
     SqlSession sqlSession = sqlSessionFactory.openSession();

   Resources 是 MyBatis 提供的一個工具類,它用於簡化資源文件的加載,它能夠訪問各類路徑的文件。Mybatis如今已經沒有SqlMapClient了,使用的則是SqlSession.在原來的基礎上加了像selectMap,selectList,selectOne這樣的方法,使用更方便了。

事務管理器和數據源配置方式 

ibatis配置事務管理器和數據源的方式以下:

   <transactionManager type="JDBC" >
     <dataSource type="SIMPLE">
       <property name="JDBC.Driver" value="${driver}"/>
       <!-- 其餘數據源信息省略 -->
     </dataSource>
    </transactionManager>

 在MyBatis中配置事務管理器和數據源的方式:

<environments default="demo">
   <environment id="demo">
       <transactionManager type="JDBC"/>
       <dataSource type="POOLED">
           <property name="JDBC.Driver" value="${driver}"/>
           <!-- 其餘數據源信息省略 -->
       </dataSource>
   </environment>
</environments>

 指定映射文件方式      

在 iBatis 中指定映射文件的方式以下:

   <sqlMap resource=... />
   <sqlMap resource=... />
    <sqlMap resource=... />

在  MyBatis  中指定映射文件的方式:

    <mappers>
       <mapper resource=... />
       <mapper resource=... />
     </mappers>

 

 MyBatis能夠經過代碼進行配置

   DataSource ds = …… // 獲取一個 DataSource
   TransactionFactory txFactory = new JdbcTransactionFactory();
   Environment env = new Environment("demo", txFactory, ds);
   Configuration cfg = new Configuration(env);
   cfg.addMapper(UserInfoMapper.class);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);

    結合前面的配置文件,很容易理解這段代碼的意思,不過,須要注意的是 Configuration 的 addMapper() 方法,該方法的參數一般是一個接口,能夠在接口裏面定義若干方法,在方法上使用註解來指定映射的 SQL 語句。   

     // 映射 SQL 綁定接口
   public interface UserInfoMapper
   {
   @Select("select * from userinfo where userid = #{userid}")
   public UserInfo getUserInfo(int userid);
   }
   // 接口綁定對應的數據訪問方法
   try
   {
   //UserInfo userinfo = (UserInfo) sqlSession.selectOne
   ("mybatis.demo.UserInfoMapper.selectUser", 2);
   UserInfoMapper userinfoMapper =
   sqlSession.getMapper(UserInfoMapper.class);
   UserInfo userinfo = userinfoMapper.getUserInfo(1);
   System.out.println(userinfo);
   } finally
   {
   sqlSession.close();
    }

 

2.映射文件中配置  SQL  語句:

  <?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="mybatis.demo.UserInfoMapper">
   <select id="selectUser" parameterType="int"
   resultType="mybatis.demo.UserInfo">
   select * from UserInfo where userid =#{userid}
   </select>
    </mapper>

  在 iBatis 中,namespace 不是必需的,且它的存在沒有實際的意義。在 MyBatis 中,namespace 終於派上用場了,它使得映射文件與接口綁定變得很是天然。Ibatis用的parameterClass在mybatis中已經永不了了,mybatis裏應該使用parameterType。另外resultMap裏面也不能繼續使用了改爲了type。

    同時數據類型的聲明和ibatis有了很大的差異,ibatis能夠像下面這樣寫

insert into M_HEALTHSPECIALYTYPE(FCODE,FCHARGE,FTYPECONTENT,FID,FMARK) 
   values (#FCODE:VARCHAR2#,#FCHARGE:VARCHAR2#,#FTYPECONTENT:VARCHAR2#,#FID#,#FMARK:VARCHAR2#)

    而在mybatis的話通常是這樣弄的:

  insert into M_HEALTHSPECIALYTYPE(FCODE,FCHARGE,FTYPECONTENT,FID,FMARK) 
   values (#{FCODE,jdbcType=VARCHAR},#{FCHARGE,jdbcType=VARCHAR},#{FTYPECONTENT,jdbcType=VARCHAR},#{FID},#{FMARK,jdbcType=VARCHAR})

 

針對映射文件,首先是一系列的屬性名稱的改變,這些僅僅是名稱的改變,用法和含義並無發生變化:

· 和全局配置文件同樣,因爲 DTD 約束髮生變化,根元素也由原來的 <sqlMap> 調整爲 <mapper>。

· <select> 等元素的 parameterClass 屬性改成了 parameterType 屬性。

· <select> 等元素的 resultClasss 屬性改成了 resultType 屬性。

· <parameterMap> 等元素的 class 屬性改成了 type 屬性。

· <result> 元素的 columnIndex 屬性被移除了。

· 嵌套參數由 #value# 改成了 #{value}。

· <parameter> 等元素的 jdbcType 屬性取值中,原來的 "ORACLECURSOR" 取值改成了如今的 "CURSOR","NUMBER" 取值改成了 "NUMERIC"。

  

3.使用  SqlSession  執行映射文件中配置的  SQL  語句

   try
   {
   UserInfo userinfo = (UserInfo) sqlSession.selectOne
   ("mybatis.demo.UserInfoMapper.getUser", 2);
   System.out.println(userinfo);
   } finally
   {
   sqlSession.close();
 }

       須要注意的是,SqlSession 的使用必需遵照上面的格式,即在 finally 塊中將其關閉。以保證資源獲得釋放,防止出現內存泄露!以上就是一個簡單而完整的 MyBatis 程序。其中涉及了全局配置文件,映射文件,構建 SqlSession 對象,執行數據訪問操做等四個步驟。

     

4.iBatis/MyBatis 對存儲過程的支持.

iBatis  中調用存儲過程的方式(經過使用 <procedure> 元素進行存儲過程的定義):

  <procedure id="getValues" parameterMap="getValuesPM">
      { ? = call pkgExample.getValues(p_id => ?) }
   </procedure>

在 MyBatis 中,<proccedure> 元素已經被移除,經過 <select>、<insert> 和 <update> 進行定義:

<select id="getValues" parameterMap="getValuesPM" statementType="CALLABLE">  
    { ? = call pkgExample.getValues(p_id => ?)}   
  </select>

如上所示,經過 statementType 屬性將該語句標識爲存儲過程而非普通 SQL 語句。

 

總結:

      經過前面的示例能夠看出,MyBatis 在編碼中的最大的改變就是將一個最經常使用的 API 由SqlMapClient 改成SqlSessionFactory。另外,類型處理器接口也由原來的 TypeHandlerCallback 改成了 TypeHandler。最後 DataSourceFactory 也進行了調整,移動到 org.apache.ibatis.datasource 包下,其中的方法也做了微調。總之,代碼層面公開的部分改動較少,不會給開發者形成較大的移植成本。

相關文章
相關標籤/搜索