mybatis从头学到jio(二)

前情回顾

mybatis从头学到jio(一)

这里写目录标题

    • 前情回顾
      • ${} 与 #{}区别
        • #{}
        • ${}
      • typeAliases标签
    • 动态SQL
      • if标签
      • trim标签
      • where标签
      • foreach标签
      • 模糊匹配
        • 直接传入%s%
        • 使用concat方法
        • 使用bind标签
    • 缓存机制
      • 一级缓存
      • 二级缓存
    • 高级映射
      • 一对一
      • 一对多
    • 延时加载
    • 注解
      • select
      • update
      • insert
      • delete
      • 一对一映射

${} 与 #{}区别

#{}

@Select("select * from Student where SID=#{sid}")
public Student getStudentBySID(int sid);

Preparing: select * from Student where SID=? 
Parameters: 2(Integer)

#{}处理方式类似于preparedStatement参数的操作将占位符替换为 ?,使用的参数必须提供了getter,将SQL语句和参数值分开传到服务器.
优点:不存在SQL注入的问题

${}

	@Select("select * from Student where SID=${SID}")
    public Student getStudentBySID(Student student);
    
	Preparing: select * from Student where SID=1 
	Parameters:

${}类似于jdbc中statement直接将参数拼接到SQL语句之中
缺点:存在SQL注入的问题

typeAliases标签

Tip:typeAliases在mybatis-config.xml中配置(主配置文件)

    
    <typeAliases>
        
        <typeAlias type="com.tulun.MybatisDemo.Student" alias="student"/>

        
        <package name="com.tulun.pojo"/>
    typeAliases>

业务场景:极大的简化了配置文件的编写,当工作量比较大的时候可以配置resultType和parameterType Windows中别名可以不关注大小写。

动态SQL

if标签

<select id="selectStudent" resultType="com.bean.student">
        select * from student where 1=1
        <if test="Sage != 0">
            and Sage = #{Sage}
        if>
select>

使用log4j.properties可以看见一下结果

假如传两个参数 :select * from Student where 1=1 and Sage = #{Sage} and Ssex = #{Ssex}
假如传一个参数:select * from Student where 1=1 and Sage = #{Sage}
## debug 级别
log4j.rootLogger=DEBUG,Console  
log4j.appender.Console=org.apache.log4j.ConsoleAppender  
log4j.appender.Console.Target=System.out  
log4j.appender.Console.layout = org.apache.log4j.PatternLayout  
log4j.appender.Console.layout.ConversionPattern=%d{yyyy-MM-dd-HH\:mm\:ss,SSS} [%t]  [%c] [%p] - %m%n  
log4j.logger.com.mybatis=DEBUG  /  

##输出sql 语句
log4j.logger.java.sql.Connection=DEBUG  
log4j.logger.java.sql.Statement=DEBUG  
log4j.logger.java.sql.PreparedStatement=DEBUG 

trim标签

trim标签作用取出SQL中多余And关键字,逗号,使用在where或者set

<select id="updateStudent" resultType="com.conn.student">
        update student
        <trim prefix="set" suffixOverrides=",">
            <if test="Sage != null">
                Sage = #{Sage},
            if>
            <if test="name != null">
                Sname = #{name},
            if>
        trim>
        where SID = #{SID}
select>
属性 描述
prefix 给SQL拼接前缀
suffix 给SQL拼接后缀
prefixOverrids 剔除SQL语句前缀字符
suffixOverrids 剔除SQL语句后缀字符

where标签

<select id="findStudent1" resultType="com.bean.student">
        select * from student
        <where>
   			Sname = #{name}         
        where>
select>

省去了多余的1 = 1的条件

foreach标签

<select id="findStudent1" resultType="com.bean.student">
        select * from student
        <where>
            <if test="list != null">
                <foreach collection="list" separator="," close=")" open="and SID in(" item="id">
                    #{id}
                foreach>
            if>
        where>
select>
属性 描述
collection 所要遍历集合的名称
separator 集合之中分割符
close 结束的字符
open 开始的字符
item 集合之中的单个字符名称

collection可以使用与List、Map、数组等等

模糊匹配

模糊匹配一共有三种方式

直接传入%s%

<select id="studentByName" resultType="com.conn.student">
        select *from student where Sname like #{name}
select>

使用concat方法

