Mybatis之Session

来源:互联网 发布:历劫俏佳人图解知乎 编辑:程序博客网 时间:2024/06/15 06:16

你可以用下列语句简单地针对 Mapper 接口进行调用,代码如下:

示例:

SmsSlaveDateMapper smsSlaveDateMapper = session.getMapper(SmsSlaveDateMapper.class);

Long id = smsSlaveDateMapper.selectLastMsgId();

第二种方式有许多优点。一、它不依赖字符串,可以减少出错。二、如果你的IDE有代码自动完成功能, 你可以很快导航到你的SQL语句(因为已经转化为方法名)。三、你不再需要设定返回值类型,因为接口限定了返回值和参数。

还有一个关于Mapper 类的技巧。它们的映射语句完全不需要使用XML 来配置,可以使用JAVA注解方式来取代。

示例:

@Select ("select messagelog_id FROM sms_messagelog  order by messagelog_id desc LIMIT 1")

public Long selectLastMsgId();

注解是非常简单明了的,但是JAVA 注解既有局限性,在语句比较复杂的情况下又比较容易混乱。所以,如果你的语句比较复杂,最好还是使用XML 来映射语句。这主要取决于你和你的项目团队,决定哪个更适合于你,主要还是以稳健为主。也就是说,你不需要制约于哪一种方式,你可以很容易的把注解转为XML,也可以把XML 转化为注解。

作用域和生命周期

1.SqlSessionFactory

一旦创建,SqlSessionFactory就会在整个应用过程中始终存在。所以没有理由去销毁和再创建它,一个 应用运行中也不建议多次创建SqlSessionFactory。如果真的那样做,会显得很拙劣。因此SqlSessionFactory最好的作用域是Application。可以有多种方法实现。最简单的方法是单例模式或者是静态单例模式。然而这既不是广泛赞成和好用的。反而,使用Google Guice Spring 来进行依赖反射会更好。这些框架允许你生成管理器来管SqlSessionFactory的单例生命周期。

2.SqlSession 

每个线程都有自己的SqlSession 实例,SqlSession 实例是不能被共享,也不是线程安全的。因此最好使用Request作用域或者方法体作用域。不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变更来引用。永远不要在一个被管理域中引用 SqlSession,比如说在Servlet 中的HttpSession 中。如果你正在使用WEB 框架,应该让SqlSession 跟随HTTP请求的相似作用域。也就是说,在收到一个HTTP请求过后,打开SqlSession,等返回一个回应以后,立马关掉这个SqlSession。关闭SqlSession 是非常重要的。你必须要确保SqlSession finally 方法体中正常关闭。可以使用下面的标准方式来关闭: 

   SqlSession session = sqlSessionFactory.openSession(); 

   try { 

     // do work 

   } finally { 

     session.close(); 

   }

使用这种模式来贯穿你的所有代码,以确保所有数据库资源都被完全关闭。这是假定不是使用你自己的数据库连接,而是使用MyBatis 来管理你的数据库连接资源

3.Mapper实例 

Mapper 是一种你创建的用于绑定映射语句的接口。Mapper 接口的实例是用SqlSession 来获得的。同样,从技术上来说,最广泛的Mapper 实例作用域像SqlSession 一样,使用请求作用域。确切地说,在方法被调用的时候调用Mapper 实例,然后使用后,就自动销毁掉。不需要使用明确的注销。当一个请求执行正确无误的时候,像SqlSession 一样,你可以轻而易举地操控这一切。保持简单性,保持 Mapper 在 

方法体作用域内。下面演示了如果来操作: 

   SqlSession session = sqlSessionFactory.openSession(); 

   try { 

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

     // do work 

   } finally { 

     session.close(); 

   }

类型别名(typeAliases) 

类型别名是Java 类型的简称。 它仅仅只是关联到XML 配置,简写冗长的JAVA类名。

例如: 

    <typeAliases> 

       <typeAlias alias="Author" type="domain.blog.Author"/> 

       <typeAlias alias="Blog" type="domain.blog.Blog"/> 

       <typeAlias alias="Comment" type="domain.blog.Comment"/> 

       <typeAlias alias="Post" type="domain.blog.Post"/> 

       <typeAlias alias="Section" type="domain.blog.Section"/> 

       <typeAlias alias="Tag" type="domain.blog.Tag"/> 

    </typeAliases> 

使用这个配置,“Blog”就能在任何地方代替“domain.blog.Blog”被使用。 

