Mybatis

Mybatis框架学习

Mybatis介绍

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis
避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis
可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的 POJO(Plain Old
Java Objects,普通老式 Java 对象)为数据库中的记录。

Mybatis简单使用

1.初始化SqlSessionFactory对象:

1.SqlSessionFactory对象:

需要从核心配置文件中获得,因此我们创建SqlSessionFactory对象时需要先配置一个Mybatis核心配置文件,过程如下:

1>.创建一个模板:建议最好去官网上找模板Mybatis配置模板

在这里插入图片描述

2.效果试图和创建Mybatis过程:

在这里插入图片描述

3.创建后的文件:

在这里插入图片描述

2.核心配置文件如下:

<?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文件,路径从类路径的根目录开始 -->
    <properties resource="jdbc.properties" />

    <settings>
        <!-- 开启将数据库中下划线连接的字段自动映射为Java的小驼峰命名 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <!-- 定义类型别名,在xxxMapper.xml文件中就可以用别名代替很长的类名 -->
    <typeAliases>
        
            <!-- 单个类配置别名 -->
<!--        <typeAlias type="com.lanou3g.mybatis.bean.User" alias="User" />-->
        
            <!-- 统一配置某个包下所有类的别名, 会使用 Bean 的首字母小写的类名来作为它的别名。 -->
        <package name="com.lanou3g.mybatis.bean" />
    </typeAliases>


    <!-- 配置不同环境的参数 -->
    <environments default="development">
        <!-- 开发环境数据库、事务配置 -->
        <environment id="development">
            <!-- 事务管理使用JDBC的事务 -->
            <transactionManager type="JDBC"/>
            <!-- 配置开发环境数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.user}"/>
                <property name="password" value="${jdbc.password}"/>
                <!-- 将所有driver.开头的参数,附加到url属性的值后面上 -->
                <property name="driver.characterEncoding" value="utf8"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 将mapper SQL映射文件包含进来 -->
    <mappers>
        <!-- 将通过XML方式配置的mapper引入进来 -->
        <mapper resource="mapper/userMapper.xml"/>
        <!-- 将通过注解方式配置的mapper引入进来 -->
<!--        <mapper class="com.lanou3g.mybatis.mapper.UserMapper" />-->

        <!-- 将com.lanou3g.mybatis.mapper包下所有通过注解方式配置的mapper引入进来 -->
<!--        <package name="com.lanou3g.mybatis.mapper"/>-->
    </mappers>
</configuration>
1.构建对象:
 @Test
    public void testXml() throws IOException {
        String xmlPath = "mybatis_config.xml";
        InputStream inputStream = Resources.getResourceAsStream(xmlPath);
        SqlSessionFactory sessionFactory = new 			                      SqlSessionFactoryBuilder().build(inputStream);
        System.out.println(sessionFactory);
    }
2.创建SqlSession对象

通过上步的SqlSessionFactory对象的创建可以获取到负责执行sql的SqlSession对象

// 3. 获取SqlSession对象,默认事务不自动提交
// SqlSession sqlSession = sqlSessionFactory.openSession();
// 获取一个自动提交事务的sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
3.用SqlSession对象从Mybatis中获取Mapper接口的实现类
 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
4.编写Mapper对象的xml配置文件

和核心配置文件的步骤一样去官网找文档配置修改之后是这样,这里可以配合Fre Mybatis plugin插件使用效率更高:

<?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.lanou3g.mybatis.mapper.UserMapper">
    <select id="queryAllUser" resultType="user">
        select * from user
     </select>

    <insert id="insertUser">
      insert into user (username,nick_name,email)
      values (#{username},#{nickName},#{email})
    </insert>
</mapper>

深入了解Mybatis

主要组件

核心配置文件的处理:

所谓的核心配置文件,就是mybatis的入口.它里面可以配置mybatis的具体参数、数据源、类型别名、关联映射文件等。

加载Mybatis配置文件的路径:
 String configMybatisXmlpath = "mybatis-config.xml";
Resources
package org.apache.ibatis.io;
//Resources:所在的包.
	public static InputStream getResourceAsStream(String resource) throws IOException {
        return getResourceAsStream((ClassLoader)null, resource);
    }

	public static InputStream getUrlAsStream(String urlString) throws IOException {
        URL url = new URL(urlString);
        URLConnection conn = url.openConnection();
        return conn.getInputStream();
    }

//上面是底层常用的方法:
//例如:加载加载Mybatis配置文件
InputStream inputStream = Resources.getResourceAsStream(configurationXmlPath);
SqlSessionFactoryBuilser

主要用来创建SqlSessionFactory接口类对象.

//SqlSessionFactoryBuiler所在的包:
package org.apache.ibatis.session;

	public SqlSessionFactory build(Reader reader, String environment) {
        return this.build((Reader)reader, environment, (Properties)null);
    }

	public SqlSessionFactory build(InputStream inputStream) {
        return this.build((InputStream)inputStream, (String)null, (Properties)null);
    }
//上面是SqlSessionFactoryBuilser的部分底层.我们调用build方法来获得下面的SqlSessionFactory接口类对象.
//例如下面:获得SqlSessionFactory接口类对象:development表示xml中的environment的id
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream,"development");

SqlSessionFactory

一个SqlSessionFactory只能连接一个数据库实例,如果需要连接多个数据库,需要构建多个SqlSessionFactory对象。

在构建SqlSesssionFactory时可以指定environment的id,表示使用指定的数据源来构建factory对象

	//这个是是否开启自动提交事务:入过不开启自动提交的话可能出现sql语句执行了,页成功了但	
	//是没有插入到数据库例如下面实例:一般我们把参数设置为true,让它自动提交事务,如果没有设置出现下面实例	//	中的错误,在实例1下面由解决方法.注意Query时开不开没关系,最好开启
	SqlSession openSession((boolean autoCommit);
    SqlSession openSession(Connection var1);                        
    //TransactionIsolationLevel是一个枚举类,事务隔离
	// NONE(0),
    //READ_COMMITTED(2),
    //READ_UNCOMMITTED(1),
    //REPEATABLE_READ(4),
    //SERIALIZABLE(8);
    SqlSession openSession(TransactionIsolationLevel level);
	// ExecutorType枚举类
    //SIMPLE,
    //REUSE,
    //BATCH;   最常用的试着个,Mybatis缓冲,下面我们会总结到                
    SqlSession openSession(ExecutorType var1);

    SqlSession openSession(ExecutorType var1, boolean var2);

    SqlSession openSession(ExecutorType var1, TransactionIsolationLevel var2);

    SqlSession openSession(ExecutorType var1, Connection var2);

    Configuration getConfiguration();

关于Mybatis的TransactionIsolationLevel枚举类的探究,事务隔离级别:

​ 隔离级别:一个事务必须与由其他事务进行的资源或数据更改相隔离的程度。隔离级别从允许的并发副作用(例如,脏读或虚拟读取)的角度进行描述。

none:
read uncommitted | 1 未提交读
read committed | 2 已提交读
repeatable read | 4 可重复读
serializable | 8 可序列化

实例1:

    @Test
    public void testPaperGirl() {
        String configurationXmlPath = "mybatis-config.xml";
        try {
            InputStream inputStream = 					            Resources.getResourceAsStream(configurationXmlPath);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //注意这里要开启事务:坑
            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
            KingMapper mapper = sqlSession.getMapper(KingMapper.class);
            List<Girl> girlList = new ArrayList<>();
            Collections.addAll(girlList, new Girl("木兰", 2), new Girl("伽罗", 2));
            int count = 0;
            List<BatchResult> batchResults = null;
            for(Girl girl : girlList){
                mapper.insertPaperGir(girl);
                count ++ ;
                if(count % 2 == 0){
                    batchResults = sqlSession.flushStatements();
                    count = 0 ;
                }
            }
            for(BatchResult batchResult : batchResults){
                int[] updateCounts = batchResult.getUpdateCounts();
                for(int updateCount : updateCounts){
                    System.out.println(updateCount);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

结果如下:
在这里插入图片描述

但是数据库中并没有插入:

在这里插入图片描述

解决办法有两种

//解决方法一:
SqlSession openSession(true);
//解决方法二
    @Test
    public void testPaperGirl() {
        String configurationXmlPath = "mybatis-config.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(configurationXmlPath);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            //注意这里要开启事务:坑
            SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
            KingMapper mapper = sqlSession.getMapper(KingMapper.class);
            List<Girl> girlList = new ArrayList<>();
            Collections.addAll(girlList, new Girl("木兰", 2), new Girl("伽罗", 2));
            int count = 0;
            List<BatchResult> batchResults = null;
            for(Girl girl : girlList){
                mapper.insertPaperGir(girl);
                count ++ ;
                if(count % 2 == 0){
                    batchResults = sqlSession.flushStatements();
                    count = 0 ;
                }
            }
            for(BatchResult batchResult : batchResults){
                int[] updateCounts = batchResult.getUpdateCounts();
                for(int updateCount : updateCounts){
                    System.out.println(updateCount);
                }
            }
            //在这里加事务提交:
            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

解决后结果:

在这里插入图片描述

SqlSession

一个SqlSession对象代表一次到数据的会话,该对象有一下功能:

  • 获取Mapper实现类
  • 管理事务操作
  • 注意: SqlSession对象是非线程安全的,在多线程环境下,建议不要作为类的实例属性来用。
Mapper接口类:
Mapper
  • Mapper接口类

    定义了增删盖查的方法。注意,必须是接口类型,而且方法只需要定义就可以了。

  • Mapper配置文件

    Mapper配置文件中就是负责实现接口中的方法,它定义了具体要执行什么SQL语句,如何映射结果集。

    • 配置文件中select、delete、update、insert标签的id必须是对应接口中的方法名。
    • mapper文件的namespace属性需要对应Mapper接口的完全类型限定名。

深入Mybatis核心配置文件

深入Mybatis映射配置文件

CRUD语句定义

接口中的源码

public interface KingMapper {
    List<King> findKingById(int id);
    int insertGirl(List<Girl> girlList);
    int insertPaperGir(Girl girl);
}

xml中的配置

<?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.lanou.mapper.KingMapper">

    <resultMap id="kingMap" type="com.lanou.bean.King">
        <id column="k_id" property="kId"/>
        <result column="k_name" property="kName"/>
        <association property="queen" javaType="com.lanou.bean.Queen" resultMap="queenMap"/>
        <collection property="girls" ofType="com.lanou.bean.Girl" resultMap="girlMap"/>
    </resultMap>

    <resultMap id="girlMap" type="com.lanou.bean.Girl">
        <id property="gId" column="g_id"/>
        <result property="kId" column="k_id"/>
        <result property="gName" column="g_name"/>

    </resultMap>

    <resultMap id="queenMap" type="com.lanou.bean.Queen">
        <id column="q_id" property="qId"/>
        <result column="k_id" property="kId"/>
        <result column="q_name" property="qName"/>
    </resultMap>
    <insert id="insertGirl">
        insert into girl (g_name,k_id) values
        <foreach collection="list" item="girl" separator=",">
            (#{girl.gName},#{girl.kId})
        </foreach>
    </insert>
    <insert id="insertPaperGir">
      insert into girl (g_name,k_id) values(#{gName},#{kId})
    </insert>

    <select id="findKingById" resultMap="kingMap">

        select
         king.k_id k_id,
         k_name,
         q_id,
         q_name,
         g_id,
         g_name
        from king
        left join girl
        on king.k_id = girl.k_id
        left join queen
        on queen.k_id = king.k_id
        where king.k_id = #{id};
    </select>
</mapper
插入语句
普通插入语句

接口

int insertUser(User user);

xml中的配置

<insert id="insertUser">
    insert into user (username,nick_name,email)
    values (#{username},#{nickName},#{email})
</insert>
如何返回数据库自增的ID
java源代码之接口中
public interface GirlMapper {
    int insertGirl(Girl girl);
}
xml中
<!-- 给insert语句添加useGeneratedKeys、keyProperty后,mybatis会将自增的id值直接赋值到传进来的user对象的id属性上
        useGeneratedKeys: 指定需要获取数据库自增的id
        keyProperty: 指定自增地段的名称
ps:只对update和insert语句使用
     -->
 <insert id="insertGirl" useGeneratedKeys="true" keyProperty="gId" >
        insert into girl (g_name,k_id)
        values(#{gName},#{kId})
    </insert>
测试
@Test
    public void testGirl(){
        String configMybatisXmlpath = "mybatis-config.xml";
        try {
            InputStream resourceAsStream = Resources.getResourceAsStream(configMybatisXmlpath);
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
            SqlSession sqlSession = sessionFactory.openSession(true);
            GirlMapper girlMapper = sqlSession.getMapper(GirlMapper.class);
            Girl girl = new Girl("香蛋",1);
            int i = girlMapper.insertGirl(girl);
            System.out.println(girl.getGId());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
结果

在这里插入图片描述

ps:

​ keyColumn="":(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望使用多个生成的列,也可以设置为逗号分隔的属性名称列表。

​ keyProperty="" :给insert语句添加useGeneratedKeys、keyProperty后,mybatis会将自增的id值直接赋值到传进来的user对象的id属性上:

​ useGeneratedKeys: 指定需要获取数据库自增的id
keyProperty: 指定自增地段的名称

只对update和insert语句使用

删除语句

接口中

void deleteUserById(Integer id);

xml中的配置:

<delete id="deleteUserById">
    delete from user where id = #{id}
</delete>
更新语句

接口中:

void updateUser(User user);

XML配置中

<update id="updateUser">
    update user set password = #{password} where id = #{id}
</update>
ps:

插入和更新删除需要:

    SqlSession sqlSession = sessionFactory.openSession(true);

接口中的参数如果传递到SQL中

简单类型参数

接口中

void deleteUserById(Integer id);

xml配置

<delete id="deleteUserById">
    delete from user where id = #{id}
</delete>
引用类型参数

接口中

int insertUser(User user);
<!--这里注意取参数直接#+实体类字段名-->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
    insert into user (username,nick_name,email)
    values (#{username},#{nickName},#{email})
</insert>
当接口中参数和XML配置取值时名称不一样时

ps:现在Mybatis版本中的不存在这个问题

在接口中的参数前加注解

User queryUserById(@Param("id") Integer xxxxxxxId);

在XML中取值时用注解指定的名称

<select id="queryUserById" resultType="user">
    select * from user where id = #{id}
</select>

例如:

接口中的java代码:

public interface GirlMapper {
    Girl queryGirl(Integer sid);
}

xml中的配置:

    <select id="queryGirl" resultType="com.lanou.bean.Girl">
        select * from girl where g_id = #{gId}
    </select>

运行的结果:
在这里插入图片描述

#{}与${}的区别
  • 它俩都可以获取接口调用中传递过来的参数
  • #{}会将参数作为占位符,使用预编译语句(PreparedStatement)执行
  • 会 直 接 用 实 际 参 数 替 换 {}会直接用实际参数替换 {}, 参数可以作为SQL的一部分。

接口中的配置:

public interface GirlMapper {
    Girl queryGirl(Integer sid);
}

xml配置:

    <select id="queryGirl" resultType="com.lanou.bean.Girl">
        select * from girl where g_id = #{gId}
    </select>

#的运行结果:
在这里插入图片描述在这里插入图片描述

结果集如何映射
ResultType方式

​ ResultType方式适用于数据库结果集可以直接映射成一个Java类的情况

ResultMap方式

​ ResultMap方式适用于复杂的结果集映射,比如数据库返回的结果集中的列名和JavaBean无法一一对应,或者对象间存在一对一、一对多关联映射时。

解决数据库列名与Java类中属性名不一致的映射问题
解决一对一映射查询问题
解决一对多映射查询问题

下面是例子:

package com.lanou.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Setter
@Getter
@ToString
public class Girl {
    private int gId;
    private int kId;
    private String gName;
    public Girl(){

    }
    public Girl(String gName ,int kId) {
        this.gName = gName;
        this.kId = kId;

    }
}
package com.lanou.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

import java.util.List;

@Setter
@Getter
@ToString
public class King {
    private int kId;
    private String kName;
    private Queen queen;
    private List<Girl> girls;
}

package com.lanou.bean;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@Getter
@Setter
@ToString
public class Queen {
    private int qId;
    private int kId;
    private String qName;
}

接口中

package com.lanou.mapper;

import com.lanou.bean.Girl;
import com.lanou.bean.King;

import java.util.List;

public interface KingMapper {
    List<King> findKingById(int id);
    int insertGirl(List<Girl> girlList);
    int insertPaperGir(Girl girl);
}

xml中的配置

<?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.lanou.mapper.KingMapper">

    <resultMap id="kingMap" type="com.lanou.bean.King">
        <id column="k_id" property="kId"/>
        <result column="k_name" property="kName"/>
        <!--这是一对一的情况-->
        <association property="queen" javaType="com.lanou.bean.Queen" resultMap="queenMap"/>
        <!--这是一对多的情况-->
        <collection property="girls" ofType="com.lanou.bean.Girl" resultMap="girlMap"/>
    </resultMap>

    <resultMap id="girlMap" type="com.lanou.bean.Girl">
        <id property="gId" column="g_id"/>
        <result property="kId" column="k_id"/>
        <result property="gName" column="g_name"/>

    </resultMap>

    <resultMap id="queenMap" type="com.lanou.bean.Queen">
        <id column="q_id" property="qId"/>
        <result column="k_id" property="kId"/>
        <result column="q_name" property="qName"/>
    </resultMap>
    <insert id="insertGirl">
        insert into girl (g_name,k_id) values
        <foreach collection="list" item="girl" separator=",">
            (#{girl.gName},#{girl.kId})
        </foreach>
    </insert>

    <insert id="insertPaperGir">
      insert into girl (g_name,k_id) values(#{gName},#{kId})
    </insert>

    <select id="findKingById" resultMap="kingMap">

        select
         king.k_id k_id,
         k_name,
         q_id,
         q_name,
         g_id,
         g_name
        from king
        left join girl
        on king.k_id = girl.k_id
        left join queen
        on queen.k_id = king.k_id
        where king.k_id = #{id};
    </select>
</mapper>
动态sql
条件分支SQL
  • if

    mapper中:

    package com.lanou.mappers;
    import com.lanou.bean.Student;
    import java.util.List;
    public interface StudentMqpper {
        List<Student> findStudent(Student condition);
    }
    
    

    xml中:

       <select id="findStudent" resultType="com.lanou.bean.Student">
            select * from `student`
            <where>
            <if test="sex != null" >
               sex = #{sex}
            </if>
            <if test="name != null" >
                and name = #{name}
            </if>
            </where>
        </select>
    

    测试1:

        @Test
        public void testStudentMapper(){
            String configMybatisXmlpath = "mybatis-config.xml";
            try {
                InputStream resourceAsStream = Resources.getResourceAsStream(configMybatisXmlpath);
                SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
                SqlSession sqlSession = sessionFactory.openSession();
                StudentMqpper mapper = sqlSession.getMapper(StudentMqpper.class);
                Student condition = new Student();
                condition.setName("黄忠");
                condition.setSex("男");
                List<Student> studentList = mapper.findStudent(condition);
                for(Student student1 :studentList ){
                    System.out.println(student1.toString());
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    

    结果:

在这里插入图片描述

测试2:把setAge注释掉:

结果为:

在这里插入图片描述

  • choose&when&otherwise
循环SQL
  • forEach

两种forEach:

第一种:

实例

mapper中:

public interface KingMapper {
    int insertGirl(List<Girl> girlList);
}

xml中:

<insert id="insertGirl">
        insert into girl (g_name,k_id) values
        <foreach collection="list" item="girl" separator=",">
            (#{girl.gName},#{girl.kId})
        </foreach>
    </insert>

第二种:

mapper中:

public interface KingMapper {
    int insertPaperGir(Girl girl);
}

xml中:

  <insert id="insertPaperGir">
      insert into girl (g_name,k_id) values(#{gName},#{kId})
    </insert>
其他特殊SQL
  • where
  • set
  • trim

一级缓存:

默认情况下是一级缓存,配置方法:

<setting name="localCacheScope" value="SESSION"/>

取值有两个:SESSION和STATEMENT分别对应缓存应用session会话范围和一次statement范围

在这里插入图片描述

验证:

mapper中:

public interface GirlsMapper {
    List<Girl> queryGirls();
    int insertGirl(Girl girl);
}

xml中:

    <insert id="insertGirl">
        insert into girl (g_name,k_id) value(#{gName},#{kId})
    </insert>

    <select id="queryGirls" resultType="com.lanou.bean.Girl">
        select * from girl
    </select>

测试:注意先不要设置自动提交,这样就能看到增删改是先对缓存的改动.提交之后才能到数据库更新数据:

    @Test
    public void testCache(){
        String mybatisXmlpath ="mybatis-config-cache.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(mybatisXmlpath);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            GirlsMapper girlsMapper = sqlSession.getMapper(GirlsMapper.class);
            List<Girl> girlList = girlsMapper.queryGirls();
            System.out.println("*************" + girlList.size());
            for(Girl girl : girlList){
                System.out.println(girl.toString());
            }

            Girl girl = new Girl("香香",1);
            int i = girlsMapper.insertGirl(girl);
            System.out.println(i);
           // sqlSession.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果是:

在这里插入图片描述

然而数据库中则:

在这里插入图片描述

放开commit:

    @Test
    public void testCache(){
        String mybatisXmlpath ="mybatis-config-cache.xml";
        try {
            InputStream inputStream = Resources.getResourceAsStream(mybatisXmlpath);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sqlSessionFactory.openSession();
            GirlsMapper girlsMapper = sqlSession.getMapper(GirlsMapper.class);
            List<Girl> girlList = girlsMapper.queryGirls();
            System.out.println("*************" + girlList.size());
            for(Girl girl : girlList){
                System.out.println(girl.toString());
            }

            Girl girl = new Girl("香香",1);
            int i = girlsMapper.insertGirl(girl);
            System.out.println(i);
           // sqlSession.commit();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

结果:

在这里插入图片描述

在这里插入图片描述

结果很明显也很符合上面原理图

二级缓存:

在这里插入图片描述

开启二级缓存的方法

  1. 第一步,打开全局二级缓存开关
<setting name="cacheEnabled" value="true"/>
  1. 在具体的Mapper中开启二级缓存
<cache/> 

可配置参数:

  • type:cache使用的类型,默认是
  • PerpetualCache,这在一级缓存中提到过。
  • eviction: 定义回收的策略,常见的有FIFO,LRU。
  • flushInterval: 配置一定时间自动刷新缓存,单位是毫秒。
  • size: 最多缓存对象的个数。
  • readOnly: 是否只读,若配置可读写,则需要对应的实体类能够序列化。
  • blocking: 若缓存中找不到对应的key,是否会一直blocking,直到有对应的数据进入缓存。

注意 要使用二级缓存结果集对应的POJO类必须实现序列化接口

Spring与Mybatis的整合:

1.需要的依赖:

<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>2.0.2</version>
</dependency>

2.在Spring中管理SqlSessionFactory

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

    <!-- 注入数据源 -->
    <property name="dataSource" ref="dataSource"/>
    <!-- 设置mybatis核心配置文件路径(可选) -->    
    <property name="configLocation" value="classpath:/mybatis-config.xml" />
     <!-- 配置mybatis xml映射文件位置(如果Mapper是用注解配置的,这里就不用设置此属性了) -->   
    <property name="mapperLocations" value="classpath:/mappers/*" />
    </bean>

如果是注解的方式配置的Mapper,我们需要在Spring配置文件中添加mybatis的schema以支持mybatis注解扫描

<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xmlns:mybatis="http://mybatis.org/schema/mybatis-spring"
  xsi:schemaLocation="
  http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
  http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring.xsd">

<!-- 配置基于注解的Mapper所在包的路径 -->
  <mybatis:scan base-package="org.mybatis.spring.sample.mapper" />


</beans>

或者这样配置

@Configuration
@MapperScan("org.mybatis.spring.sample.mapper")
public class AppConfig {
  // ...
}

3.用Spring管理事务

和单独使用Spring时一样, 配置Spring的声明式事务就可以了,mybatis会自动参与到spring的事务中

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值