Mybatis-

Mybatis

Mybatis的第一个程序

1.pom文件

 <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>
     <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.6</version>
        </dependency>

2.配置MapperConfig.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>
    <properties resource="jdbc.properties"/>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driverClass}"/>
                <property name="url" value="${jdbcUrl}"/>
                <property name="username" value="${user}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
<!--        resource:扫描的是xml文件-->
<!--        class:扫描的是xml文件-->
        <mapper resource="com/xukai/Mapper/UserMapper.xml"/>

    </mappers>
</configuration>

3.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.xukai.dao.Userdao">
    <select id="Getall" resultType="com.xukai.entity.User">
    select * from user_table
  </select>

    <select id="getUser" parameterType="java.lang.String" resultType="com.xukai.entity.User">
        select * from user_table where user = #{user}
    </select>

    <insert id="AddUser" parameterType="com.xukai.entity.User" >
        insert into user_table (user,password,balance)values(#{user},#{password},#{balance});
    </insert>

    <delete id="UpdateUser" parameterType="com.xukai.entity.User" >
        update user_table set user=#{user},password=#{password},balance=#{balance}
    </delete>

    <delete id="DeleteUser" parameterType="java.lang.String" >
        delete  from user_table where user=#{user}
    </delete>
</mapper>
   // 1.创建一个SqlSessioFactory
        SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();

        // 2.把MyBatis配置文件转成一个流
        InputStream ips = Resources.getResourceAsStream("mybatis-config.xml");

        // 3.构建SQLSessionFactory
        SqlSessionFactory sqlSessionFactory = sfb.build(ips);

        // 4.通过SQLSessionFactory创建SQLSession
        SqlSession sqlSession = sqlSessionFactory.openSession();


        // 这是IBatis中的写法
        // 调用返回一个结果集的sql语句
        Map<String,Object> map = new HashMap<>();
        map.put("name","admin");
        map.put("pw","admin");

        User user = (User)sqlSession.selectOne("com.qf.dao.IUserDao.getUserById", map);

//        sqlSession.selectList();
        sqlSession.insert("com.qf.dao.IUserDeao.addUser",new User());
//        sqlSession.delete()

       System.out.println(user);

Mybatis中的三种写法

1.通过映射器

  1. 通过xml

  2. 通过注解

    注解的话MapperConfig.xml中需要把<Mappers>换出calss扫描
    

2.直接调用sql(Iatis中的特有写法)官网有写法https://mybatis.org/mybatis-3/zh/getting-started.html

日志

Mybatis中也有内置日志

STDOUT_LOGGING (标准日志输出)

1.MapperConfig.xml文件配置

  <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

Log4j

  • Log4j是Apache的一个开源项目
  • 通过使用Log4j,我们可以控制日志信息输送的目的地:控制台,文本,GUI组件…
  • 我们也可以控制每一条日志的输出格式;
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。最令人感兴趣的就是,这些可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码。

1.相应的jar

  <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

2.log4j的配置文件

#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=DEBUG,console,file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/kuang.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

获取方法参数/别名设置

获取参数

  1. 按照索引

  2. 按照名称

  3. Map获取.根据key获取问value就是那个对应的值

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-danR4l54-1631536799134)(image/image-20210416110800219.png)]

  4. 对象自动属性获取

别名设置

<typeAliases>
    <!--typeAlias:这是指定一个类名的别名-->
    <!--package:这是指定一个包下的类起别名,默认就是类型小写.可以通过-->
        <typeAlias type="com.xukai.entity.User" alias="user"/>
        <package name="com.xukai.ent    ity"/>
    </typeAliases>

在这个包下设置了别名也可以修改别名,用注解@Alias

字段和属性映射关系

@Param

绑定的是mysql里面的字段

ResultMap

将数据和实体类里面的关系映射起来在这里插入图片描述

As

别名

