Mybatis 的小笔记 1. Mybatis创建 引用 关闭 和生命周期

来源:互联网 发布:wifi破解源代码 c语言 编辑:程序博客网 时间:2024/05/10 01:58

写在前面的小尾巴
这些天再看Mybatis 的API 有很多术语不是很懂 度娘的时候 有的blog直接copyAPI上面的话 就完了 坑爹呢 直接copy写个鸟蛋的blog (╯‵□′)╯︵┻━┻ 当然也有不是划水 总是有那么真才实学的 在这整理一下 借花献佛 也许会是一个坑 坑就坑吧 反正这么水 木有小伙伴会理我的 嘤嘤嘤嘤 T.T 不说废话 顺序是照着Mybatis的API往下写 多半是我自己的理解注释 其他不是很懂暂且坑着吧 这东西反正是要反复看的 且待来日


1.从 XML 中构建 SqlSessionFactory


API:

构建:
每 一 个 MyBatis 的 应 用 程 序 都 以 一 个 SqlSessionFactory 对 象 的 实 例 为 核 心 。 SqlSessionFactory 对 象 的 实 例 可 以 通 过 SqlSessionFactoryBuilder 对 象 来 获 得 。 SqlSessionFactoryBuilder 对象可以从 XML 配置文件,或从 Configuration 类的习惯准备的实 例中构建 SqlSessionFactory 对象。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单。这里建议你使用类路径下的资 源文件来配置,但是你可以使用任意的 Reader 实例,这个实例包括由文字形式的文件路径 或 URL 形式的文件路径 file://来创建。MyBatis 包含了一些工具类,称作为资源,这些工具 类包含一些方法,这些方法使得从类路径或其他位置加载资源文件更加简单。

生命周期:

SqlSessionFactoryBuilder

