Java教程

Mybatis的缓存与动态SQL

本文主要是介绍Mybatis的缓存与动态SQL,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Mybatis的缓存

缓存也是为了减少java应用与数据库的交互次数,提升程序的效率

一级缓存

自带一级缓存,并且无法关闭,一直存在,存储在SqlSession中

使用同一个sqlsession进行查询操作一级缓存存在;如果有多个sqlsession那么一级缓存不存在

缓存一般争对查询,如果进行了增删改查操作,会自动的将缓存的数据清除,保证数据的一致性,一级缓存不需要设置,直接使用即可。

1.实体类

package com.shouthwind.entity;

import lombok.Data;

import java.util.List;

@Data
public class Account {
    private Integer id;
    private String name;
    private List<Course> courses;
}

2.接口

package com.shouthwind.repository;

import com.shouthwind.entity.Account;

public interface AccountRepository {
    public Account findById1(Integer id);
    public Account findById(Integer id);
}

3.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="com.shouthwind.repository.AccountRepository">
    <resultMap id="accoutMap" type="com.shouthwind.entity.Account">
        <id column="aid" property="id"></id>
        <result column="aname" property="name"></result>
        <collection property="courses" ofType="com.shouthwind.entity.Course">
            <id column="cid" property="id"></id>
            <result column="cname" property="name"></result>
        </collection>
    </resultMap>
 <select id="findById1" parameterType="java.lang.Integer" resultMap="accoutMap">
     select a.id aid,a.name aname,c.id cid,c.name cname from account a,t_course c,account_course ac where a.id=#{id} and a.id=ac.aid and c.id=ac.cid
 </select>
    <select id="findById" parameterType="java.lang.Integer" resultType="com.shouthwind.entity.Account">
        select * from  account where id=#{id}
    </select>
</mapper>

4.测试

对一个SQL session一直使用查询的结果

二级缓存

它是Mapper级别的,无论使用多少个sqlsession都可以共享。

二级缓存默认是关闭的,二级缓存配置开启。

  • 自带的二级缓存
  • 第三方的ehcache二级缓存

自带的二级缓存

1.配置config.xml

<!--        打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

2.Mapper.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.shouthwind.repository.StudentRepository">

    <cache></cache>

    <resultMap id="studentMap" type="com.shouthwind.entity.Student">
        <id column="sSno" property="Sno"></id>
        <result column="sSname" property="Sname"></result>
        <result column="sSsex" property="Ssex"></result>
        <result column="sSage" property="Sage"></result>
        <result column="sSdept" property="Sdept"></result>
        <association property="sc"  javaType="com.shouthwind.entity.Sc">
            <result column="cSno" property= "Sno"></result>
            <result column="cCno" property="Cno"></result>
            <result column="cGrade" property="Grade"></result>
        </association>
    </resultMap>
    <select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
        select s.Sno sSno,s.Sname sSname,s.Ssex sSsex,s.Sage sSage,s.Sdept sSdept,c.Sno cSno,c.Cno cCno,c.Grade cGrade from student s,sc c where s.Sno=c.Sno and s.Sno=#{Sno}
    </select>
</mapper>

3.实体类实现Serializable接口

package com.shouthwind.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class Student implements Serializable {
    private  Integer Sno;
    private String Sname;
    private String Ssex;
    private Integer Sage;
    private String Sdept;
    private  Sc sc;
}

第三方的ehcache缓存

1.配置

<!--        ehcache-->
        <dependency>
            <groupId>net.sf.ehcache</groupId>
            <artifactId>ehcache-core</artifactId>
            <version>2.4.3</version>
        </dependency>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-ehcache</artifactId>
            <version>1.0.0</version>
        </dependency>

2.在resource小创建ehcache创建配置

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- 磁盘保存路径 -->
    <diskStore path="D:\\ehcache" />

    <defaultCache
            maxElementsInMemory="10000"
            maxElementsOnDisk="10000000"
            eternal="false"
            overflowToDisk="true"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

3.config.xml中配置二级缓存

    <settings>