主键回填

  1. xml配置

    <!--
        主键回填:
                useGeneratedKeys:true是否开启主键回填
                keyProperty:回填到哪个属性里面
    -->
        <insert id="AddStudent" useGeneratedKeys="true" keyProperty="id" >
            insert into user(name,password,address,phone)values(#{name},#{password},#{address},#{phone})
        </insert>
    
  2. 测试:

#和$区别

在这里插入图片描述

Mybatis动态sql

动态SQL指的是根据不同的查询条件 , 生成不同的Sql语句.

 ------------------------------- 
 - if  
 - choose (when, otherwise)  
 - trim (where, set) 
 - foreach 
 -------------------------------

if

 Student GetStudentById(@Param("id") Integer id,@Param("name") String username);
<!--
    Mybatis的动态sql练习,test里面为真的话就会加上if里面的sql
    if里面的test是个判断,name是传过来的字段
-->
    <select id="GetStudentById" resultType="student">
        select * from user
        where id = #{id}
        <if test="name != null and name != ''">
            and name=#{name}
        </if>
    </select>

where

Student GetStudentByMany(@Param("id") Integer id,@Param("name") String name);
<select id="GetStudentByMany" resultType="student">
        select *
        from user where
    //otherwise:如果都不匹配,那么久会加上这里面的 .就相当于java中的switch
        <choose>
            <when test="name != null">
                name = #{name}
            </when>
            <when test="id != null">
                id = #{id}
            </when>
            <otherwise>
              id = 1;
            </otherwise>
        </choose>
    </select>

where

  Student GetStudentByWhere(@Param("id") Integer id,@Param("name") String name);

            <!--where标签会替换自动生成where-->
    <select id="GetStudentByWhere" resultType="student">
        select * from user
        <where>
            <if test="id != null">
                id = #{id}
            </if>
            <if test="name != null and name != ''">
                and name=#{name}
            </if>
        </where>
    </select>

trim

  Student GetStudentByTrim(@Param("id") Integer id,@Param("name") String name);
            <!--  trim:
                        prefix:在之前添加的内容
                        prefixOverrides:前缀覆盖
                        suffix:在之后添加的内容
                  -->
    <select id="GetStudentByTrim" resultType="student">
        select * from user
        <where>
            <trim prefix="and" prefixOverrides=",">

                <if test="id != null">
                  ,  id = #{id}
                </if>
                <if test="name != null and name != ''">
                    , name=#{name}
                </if>
            </trim>
        </where>
    </select>

Foreach

 List<Student> GetListStudent(List<Integer> id);
<!--foreach:
            collection:遍历的属性 list,map,array,
            item:就是一个变量
            open:开头,只会掉用一次
            close:结束循环,只会调用一次
            separator:每次循环调用一次,
-->
    <select id="GetListStudent" resultType="student">
        select * 
        from user 
        where id in 
        <foreach item="ids" collection="list" open="(" close=")" separator=",">
            #{ids}
        </foreach>
    </select>

Set

set标签和trim标签一样,会自动添加set关键字,过滤多余的逗号

在这里插入图片描述

缓存

  1. 临时数据,
  2. 提高效率,在本地磁盘上面去查询,不用再去连接数据库

使用缓存的好处

  1. 减少开销
  2. 提高效率

Mybatis缓存

  • MyBatis包含一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大的提升查询效率。
  • MyBatis系统中默认定义了两级缓存:一级缓存二级缓存
    • 默认情况下,只有一级缓存开启。(SqlSession级别的缓存,也称为本地缓存)
    • 二级缓存需要手动开启和配置,他是基于namespace级别的缓存。
    • 为了提高扩展性,MyBatis定义了缓存接口Cache。我们可以通过实现Cache接口来自定义二级缓存

一级缓存

一级缓存也叫本地缓存,SqlSession级别的缓存

  • 与数据库同一次会话期间查询到的数据会放在本地缓存中。
  • 以后如果需要获取相同的数据,直接从缓存中拿,没必须再去查询数据库;

测试:

    @Test
    public void TestCache(){
        Student student = studenDao.GetStudentById(4);
        System.out.println("cache========= = cache");
        Student student1 = studenDao.GetStudentById(4);

        System.out.println("student==student1 = " +(student == student1));
    }
    

查看日志

在这里插入图片描述

一级缓存Mybatis是默认开启的

一级缓存缓存失败的四种情况:

一级缓存是SqlSession级别的缓存,是一直开启的,我们关闭不了它;

一级缓存失效情况:没有使用到当前的一级缓存,效果就是,还需要再向数据库中发起一次查询请求!

  1. Sqlsession不同
    1. 每个sqlsession中的缓存相互独立
  2. Sqlsession相同,查询条件不同
    1. 缓存不一样,数据不一样,找不到缓存。
  3. Sqlsession相同,两次查询之间执行了增删操作
    1. 因为增删操作可能会对当前数据产生影响
  4. Sqlsession相同,手动清除一级缓存
    1. 一级缓存就是一个map(debug的时候可以发现,里面有方法的缓存)

二级缓存

二级缓存需要手动开启(Namespaces)级别

所有的实体类先实现序列化接口(将实体类存在本地,也是使用map储存)

  1. 在MapperConfig开启
<setting name="cacheEnabled" value="true"/>
  1. 在相对于的mapper文件中开启缓存

    <?xml version="1.0" encoding="UTF-8"?>
    <ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
            xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"
            updateCheck="false">
       <!--
          diskStore:为缓存路径,ehcache分为内存和磁盘两级,此属性定义磁盘的缓存位置。参数解释如下:
          user.home – 用户主目录
          user.dir – 用户当前工作目录
          java.io.tmpdir – 默认临时文件路径
        -->
       <diskStore path="./tmpdir/Tmp_EhCache"/>
       
         <!--
          defaultCache:默认缓存策略,当ehcache找不到定义的缓存时,则使用这个缓存策略。只能定义一个。
        -->
       <defaultCache
               eternal="false"
               maxElementsInMemory="10000"
               overflowToDisk="false"
               diskPersistent="false"
               timeToIdleSeconds="1800"
               timeToLiveSeconds="259200"
               memoryStoreEvictionPolicy="LRU"/>
    		 <!--  开启缓存-->
       <cache
               name="cloud_user"
               eternal="false"
               maxElementsInMemory="5000"
               overflowToDisk="false"
               diskPersistent="false"
               timeToIdleSeconds="1800"
               timeToLiveSeconds="1800"
               memoryStoreEvictionPolicy="LRU"/>
      
       <!--
         name:缓存名称。
         maxElementsInMemory:缓存最大数目
         maxElementsOnDisk:硬盘最大缓存个数。
         eternal:对象是否永久有效,一但设置了,timeout将不起作用。
         overflowToDisk:是否保存到磁盘,当系统当机时
         timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
         timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
         diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
         diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
         diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
         memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
         clearOnFlush:内存数量最大时是否清除。
         memoryStoreEvictionPolicy:可选策略有:LRU(最近最少使用,默认策略)、FIFO(先进先出)、LFU(最少访问次数)。
         FIFO,first in first out,这个是大家最熟的,先进先出。
         LFU, Less Frequently Used,就是上面例子中使用的策略,直白一点就是讲一直以来最少被使用的。如上面所讲,缓存的元素有一个hit属性,hit值最小的将会被清出缓存。
         LRU,Least Recently Used,最近最少使用的,缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存。
      -->
    
    </ehcache>
    

    测试:

在这里插入图片描述

二级缓存默认会在insert;update;delete;操作后刷新缓存;可以手动不刷新缓存
在这里插入图片描述

总结:

在这里插入图片描述

分页

分页插件

1.jar

   <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.10</version>
        </dependency>

2.MapperConfig.xml

配置插件

    <plugins>
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <property name="param1" value="value1"/>
        </plugin>
    </plugins>

3.使用:
在这里插入图片描述

Limit


    List<Student> getListStudentLimit(Map<String,Integer> map);

Mapper.xml

<select id="getListStudentLimit" resultMap="StudentMap">
         select * from user limit #{startIndex},#{PageSize}
    </select>

在这里插入图片描述

防止出现src下面的mapper文件编译不出来

<!--  防止src下面的xml文件编译不到-->
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
  </build>

Mybatis中的四大对象

Excutor

Mybatis中的执行器,用于CURD

StatementHandel

处理数据库对象用于执行SQL

ResultSetHandel

处理SQL返回的结果集

ParamenterHandel

dentLimit" resultMap=“StudentMap”>
select * from user limit #{startIndex},#{PageSize}


[外链图片转存中...(img-nrW3LkPp-1631536799155)]

# 防止出现src下面的mapper文件编译不出来

```xml
<!--  防止src下面的xml文件编译不到-->
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <include>**/*.xml</include>
        </includes>
      </resource>
    </resources>
  </build>
```

# Mybatis中的四大对象

## Excutor

Mybatis中的执行器,用于CURD

## StatementHandel

处理数据库对象用于执行SQL

## ResultSetHandel

处理SQL返回的结果集

## ParamenterHandel

用户处理SQL参数对象
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值