`

mybatis开发

阅读更多

MyBatis是一款能自定义sql和映射的持久层框架,摒除了大量的JDBC代码、手工设置参数和结果集封装,提高了开发效率。

1、SqlSessionFactory

SqlSessionFactory类是获取SqlSession对象的工厂类,实现代码如下:

 

String resource = config文件的路径(由开发人员编写);

Reader reader =Resources.getResourceAsReader(resource);

SqlSessionFactory ssf  = new SqlSessionFactoryBuilder().build(reader);

config文件的内容如下所示,当然只是举个例子,开发人员必须根据自己的开发环境编写对应的数据

 

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

--- 表示默认采用id="development"的environment 配置

<environments default="development">  

<environment id="development">

---事务管理

<transactionManager type="JDBC"/>

---采用数据库连接池操作DB

<dataSource type="POOLED">

<property name="driver" value="${driver}"/>

<property name="url" value="${url}"/>

<property name="username" value="${username}"/>

<property name="password" value="${password}"/>

</dataSource>

</environment>

</environments>

---预定义要加载的映射文件

<mappers>

<mapper resource="org/mybatis/example/mapper1.xml"/>

</mappers>

</configuration>

获取SqlSessionFactory的源码对应SqlSessionFactoryBuilder类中的build()方法:

 

public SqlSessionFactory build(Reader reader, String environment, Properties properties) {

    try {

 //将config配置文件的信息封装到XMLConfigBuilder对象

         XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);

         return build(parser.parse());

    } catch (Exception e) {

         throw ExceptionFactory.wrapException("Error building SqlSession.", e);

    } finally {

        ErrorContext.instance().reset();

        try {

          reader.close();

        } catch (IOException e) {

          // Intentionally ignore. Prefer previous error.

        }

     }

  }

 

 

其中parser.parse()方法的源码如下所示:

 

public Configuration parse() {

    if (parsed) {

       throw new BuilderException("Each MapperConfigParser can only be used once.");

    }

    parsed = true;

    parseConfiguration(parser.evalNode("/configuration")); //这句很重要

    return configuration;

}

 

 

private void parseConfiguration(XNode root) {

    try {

---读取config文件中<properties></properties>标签里的内容

        propertiesElement(root.evalNode("properties")); //issue #117 read properties first

---读取config文件中<typeAliases></typeAliases>标签里的内容

        typeAliasesElement(root.evalNode("typeAliases"));

---读取config文件中<plugins></plugins>标签里的内容

        pluginElement(root.evalNode("plugins"));

---读取config文件中<objectFactory></objectFactory>标签里的内容

        objectFactoryElement(root.evalNode("objectFactory"));

---读取config文件中<objectWrapperFactory></objectWrapperFactory>标签里的内容

        objectWrapperFactoryElement(root.evalNode("objectWrapperFactory"));

----读取config文件中<settings></settings>标签里的内容

        settingsElement(root.evalNode("settings"));

---读取config文件中的<environments></environments>标签里的内容

        environmentsElement(root.evalNode("environments"));

---读取config文件中的<databaseIdProvider ></databaseIdProvider >标签里的内容

        databaseIdProviderElement(root.evalNode("databaseIdProvider"));

---读取config文件中的<typeHandlers ></typeHandlers >标签里的内容,用于自定义数据类型转换

        typeHandlerElement(root.evalNode("typeHandlers"));

---读取config文件中的< mappers></mappers >标签里的内容,获取配置的映射文件

        mapperElement(root.evalNode("mappers"));

    } catch (Exception e) {

      throw new BuilderException("Error parsing SQL Mapper Configuration. Cause: " + e, e);

    }

  }

 

 

2、获取SqlSession对象

 

如果你有一个SqlSessionFactory,你就可以来获取一个SqlSession实例,SqlSession包含了针对数据库执

行语句的每一个方法。你可以直接使用SqlSession执行已经映射的每一个SQL语句。比如:

SqlSession session =ssf.openSession();

try {

Blog blog = session.select("org.mybatis.example.BlogMapper.selectBlog ", 101);

} finally {

session.close();

}

除此之外,还可以通过接口的方式操纵数据库,代码如下:

 

SqlSession session =sqlSessionFactory.openSession();

try {

BlogMapper mapper = session.getMapper(BlogMapper.class);

Blog blog = mapper.selectBlog(101);

} finally {

session.close();

}

接下来就是编写BlogMapper对应的mapper文件,如下:

 

<?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="org.mybatis.example.BlogMapper">

<select id="selectBlog" parameterType="int" resultType="Blog">

select * from Blog where id = #{id}

</select>

</mapper>

在上面的代码中在方法调用完后,必须关闭openSession对象,避免数据库资源一直被占用。

 

 

3、高级结果查询

(1)、一对一查询简单查询(association)

<!-- Very Complex Result Map -->

<resultMap id="detailedBlogResultMap" type="Blog">

<constructor>

<idArg column="blog_id" javaType="int"/>

</constructor>

<result property="title" column="blog_title"/>

---blog表和author表关联查询,将author表中的查询结果封装到Author对象,同时将Author对象赋值给blog对 ---象的author属性,也可在association标签中设置select=”selectAuthor”属性,表示结果集从selectAuthor ---方法读取

<association property="author" column="blog_author_id" javaType="Author">

<id property="id" column="author_id"/>

<result property="username" column="author_username"/>

<result property="password" column="author_password"/>

<result property="email" column="author_email"/>

</association>

</resultMap>

 

constructor–用来将结果反射给一个实例化好的类的构造器

idArg –ID参数;将结果集标记为ID,以方便全局调用

arg –反射到构造器的通常结果

id –ID结果,将结果集标记为ID,以方便全局调用

result –反射到JavaBean属性的普通结果

association –复杂类型的结合;多个结果合成的类型

(2)、识别器查询(discriminator)

将上述的配置

 

<resultMap id="vehicleResult" type="Vehicle">

<id property=”id”column="id" />

<result property="vin" column="vin"/>

<result property="year" column="year"/>

<result property="color" column="color"/>

 

 

 

<discriminator javaType="int" column="vehicle_type">

<case value="1" resultMap="carResult"/>

<case value="2" resultMap="truckResult"/>

<case value="3" resultMap="vanResult"/>

<case value="4" resultMap="suvResult"/>

</discriminator>

</resultMap>

 

MyBatis将会从数据集中获取每条记录,并比较vehicletype的值。如果它匹配了识别器的条件,就会使用相对应的resultMap。

(3)、一对多查询(collection )

<resultMap id="blogResult" type="Blog">

<id property=”id”column="blog_id" />

<result property="title" column="blog_title"/>

<collection property="posts" ofType="Post">

<id property="id" column="post_id"/>

<result property="subject" column="post_subject"/>

<result property="body" column="post_body"/>

</collection>

</resultMap>

collection标签表示:一组名为posts的ArrayList集合,它的类型是Post。javaType 属于完全可以省略,MyBatis会为你自动识别。

 

4、foreach动态SQL语句(参数为list、array等集合类型)

<select id="selectPostIn" resultType="domain.blog.Post">

SELECT * FROM POST P WHERE ID in

<foreach item="item" index="index" collection="list" open="(" separator="," close=")">

#{item}

</foreach>

</select>

foreach元素非常强大,允许你指定一个集合,申明一个项和一个索引变量,用在这个元素的方法体内。也允许你指定开始和结束的字符,也可以在两个迭代器之间加入一个分隔符。它的智能之处在于它不会偶尔追加额外的分隔符。

注意:你可以传入一个List实例或者一个数组给MyBatis作为一个参数对象。如果你这么做,MyBatis会自动将它包装成一个Map,使用它的名称做为key。List实例将使用“list”做为键,数组实例以“array”作为键。

 

5、@InsertProvider使用

这是可选的SQL注解,允许你在运行的过程中,指定类名和方法名返回SQL来执行。。属性:type,method。type属性指定类的全名,method方法属性指定方法名称。

 

6、@InsertProvider结合SqlBuilder

mapper接口类的代码如下:

@InsertProvider(method = "insert", type = MySqlBuilder.class)

public Integer insert(UserType entity);

MySqlBuilder类的代码如下:

import static org.apache.ibatis.jdbc.SelectBuilder.BEGIN; 

import static org.apache.ibatis.jdbc.SqlBuilder.*;

 

public class  MySqlBuilder {  

public String insert() {

BEGIN();

    INSERT_INTO(TABLE_NAME);

    VALUES("value",  "#{value}");

    return SQL(); 

}

}

 

 

 

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics