zoukankan      html  css  js  c++  java
  • MyBatis使用总结

    iBatis从3.x开始更名为MyBatis。除了Java以外,还有可用于.Net的Mybatis.Net。

     相关依赖包(maven)

    <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)

    iBatis提供了Abator用于生成映射相关文件。Mybatis可以用mybatis generator实现类似功能。

    生成配置文件

    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="targetassistWEB-INFlibmysql-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文件

    # 数据库驱动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包

    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方法。

    (2). 查询条件类 xxxExample.java

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

    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 包下,其中的方法也作了微调。总之,代码层面公开的部分改动较少,不会给开发者造成较大的移植成本。

  • 相关阅读:
    ExtJs多级联动菜单的一种实现
    初学jquery之自学笔记(2)
    微软MVP评Silverlight的功能特性和价值
    利用XMLFormView在Web部件页中或者自定义页面中嵌入Infopath表单
    初学jquery之自学笔记(3)
    我想大声告诉你
    HTC G7 金卡 制作
    黑苹果配置
    我的Android 从 2.3开始! 开发环境搭建
    新台式机配置表
  • 原文地址:https://www.cnblogs.com/pixy/p/5038275.html
Copyright © 2011-2022 走看看