<select id="studentByName" parameterType="java.lang.String" resultType="com.conn.student">
        select *from student where Sname like concat('%',concat(#{name},'%'))
select>

使用bind标签

<select id="studentByName" resultType="com.conn.student">
        <bind name="s" value="'%'+name+'%'"/>
        select *from student where Sname like #{s}
select>

缓存机制

一级缓存

mybatis中一级缓存是不需要任何的配置,是sqlsession级别的查询
执行同一个SQL语句第一次查询对应的信息,当第二次查询的时候优先去缓存区查询对应的结果
在这里插入图片描述

这个图片可以看到第一次进行了SQL查询,第二次直接在缓存区查询

mybatis从头学到jio(二)_第1张图片
这里可以看出当对对应的数据库字段做出改变是,缓存区立马被清空,第二次查询只能继续访问数据库

mybatis从头学到jio(二)_第2张图片
不同session执行缓存不共享

二级缓存

二级缓存是mapper级别的,默认的是关闭的需要手动的开启
主配置文件配置

    <settings>
        
        <setting name="cacheEnabled" value="true"/>
    settings>

映射文件配置

    
   <cache>cache>

同一个mapper不同SQLSession下的查询可以看出共享缓存
mybatis从头学到jio(二)_第3张图片

高级映射

一对一

association:用于映射关联查询单个对象的信息

<mapper namespace="com.dao.ordersDao">
    <resultMap id="OrderUserResultMap" type="com.bean.orders" >
        
        <id column="id" property="id"/>
        <result column="user_id" property="user_id"/>
        <result column="number" property="number"/>
        <result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
        <result column="note" property="note"/>
        <association property="user" columnPrefix="u_" javaType="com.bean.user">
            
            <result column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
        association>
    resultMap>

    <select id="findAll" resultMap="OrderUserResultMap">
        select o.*,u.id u_id,u.username u_username,u.sex u_sex,u.address u_address from orders o,user u where o.user_id = u.id
    select>
mapper>

这里需要注意当SQL语句太长换行的时候在前一段末尾或下一段前面加一个空格因为在拼接字符串的时候会将两个关键词拼接在一起

使用extends关键词简化xml配置的编写

	<resultMap id="orderResultMap" type="com.bean.orders">
		
        <id column="id" property="id"/>
        <result column="user_id" property="user_id"/>
        <result column="number" property="number"/>
        <result column="date" property="date" javaType="java.util.Date" jdbcType="TIMESTAMP"/>
        <result column="note" property="note"/>
    resultMap>

    <resultMap id="userResultMap" type="com.bean.user">
        
        <result column="id" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="address" property="address"/>
    resultMap>
    <resultMap id="OrderUserResultMap" type="com.bean.orders" extends="orderResultMap">
        <association property="user" columnPrefix="u_" javaType="com.bean.user" resultMap="userResultMap">association>
    resultMap>

这里需要注意:当xml配置映射关系比较多的时候使用extends关键词可以极大节省开发时间,也可以是代码变得简洁起来,通俗说哪里需要用到直接可以使用extends关键词使用

一对多

使用collection可以将用户一对多订单映射到集合之中

	<resultMap id="userMap" type="com.bean.user" extends="userResultMap">
        <collection property="orders" columnPrefix="order_"  ofType="com.bean.orders" resultMap="orderResultMap">collection>
    resultMap>
    
    <sql id="selectId">
       u.id,
       u.username,
       u.sex,
       u.address,
       o.id order_id,
       o.user_id order_user_id,
       o.number order_number,
       o.createtime order_createtime,
       o.note order_note
    sql>

    <select id="findStudentIds" parameterType="int" resultMap="userMap">
        select <include refid="selectId"/>
        from user u ,orders o where u.id=o.user_id and u.id=#{uid};
    select>

延时加载

开启延时加载

 
<settings>
    <setting name="lazyLoadingEnabled" value="true"/>
    <setting name="aggressiveLazyLoading" value="false"/>
settings>


<mapper namespace="com.dao.ordersDao">
    
    <resultMap id="orderWithUserMap" type="com.bean.orders" extends="orderResultMap">
        
        <association property="user" javaType="com.bean.user" column="user_id" select="com.dao.userDao.findStudentIds">association>
    resultMap>
    
    <select id="findAll" resultMap="orderWithUserMap">
        SELECT * FROM orders
    select>
mapper>

这里需要注意select关联查询的已存在的方法的全路径
association中的column是接口的参数



<mapper namespace="com.dao.userDao">
    
    <select id="findStudentIds" parameterType="java.lang.Integer" resultType="com.bean.user">
        SELECT * FROM user WHERE id = #{id}
    select>
mapper>
	<mappers>
        <mapper resource="mappers/order.xml">mapper>
        <mapper resource="mappers/user.xml">mapper>
    mappers>

这里一定需要注意在配置文件之中需要两个映射文件都需要加载并且在同一个mappers标签之下。我在这个错误浪费了好多的时间,还是自己不细心。
mybatis从头学到jio(二)_第4张图片
图中拿到user_id三天记录两个1一个10分成两次去数据库查找实现了懒加载。

注解

直接装载在方法上面
优点:比较简单
缺点:SQL语句的改变就需要重新编译
注解 作用

mybatis从头学到jio(二)_第5张图片

>标签 作用
@Intsert 实现新增
@Update 实现更新
@Delete 实现删除
@Select 实现查询
@Results 实现结果集封装
@ResultMap 实现引用 @Results 定义的封装
@One 实现一对一结果集封装
@Many 实现一对多结果集封装

select

public interface StudentMapper2 {
     
    @Select("select * from Student")
    public Student getStudentBySID();
}

update

@update("update student set Sname=#{name} where SID=#{SID}")
public void updateStudent(@Param("name") String Sname,@Param("SID") int SID)

insert

 @Insert("insert into Student(SID,Sname,Sage,Ssex) values(#{SID},#{name},#{Sage},#{Ssex})")
 public int insertStudent(Student student);

delete

    @Delete("delete form student where SID={SID}")
    public void deleteStudent(int SID);

一对一映射

@Results(id = "result",value = {
     
            @Result(column = "SID",property = "SID"),
            @Result(column = "Sname",property = "name"),
            @Result(column = "Sage",property = "Sage"),
            @Result(column = "Ssex",property = "Ssex"),
            @Result(column = "score",property = "SID",one = @One(select = "com.dao.studentDao.StudentScore",fetchType = FetchType.EAGER)
    })

需要注意的是one表示的是一对一,many表示一对多是使用,fetchtype加载类型,立即加载为EAGER

以上是我对mybatis的学习如果有错误的地方欢迎大佬指正

你可能感兴趣的:(mybatis,mybatis,java,mysql)