这个类可以被实例化,使用和丢弃。一旦你创建了 SqlSessionFactory 后,这个类就不需 要存在了。 因此 SqlSessionFactoryBuilder 实例的最佳范围是方法范围 (也就是本地方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例, 但是最好的方式是 不需要保持它一直存在来保证所有 XML 解析资源,因为还有更重要的事情要做。

SqlSessionFactory

一旦被创建,SqlSessionFactory 应该在你的应用执行期间都存在。没有理由来处理或重 新创建它。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次。 这样的 操作将被视为是非常糟糕的。 因此 SqlSessionFactory 的最佳范围是应用范围。 有很多方法可 以做到, 最简单的就是使用单例模式或者静态单例模式。


其实关键的是下面

String resource = "org/mybatis/example/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

API的意思就是这里面牵扯到了程序的生命周期和线程的安全与不安全的问题 理解了这个 其实API是很好理解的 SqlSessionFactoryBuilder构建了sqlSessionFactory 之后就不再需要 因为它的作用就是从config中读取数据来构建session语句 之后通过sqlSessionFactory 来选择开启或者关闭而无需重复构建SqlSessionFactoryBuilder 那么这样或许不明白 那么用静态域的方法来结合API说明或许更清楚一些

static {        try {            Reader reader=  Resources.getResourceAsReader("configuraction.xml");            sqlSessionFactory=new SqlSessionFactoryBuilder().build(reader);        } catch (IOException e) {            e.printStackTrace();        }    }

是用静态域的方法来设计 就保证了 每次运行的只会在第一次构建静态域 而不是重复的构建 sqlSessionFactory 则在静态域中作为局部变量使用 在内存中使用之后即被丢弃 也保证在程序执行期间保持存在且不会被重复创建

2.xml文件配置

XML 配置文件包含对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源和 决定事务范围和控制的事务管理器。关于 XML 配置文件的详细内容可以在文档后面找到, 这里给出一个简单的示例:

<?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="${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/BlogMapper.xml"/>  </mappers></configuration>

当然, XML 配置文件中还有很多可以配置的, 在 上面的示例指出的则是最关键的部分。 要注意 XML 头部的声明,需要用来验证 XML 文档正确性。environment 元素体中包含对事 务管理和连接池的环境配置。 mappers 元素是包含所有 mapper 映射器) ( 的列表, 这些 mapper 的 XML 文件包含 SQL 代码和映射定义信息。

没有什么好说 这块就这么写的 记住就行了

3.从 SqlSessionFactory 中获取 SqlSession

取得SqlSeesion有两种方法 同样的 在架构设计也有两种方法 一种使用SqlSession 自身方法实现接口 一种直接关联接口而不是接口方法


API:

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不能被共享,也是线程 不安全的。因此最佳的范围是请求或方法范围。绝对不能将 SqlSession 实例的引用放在一个 类的静态字段甚至是实例字段中。 也绝不能将 SqlSession 实例的引用放在任何类型的管理范 围中, 比如 Serlvet 架构中的 HttpSession。 如果你现在正用任意的 Web 框架, 要考虑 SqlSession 放在一个和 HTTP 请求对象相似的范围内。换句话说,基于收到的 HTTP 请求,你可以打开 了一个 SqlSession,然后返回响应,就可以关闭它了。关闭 Session 很重要,你应该确保使 用 finally 块来关闭它。下面的示例就是一个确保 SqlSession 关闭的基本模式:

SqlSession session = sqlSessionFactory.openSession();try {  // do work} finally {  session.close();}

在你的代码中一贯地使用这种模式, 将会保证所有数据库资源都正确地关闭 (假设你没 有通过你自己的连接关闭,这会给 MyBatis 造成一种迹象表明你要自己管理连接资源) 。


<1>.使用SqlSession 自身方法实现接口

关联此种方法的表实体类的xml文件 src对应的是实现接口的类名

SqlSession session = sqlSessionFactory.openSession();try {  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);} finally {  session.close();}

<2>.直接关联接口而不是接口方法

关联此种方法的表实体类的xml文件 src对应的是自定义了接口的类名


API:

Mapper 实例

映射器是你创建绑定映射语句的接口。映射器接口的实例可以从 SqlSession 中获得。那 么从技术上来说,当被请求时,任意映射器实例的最宽范围和 SqlSession 是相同的。然而, 映射器实例的最佳范围是方法范围。也就是说,它们应该在使用它们的方法中被请求,然后 就抛弃掉。它们不需要明确地关闭,那么在请求对象中保留它们也就不是什么问题了,这和 SqlSession 相似。你也许会发现,在这个水平上管理太多的资源的话会失控。保持简单,将 映射器放在方法范围内


SqlSession session = sqlSessionFactory.openSession();try {  BlogMapper mapper = session.getMapper(BlogMapper.class);  Blog blog = mapper.selectBlog(101);} finally {  session.close();}

API的意思就是JAVA的多线程机制很可能会出现多个线程同时处理一个程序 那么就产生不安全的隐患 因此最好的设计思路就是使用方法调用或者数据请求 那么 就可以这么设计 而绝对不可以将其设计成类的一个属性来调用 或者通过new一个对象来调用 同时将其和Serlvet 等类似的管理类中 这种设计是不明智的

public static SqlSession  getSqlSession(){        return sqlSessionFactory.openSession();    }

通过方法调用并且返回值就可以获得session语句了

关闭语句

    public  static void closeSession(SqlSession session){        if(session!=null){            session.close();        }    }

整合一个例子

int deleteGradeInfo(String[]ids);
//接口int deleteGradeInfo(String[]ids);//实现方法public int deleteGradeInfo(String[]ids){        SqlSession session=MyBatisUtils.getSqlSession();//通过方法调用取得session  MyBatisUtils是上述方法的公共类名        int i=0;        try {            basedDao=session.getMapper(BaseGradeDao.class);            i=basedDao.deleteGradeInfo(ids);            session.commit();//session语句中增加 修改  都要提交数据才可以        } catch (Exception e) {            e.printStackTrace();        }finally{            MyBatisUtils.closeSession(session);//结束时关闭        }        return i;    }
0 0