MyBatisday01

Mybatis入门

为什么使用框架

  • 是一个应用程序的半成品
  • 提供可重用的公共结构
  • 按一定规则组织的一组组件

优势:

  • 不用再考虑公共部分
  • 专心在业务实现上
  • 结构同一,易于学习,维护
  • 新手也可以写出好程序

世界上流行的框架(framework)

  • Struts1\Struts2\Spring MVC\Spring Boot
  • Hibernate\MyBatis
  • Spring

持久化与瞬时状态

  • 瞬时状态

  当创建一个对象后,但没有存储到数据库中之前的一段时间状态被称为瞬时状态

  • 持久状态

  当一个对象被存到了磁盘上或者数据库中时,这时的状态为持久状态

事务(Transaction)

  事务(Transaction),一般是指要做的或所做的事情。在计算机术语中是指访问并可能更新数据库中各种数据项的一个程序执行单元(unit)。

  默认情况下,MySQL的事务提交方式是自动提交。每一条SQL语句就是一个独立的事务

延时加载(LazyLoad)

  默认情况下,框架会将某一个表的映射关系全部读取出来。如果所有的数据,在读取一张表的时候,就将所有的关联表数据全部加载出来,会造成内存使用量消耗过大,在MyBatis中提供了延迟加载,即,什么时候用到关联表数据,再发起查询,避免内存浪费。

 


Mybatis环境搭建

导入依赖

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.6</version>
</dependency>

 

创建xml

全局文件配置

配置全局xml 一般叫做mybatis-config.xml

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

 

最简单的全局配置文件由三个部分组成:

  • 数据源
// 该写法,代表调用默认的配置数据源
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is) ;

// 该写法,代表调用所选的的配置数据源
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is,"dev") ;
<environments default="development">
     <environment id="development">
         <!--事务管理器-->
         <transactionManager type="JDBC"/>
         <!--数据源:数据连接池-->
         <dataSource type="POOLED">
             <property name="driver" value="${oracle_driver}"/>
             <property name="url" value="${oracle_url}"/>
             <property name="username" value="${oracle_username}"/>
             <property name="password" value="${oracle_password}"/>
         </dataSource>
     </environment>


     <environment id="dev">
         <!--事务管理器-->
         <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>
  • 事务管理

  事务管理默认使用的是JDBC调用,还可以配置其他的使用方式。

  • 映射文件加载
<mappers>
         <!--注意这里的路径要与实体类路径相对应-->
    <mapper resource="com/csi/domain/RoleMapper.xml" />
        <mapper .../>
</mappers>      

映射文件

<?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">
<!--namespace:属性值在全局只能存在一个,一般普通写法都是写的对应的实体类名称-->
<mapper namespace="com.csi.domain.Role">
    <!--
        id:代表方法名称
        resultType:返回的类型
    -->
    <select id="list" resultType="com.csi.domain.Role">
        SELECT * FROM smbms_role
    </select>
</mapper>

映射类型对应表:

别名映射的类型
_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
object Object
map Map
hashmap HashMap
list List
arraylist ArrayList
collection Collection
iterator Iterator

日志文件配置(选用log4j)

log4j.rootLogger=DEBUG,CONSOLE,file
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.com.csi.dao=debug
log4j.logger.com.ibatis=debug 
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug 
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug 
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug 
log4j.logger.java.sql.Connection=debug 
log4j.logger.java.sql.Statement=debug 
log4j.logger.java.sql.PreparedStatement=debug 
log4j.logger.java.sql.ResultSet=debug 
log4j.logger.org.tuckey.web.filters.urlrewrite.UrlRewriteFilter=debug

######################################################################################
# Console Appender  \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern= [%p] %d %c - %m%n


######################################################################################
# DailyRolling File  \u6bcf\u5929\u4ea7\u751f\u4e00\u4e2a\u65e5\u5fd7\u6587\u4ef6\uff0c\u6587\u4ef6\u540d\u683c\u5f0f:log2009-09-11
######################################################################################
log4j.appender.file=org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.DatePattern=yyyy-MM-dd
log4j.appender.file.File=log.log
log4j.appender.file.Append=true
log4j.appender.file.Threshold=error
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-M-d HH:mm:ss}%x[%5p](%F:%L) %m%n


log4j.logger.com.opensymphony.xwork2=debug

Mybatis生命周期

SqlSessionFactoryBuilder

  • 用过即丢,其生命周期只存在于方法体内
  • 可重用其来创建多个SqlSessionFactory实例
  • 负责构件SqlSessionFactory,并提供多个build方法的重载

SqlSessionFactory

  • SqlSessionFactory是每个MyBatis应用的核心
  • 作用:创建SqlSession实例
    • 在创建SqlSession的同时,能够将事务设置为手动或者自动的
    • SqlSession sqlSession = sqlSessionFactory.openSession(boolean autoCommit);
    • true | false 默认为false 表示事务不自动提交
  • 作用域:application
  • 生命周期与应用的声明周期相同
  • 单利
    • 存在于整个应用运行中,并且同时只存在于一个对象实例中  

SqlSession

  • 包含了执行SQL所需的所有方法
  • 对应一次数据库会话,会话结束必须关闭
  • 线程级别,不能共享
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}

 

  在sqlSession不关闭的情况下可以多次执行sql,但关闭后SqlSession就需要重新创建

  在一个方法中使用sqlsession对象执行sql后,如果再次执行相同的sql,那么后一条sql就不会再次执行,而是直接取缓存中的数据。

‘完美’的单例模式

// 单例设计 获取SqlSessionFactory对象
public class MyBatisUtil {
    // 声明一个 静态的 sqlSessionFactory对象   volatile->禁止指令重排序
    private static SqlSessionFactory sqlSessionFactory = null;

    // 静态获取sqlsessionfactory工厂对象
    public static SqlSessionFactory getInstance(){

        System.out.println(Thread.currentThread().getName() + "....................." );

        // 判断sqlSessionFactory对象是否已经实例化 如果没有则通过io流读取配置文件数据
        if (sqlSessionFactory == null){
            InputStream is = null;
            try {
                is = Resources.getResourceAsStream("mybatis-config.xml");
            } catch (IOException e) {
                e.printStackTrace();
            }
            // 设置同步代码块 进行二次判断 如果此时sqlSessionFactory对象为null 则实例化
            synchronized (SqlSessionFactory.class){
                if (sqlSessionFactory == null){
                    sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
                }
            }
        }
        return sqlSessionFactory;
    }

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

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

 

  假如四个线程同时进入此方法,当sqlsessionFactory为null时,四个线程都会在synchronized块前阻塞,第一个进入代码块的线程会最先实例化sqlSessionFactory对象,并且取得sqlSessionFactory对象返回值,此时其他的线程获取到资源访问同步代码快中的代码,但是这是sqlSessionFactory对象已经不为null,所以其余阻塞线程都会直接获取sqlSessionFactory对象作为返回值,而不是重新使用SqlSessionFactoryBuilder().build()来创建SqlSessionFactory对象。

 

posted @ 2020-10-19 23:18  大明湖畔的闰土  阅读(92)  评论(0编辑  收藏  举报