还有一些与通用JAVA类型建立的别名。它们是大小写敏感的,注意JAVA的基本类型,使用了_来命名。

八、映射器(Mappers) 

现在MyBatis 的动作已经通过以上的步骤配置好了。我们现在开始定义我们的映射SQL语句。首先,我们需要告诉MyBatis 去哪儿寻找。JAVA在自动发现上没有什么好的方法,所以最好的方式就是直接告诉MyBatis 去哪发现映射文件。你可以使用类路径中的资源引用,或者使用字符,输入确切的URL引用

例如: 

   // Using classpath relative resources 

   <mappers> 

       <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> 

       <mapper resource="org/mybatis/builder/BlogMapper.xml"/> 

       <mapper resource="org/mybatis/builder/PostMapper.xml"/> 

   </mappers> 

   // Using url fully qualified paths 

   <mappers> 

       <mapper url="file:///var/sqlmaps/AuthorMapper.xml"/> 

       <mapper url="file:///var/sqlmaps/BlogMapper.xml"/> 

       <mapper url="file:///var/sqlmaps/PostMapper.xml"/> 

   </mappers> 

这些句子仅仅只是告诉MyBatis往哪去寻找,具体的关于每个SQL映射文件的细节,在下一章中详细讨论。

第四章 SQL映射语句文件 

MyBatis 真正强大的地主就是在映射语句,这也是魔力所在。就所有功能来说,SQL映射XML文件相 对来说比较简单。当然,如果你比较了文件与JDBC 代码,你就会发现,映射XML 文件节省了95%的代码。MyBatis SQL而建,但却又给你极大的空间。

SQL映射XML 文件仅仅只有一些初级的元素: 

cache – 配置给定模式的缓存 

cache-ref – 从别的模式中引用一个缓存 

resultMap – 这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象 

sql – 一个可以被其他语句复用的SQL块 

insert – 映射INSERT语句 

update – 映射UPDATE语句 

delete – 映射DELEETE语句 

select – 映射SELECT 语句

select

select 语句可能是MyBatis 中使用最多的元素了。通常都会把数据存储在数据库中,然后读取。所以大部分的应用中查询远远多于修改。对于每个过insertupdate或者delete,都会伴有众多select。这是MyBatis基础原则之一,也是为什么要把更多的焦点和努力都放在查询和结果映射上。

Insert

Sql