<!--        打印SQL-->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
<!--        延迟加载-->
        <setting name="lazyLoadingEnabled" value="true"/>
<!--        开启二级缓存-->
        <setting name="cacheEnabled" value="true"/>
    </settings>

4.Mapper.xml中配置二级缓存

    <cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!--        缓存创建以后,最后一次访问的时间到失效时间-->
        <property name="timeToIdleSeconds" value="3600"/>
<!--        缓存自创建时间起自失效时间的间隔-->
        <property name="timeToLiveSeconds" value="3600"/>
<!--        缓存回收策略,LRU移除近期的最少使用的对象-->
        <property name="memoryStoreEvictionPolicy" value="LRU"/>
    </cache>

5.实体类不需要实现序列化接口

Mysql的动态SQL

Mybatis的动态SQL可以更据不同的信息来拼接不同的SQL、以适应不同的需求

1.创建实体类

package com.shouthwind.entity;

import lombok.Data;

@Data
public class People {
//    private Integer Sno;
//    private String Sname;
//    private String Ssex;
//    private Integer Sage;
//    private String Sdept;
    private Integer id;
    private String name;
    private Integer money;
}

2.创建Mapper接口和文件

package com.shouthwind.repository;

import com.shouthwind.entity.People;

import java.util.List;

public interface UserRepository {
//    public int save(People people);
//    public int deleteById(Integer id);
//    public  int update(People people);
//    public People findById(Integer id);
//    public List<People> findAll();
//    public  People findById2(int id);
//    public  People findByName(String name);
//    public  People findByIdAndName(Integer id,String name);
//    public Integer count();
//    public  String findNameById(Integer id);
    public People findByUser (People people);
}

<!--    动态  sql-->
    <select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
        select  * from  people
        <where>
            <if test="id!=null">
                id=#{id}
            </if>
            <if test="name!=null">
                and name={name}
            </if>
            <if test="money!=null">
                and money=#{money}
            </if>
        </where>
    </select>

4.测试

package com.shouthwind.Test;

import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test7 {
    public static void main(String[] args) {
        InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取实现了自定义代理接口的对象
        UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
        People people = new People();
        people.setId(1);
        People result =userRepository.findByUser(people);
        System.out.println(result);
    }
}

if

where

  • choose、when
    类似swich case

代码:

<!--    动态  sql-->
    <select id="findByUser" parameterType="com.shouthwind.entity.People" resultType="com.shouthwind.entity.People">
        select  * from  people
        <where>
        <choose>
            <when test="id!=null">
                id=#{id}
            </when>
            <when test="name!=null">
                and name={name}
            </when>
            <when test="money!=null">
                and money=#{money}
            </when>
        </choose>
        </where>
    </select>
  • trim
    设置predix和suffix参数来完成使用

  • set用于update操作
    package com.shouthwind.repository;

    import com.shouthwind.entity.People;
    
    import java.util.List;
    
    public interface UserRepository {
    //    public int save(People people);
    //    public int deleteById(Integer id);
    //    public  int update(People people);
    //    public People findById(Integer id);
    //    public List<People> findAll();
    //    public  People findById2(int id);
    //    public  People findByName(String name);
    //    public  People findByIdAndName(Integer id,String name);
    //    public Integer count();
    //    public  String findNameById(Integer id);
        public People findByUser (People people);
        public Integer update (People people);
    }
    

    mapperi文件

    update people


    name=#{name},


    money=#{money}


    where id=#{id}

测试类:

package com.shouthwind.Test;

import com.shouthwind.entity.People;
import com.shouthwind.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test7 {
    public static void main(String[] args) {
        InputStream inputStream = Test7.class.getClassLoader().getResourceAsStream("config.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //获取实现了自定义代理接口的对象
        UserRepository userRepository=sqlSession.getMapper(UserRepository.class);
        People people = new People();
        people.setId(1);
        people.setName("郝momo");
        people.setMoney(55);
        userRepository.update(people);
        sqlSession.commit();
//        People result =userRepository.findByUser(people);
//        System.out.println(result);
        sqlSession.close();
    }
}
这篇关于Mybatis的缓存与动态SQL的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!