参数(parameters

ResultMap

你当TypeAliases 当成你朋友一样牢记。使用它,就可以避免敲长长的类的全路径名。比如说:

在这些情况下MyBatis自动在后台生成一个ResultMap 映射列名到JavaBean 的属性,如果列的名称与属性名确实不符,可以使用标准SQL的特性,生成别名,使用列名与属性匹配。例如:

做为一个例子的情况,我们来看一下最后一个例子,看起来像resultMap 扩展功能,是另外一种解决列表不配对的情况。

高级结果映射 

MyBatis 谨记一个信条:数据库并不是你想怎么就怎么的。我们也许总是希望总是只有一条简单的数据库映射就能完美的解决应用中的问题,但是它们不是。结果映射就是MyBatis为解决这些问题提供的答案。

联合(association

联合的嵌套结果集

聚集(collection

缓存(cache) 

MyBatis 包含一个强在的、可配置、可定制的缓存机制。MyBatis 3的缓存实现有了许多改进,既强劲也更容易配置。

动态语句 

MyBatis 最强大的特性之一是它的动态语句功能。如果你以前使用JDBC 或者类似的框架,你就会明白把SQL语句条件连接在一起是多么的痛苦,一点都不能疏忽空格和逗号等。动态语句完全能解决这些烦恼。 尽管使用动态SQL不是开晚会,但是MyBatis 确实能通过映射的SQL语句使用强大的动态SQL来解决许多的问题。

If

choose, when, otherwise

trim, where, set

Foreach

Mybatis session

package org.apache.ibatis.session;

import java.sql.Connection;

import java.util.List;

import java.util.Map;

public interface SqlSession {

Object selectOne(String statement);

示例:

Long count=(Long)sqlsession.selectOne("selectLastMsgId");

Object selectOne(String statement, Object parameter);

示例:

Map<String,Object> accountMap=(Map<String, Object>)session.selectOne("checkAccount_extend", account_id);

List selectList(String statement);

示例:

List<OrderRecord> orderList=session.selectList("queryOrderByAccountId");

List selectList(String statement, Object parameter);

示例:

List<OrderRecord> orderList=session.selectList("queryOrderByAccountId", account_id);

List selectList(String statement, Object parameter, RowBounds rowBounds);

示例:

int offset=1;

int limit=25;

RowBounds rowBounds=new RowBounds(offset, limit);

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend",map,"zzzzzzzzzz",rowBounds);

Map selectMap(String statement, String mapKey);

示例:

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend","zzzzzzzzzz");

Map<String,Object> result = (Map<String, Object>) accountMap2.get(null);

Map selectMap(String statement, Object parameter, String mapKey);

示例:

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend",map,"zzzzzzzzzz");

Map<String,Object> result = (Map<String, Object>) accountMap2.get(null);

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

示例:

sqlsession.insert("insert");

int insert(String statement, Object parameter);

示例:

sqlsession.insert("insert", listMessage);

int update(String statement);

示例:

session.update("updateOrder");

int update(String statement, Object parameter);

示例:

session.update("updateOrder", map);

int delete(String statement);

示例:

session.delete("delete");

int delete(String statement, Object parameter);

示例:

session.delete("delete", map);

事务控制方法:

void commit();

void commit(boolean force);

void rollback();

void rollback(boolean force);

void close();

void clearCache();

Configuration getConfiguration();

<T> T getMapper(Class<T> type);

示例:

SmsSlaveDateMapper smsSlaveDateMapper = session.getMapper(SmsSlaveDateMapper.class);

Long id = smsSlaveDateMapper.selectLastMsgId();

Connection getConnection();

}

SqlSession

语句执行方法 

这些方法用来执行定义在SQL映射XML文件里的SELECT,INSERT,UPDATE 和 DELETE 语句。它们本身非常好理解,执行以ID为标识的语句,使用参数对象。也可以是JAVA的基本类型(自动装箱,包装类)、JavaBeanPOJO 或是Map

最后,还有三个select方法的高级版本,永远你严格限定返回记录的范围,或者使用自定义的结果处理逻辑,通常是用来处理大数据集。

事务控制方法

清除会话层缓存

最重要的事情是要确保你打开的所有会话都已经关闭。确保的最好方式就是使用下面的工作模式。

使用映射

映射注解

SelectBuilder

SelectBuilder的秘密

如果想像上例中那样使用SelectBuilder,你需要静态导入: 

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

SqlBuilder


你可以用下列语句简单地针对 Mapper 接口进行调用,代码如下:

示例:

SmsSlaveDateMapper smsSlaveDateMapper = session.getMapper(SmsSlaveDateMapper.class);

Long id = smsSlaveDateMapper.selectLastMsgId();

第二种方式有许多优点。一、它不依赖字符串,可以减少出错。二、如果你的IDE有代码自动完成功能, 你可以很快导航到你的SQL语句(因为已经转化为方法名)。三、你不再需要设定返回值类型,因为接口限定了返回值和参数。

还有一个关于Mapper 类的技巧。它们的映射语句完全不需要使用XML 来配置,可以使用JAVA注解方式来取代。

示例:

@Select ("select messagelog_id FROM sms_messagelog  order by messagelog_id desc LIMIT 1")

public Long selectLastMsgId();

注解是非常简单明了的,但是JAVA 注解既有局限性,在语句比较复杂的情况下又比较容易混乱。所以,如果你的语句比较复杂,最好还是使用XML 来映射语句。这主要取决于你和你的项目团队,决定哪个更适合于你,主要还是以稳健为主。也就是说,你不需要制约于哪一种方式,你可以很容易的把注解转为XML,也可以把XML 转化为注解。

作用域和生命周期

1.SqlSessionFactory

一旦创建,SqlSessionFactory就会在整个应用过程中始终存在。所以没有理由去销毁和再创建它,一个 应用运行中也不建议多次创建SqlSessionFactory。如果真的那样做,会显得很拙劣。因此SqlSessionFactory最好的作用域是Application。可以有多种方法实现。最简单的方法是单例模式或者是静态单例模式。然而这既不是广泛赞成和好用的。反而,使用Google Guice Spring 来进行依赖反射会更好。这些框架允许你生成管理器来管SqlSessionFactory的单例生命周期。

2.SqlSession 

每个线程都有自己的SqlSession 实例,SqlSession 实例是不能被共享,也不是线程安全的。因此最好使用Request作用域或者方法体作用域。不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变更来引用。永远不要在一个被管理域中引用 SqlSession,比如说在Servlet 中的HttpSession 中。如果你正在使用WEB 框架,应该让SqlSession 跟随HTTP请求的相似作用域。也就是说,在收到一个HTTP请求过后,打开SqlSession,等返回一个回应以后,立马关掉这个SqlSession。关闭SqlSession 是非常重要的。你必须要确保SqlSession finally 方法体中正常关闭。可以使用下面的标准方式来关闭: 

   SqlSession session = sqlSessionFactory.openSession(); 

   try { 

     // do work 

   } finally { 

     session.close(); 

   }

使用这种模式来贯穿你的所有代码,以确保所有数据库资源都被完全关闭。这是假定不是使用你自己的数据库连接,而是使用MyBatis 来管理你的数据库连接资源

3.Mapper实例 

Mapper 是一种你创建的用于绑定映射语句的接口。Mapper 接口的实例是用SqlSession 来获得的。同样,从技术上来说,最广泛的Mapper 实例作用域像SqlSession 一样,使用请求作用域。确切地说,在方法被调用的时候调用Mapper 实例,然后使用后,就自动销毁掉。不需要使用明确的注销。当一个请求执行正确无误的时候,像SqlSession 一样,你可以轻而易举地操控这一切。保持简单性,保持 Mapper 在 

方法体作用域内。下面演示了如果来操作: 

   SqlSession session = sqlSessionFactory.openSession(); 

   try { 

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

     // do work 

   } finally { 

     session.close(); 

   }

类型别名(typeAliases) 

类型别名是Java 类型的简称。 它仅仅只是关联到XML 配置,简写冗长的JAVA类名。

例如: 

    <typeAliases> 

       <typeAlias alias="Author" type="domain.blog.Author"/> 

       <typeAlias alias="Blog" type="domain.blog.Blog"/> 

       <typeAlias alias="Comment" type="domain.blog.Comment"/> 

       <typeAlias alias="Post" type="domain.blog.Post"/> 

       <typeAlias alias="Section" type="domain.blog.Section"/> 

       <typeAlias alias="Tag" type="domain.blog.Tag"/> 

    </typeAliases> 

使用这个配置,“Blog”就能在任何地方代替“domain.blog.Blog”被使用。 

还有一些与通用JAVA类型建立的别名。它们是大小写敏感的,注意JAVA的基本类型,使用了_来命名。

八、映射器(Mappers) 

现在MyBatis 的动作已经通过以上的步骤配置好了。我们现在开始定义我们的映射SQL语句。首先,我们需要告诉MyBatis 去哪儿寻找。JAVA在自动发现上没有什么好的方法,所以最好的方式就是直接告诉MyBatis 去哪发现映射文件。你可以使用类路径中的资源引用,或者使用字符,输入确切的URL引用

例如: 

   // Using classpath relative resources 

   <mappers> 

       <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> 

       <mapper resource="org/mybatis/builder/BlogMapper.xml"/> 

       <mapper resource="org/mybatis/builder/PostMapper.xml"/> 

   </mappers> 

   // Using url fully qualified paths 

   <mappers> 

       <mapper url="file:///var/sqlmaps/AuthorMapper.xml"/> 

       <mapper url="file:///var/sqlmaps/BlogMapper.xml"/> 

       <mapper url="file:///var/sqlmaps/PostMapper.xml"/> 

   </mappers> 

这些句子仅仅只是告诉MyBatis往哪去寻找,具体的关于每个SQL映射文件的细节,在下一章中详细讨论。

第四章 SQL映射语句文件 

MyBatis 真正强大的地主就是在映射语句,这也是魔力所在。就所有功能来说,SQL映射XML文件相 对来说比较简单。当然,如果你比较了文件与JDBC 代码,你就会发现,映射XML 文件节省了95%的代码。MyBatis SQL而建,但却又给你极大的空间。

SQL映射XML 文件仅仅只有一些初级的元素: 

cache – 配置给定模式的缓存 

cache-ref – 从别的模式中引用一个缓存 

resultMap – 这是最复杂而却强大的一个元素了,它描述如何从结果集中加载对象 

sql – 一个可以被其他语句复用的SQL块 

insert – 映射INSERT语句 

update – 映射UPDATE语句 

delete – 映射DELEETE语句 

select – 映射SELECT 语句

select

select 语句可能是MyBatis 中使用最多的元素了。通常都会把数据存储在数据库中,然后读取。所以大部分的应用中查询远远多于修改。对于每个过insertupdate或者delete,都会伴有众多select。这是MyBatis基础原则之一,也是为什么要把更多的焦点和努力都放在查询和结果映射上。

Insert

Sql

参数(parameters

ResultMap

你当TypeAliases 当成你朋友一样牢记。使用它,就可以避免敲长长的类的全路径名。比如说:

在这些情况下MyBatis自动在后台生成一个ResultMap 映射列名到JavaBean 的属性,如果列的名称与属性名确实不符,可以使用标准SQL的特性,生成别名,使用列名与属性匹配。例如:

做为一个例子的情况,我们来看一下最后一个例子,看起来像resultMap 扩展功能,是另外一种解决列表不配对的情况。

高级结果映射 

MyBatis 谨记一个信条:数据库并不是你想怎么就怎么的。我们也许总是希望总是只有一条简单的数据库映射就能完美的解决应用中的问题,但是它们不是。结果映射就是MyBatis为解决这些问题提供的答案。

联合(association

联合的嵌套结果集

聚集(collection

缓存(cache) 

MyBatis 包含一个强在的、可配置、可定制的缓存机制。MyBatis 3的缓存实现有了许多改进,既强劲也更容易配置。

动态语句 

MyBatis 最强大的特性之一是它的动态语句功能。如果你以前使用JDBC 或者类似的框架,你就会明白把SQL语句条件连接在一起是多么的痛苦,一点都不能疏忽空格和逗号等。动态语句完全能解决这些烦恼。 尽管使用动态SQL不是开晚会,但是MyBatis 确实能通过映射的SQL语句使用强大的动态SQL来解决许多的问题。

If

choose, when, otherwise

trim, where, set

Foreach

Mybatis session

package org.apache.ibatis.session;

import java.sql.Connection;

import java.util.List;

import java.util.Map;

public interface SqlSession {

Object selectOne(String statement);

示例:

Long count=(Long)sqlsession.selectOne("selectLastMsgId");

Object selectOne(String statement, Object parameter);

示例:

Map<String,Object> accountMap=(Map<String, Object>)session.selectOne("checkAccount_extend", account_id);

List selectList(String statement);

示例:

List<OrderRecord> orderList=session.selectList("queryOrderByAccountId");

List selectList(String statement, Object parameter);

示例:

List<OrderRecord> orderList=session.selectList("queryOrderByAccountId", account_id);

List selectList(String statement, Object parameter, RowBounds rowBounds);

示例:

int offset=1;

int limit=25;

RowBounds rowBounds=new RowBounds(offset, limit);

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend",map,"zzzzzzzzzz",rowBounds);

Map selectMap(String statement, String mapKey);

示例:

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend","zzzzzzzzzz");

Map<String,Object> result = (Map<String, Object>) accountMap2.get(null);

Map selectMap(String statement, Object parameter, String mapKey);

示例:

Map<String,Object> accountMap2 = (Map<String, Object>)session.selectMap("checkAccount_extend",map,"zzzzzzzzzz");

Map<String,Object> result = (Map<String, Object>) accountMap2.get(null);

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

示例:

sqlsession.insert("insert");

int insert(String statement, Object parameter);

示例:

sqlsession.insert("insert", listMessage);

int update(String statement);

示例:

session.update("updateOrder");

int update(String statement, Object parameter);

示例:

session.update("updateOrder", map);

int delete(String statement);

示例:

session.delete("delete");

int delete(String statement, Object parameter);

示例:

session.delete("delete", map);

事务控制方法:

void commit();

void commit(boolean force);

void rollback();

void rollback(boolean force);

void close();

void clearCache();

Configuration getConfiguration();

<T> T getMapper(Class<T> type);

示例:

SmsSlaveDateMapper smsSlaveDateMapper = session.getMapper(SmsSlaveDateMapper.class);

Long id = smsSlaveDateMapper.selectLastMsgId();

Connection getConnection();

}

SqlSession

语句执行方法 

这些方法用来执行定义在SQL映射XML文件里的SELECT,INSERT,UPDATE 和 DELETE 语句。它们本身非常好理解,执行以ID为标识的语句,使用参数对象。也可以是JAVA的基本类型(自动装箱,包装类)、JavaBeanPOJO 或是Map

最后,还有三个select方法的高级版本,永远你严格限定返回记录的范围,或者使用自定义的结果处理逻辑,通常是用来处理大数据集。

事务控制方法

清除会话层缓存

最重要的事情是要确保你打开的所有会话都已经关闭。确保的最好方式就是使用下面的工作模式。

使用映射

映射注解

SelectBuilder

SelectBuilder的秘密

如果想像上例中那样使用SelectBuilder,你需要静态导入: 

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

SqlBuilder

原创粉丝点击