Mybatis的学习笔记,比较基础

Mybatis学习笔记

简介

什么是Mybatis?

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

持久层

数据持久化

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过程
  • 内存:断电即失
  • 数据库,io文件持久化
    为什么需要持久化?
  • 有一些对象,不能让他丢失
  • 内存太贵

持久层

Dao层,Service层,Controller层

  • 完成持久化工作的代码块
  • 层次很明显

为什么需要Mybatis?

  • 传统的JDBC代码太复杂了,框架就是简化操作的

  • __hibernate__处理复杂业务时,灵活度差,复杂的HQL难写难理解,例如多表查询的HQL语句

  • spring的__JdbcTemplete__就是jdbc的封装,类似dbutils没什么特别的

  • 不用Mybatis也可以。更容易上手

  • Mybatis的优点

    • 简单易学
    • 灵活
    • 解除sql与程序代码的耦合
    • 映射标签
    • 提供xml标签

第一个Mybatis程序

搭建环境

建表

CREATE TABLE USER ( 
uid INT PRIMARY KEY auto_increment, 
username VARCHAR ( 50 ), 
PASSWORD VARCHAR ( 50 ) 
) ENGINE = INNODB DEFAULT CHARSET = utf8;
INSERT INTO USER ( username, PASSWORD )
VALUES
	( "root", "111111" ),
	( "admin", "222222" );
  • 新建maven项目
  • 删除src文件,作为父工程
  • 配置pom.xml
  <dependency>
      <!--      mybatis-->
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.4</version>
    </dependency>
    <!--    junit测试-->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
    </dependency>
    <!--    mysql驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.40</version>
    </dependency>
  • 创建一个模块

创建一个模块

  • 创建mybatis核心配置文件
<?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">
<!--mybatis的核心配置文件-->
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager type="JDBC"/>
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url"
          value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;userUnicode=true&amp;characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="761020zy"/>
      </dataSource>
    </environment>
  </environments>
</configuration>
  • 建立工具类
//sqlSessionFactory-->sqlSession
public class MybatisUtils {

  private static SqlSessionFactory sqlSessionFactory;

  static {
    String resource = "mybatis-config.xml";
    InputStream inputStream = null;
    try {
      //使用Mybatis第一步:获取sqlSessionFactory对象
      inputStream = Resources.getResourceAsStream(resource);
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

  //  既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
//  SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
  public static SqlSession getSqlSession() {
    return sqlSessionFactory.openSession();
  }
}

编写代码

  • 实体类

    public class User {
    
      private int uid;
      private String username;
      private String password;
    
      public User() {
    
      }
    
      public User(int uid, String username, String password) {
        this.uid = uid;
        this.username = username;
        this.password = password;
      }
    
      public int getUid() {
        return uid;
      }
    
      public void setUid(int uid) {
        this.uid = uid;
      }
    
      public String getUsername() {
        return username;
      }
    
      public void setUsername(String username) {
        this.username = username;
      }
    
      public String getPassword() {
        return password;
      }
    
      public void setPassword(String password) {
        this.password = password;
      }
    }
    
    
  • Dao接口

    public interface UserDao {
      List<User> getUserList();
    
    }
    
    
  • 接口实体类转化为Mapper配置文件(UserMapper.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">
<!--namsspace绑定一个对应的Dao/Mapper接口-->
<mapper namespace="cn.itcast.dao.UserDao">
  <select id="getUserList" resultType="cn.itcast.domain.User">
    # 查询语句
    select *
    from mybatis.user;
  </select>
</mapper>
  • 测试

    • 报错:org.apache.ibatis.binding.BindingException: Type interface cn.itcast.dao.UserDao is not known to the MapperRegistry.
  • 原因:Mapper文件没有引入mybatis的核心文件

    • 解决:在mybatis引入Mapper文件
    • 报错:java.lang.ExceptionInInitializerError
    • 原因:资源过滤问题
  • 解决:放在resources下或者配置pom文件让idea可以加载java下面的配置文件

      @Test
      public void test01() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List<User> list = userDao.getUserList();
        for (User user : list) {
          System.out.println(user.toString());
        }
    //关闭sqlSession
        sqlSession.close();
      }
    

Mybatis中的事务是默认开启的,因此我们在完成操作以后,需要我们手动去提交事务!

测试结果

简单CRUD

1、namespace

namespace中的包名要和Dao/mapper接口的包名一致!

2、select

选择,查询语句;

  • id:namespace中的唯一标识符就是方法名
  • resultType:sql语句执行的返回值!
  • parameterType:参数类型,方法中传的参数

3、insert

 <!--  插入-->
  <insert id="addUser" parameterType="cn.itcast.domain.User">
    insert into mybatis.user(uid, username, password)
    values (#{uid}, #{username}, #{password})
  </insert>

4、update

<update id="updateUser" parameterType="cn.itcast.domain.User">
    update mybatis.user
    set username=#{username},
        password=#{password}
    where uid = #{uid}
  </update>

5、delete

 <delete id="deleteUser" parameterType="Integer">
    delete
    from mybatis.user
    where uid = #{uid};
  </delete>

注意点:

  • 增删改需要提交事务!

万能的Map

假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map!

Map传递参数,直接在ssql中取出key即可!

对象传递参数,直接在sql中取对象的属性即可!

只有一个基本参数,直接在sql中取到即可

多个参数用Map,或者__注解__

配置解析

核心配置文件

  • mybatis-config.xml

  • mybatis的配置文件包含了影响mybatis行为的设置和属性信息

    • configuration(设置)
    • properties(属性)
    • settings(设置)
    • typeAliases(类型别名)
    • typeHandlers(类型处理器)
    • objectFactory(对象工厂)
    • plugins(插件)
    • environments(环境配置)
    • environment(环境变量)
    • transactionManager(事务管理器)
    • dataSource(数据源)
    • databaseIdProvider(数据库库厂标识)
    • mappers(映射器)

环境变量(enevirnments)

Mybatis可以配置多个环境

但是sqlSessionFactory实例只能选择__一种环境__

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

属性(properties)

  • 可以直接引入外部文件

  • 可以在其中增加一些属性配置

  • 如果两个文件有同一个字段,优先使用外部配置文件

  <properties resource="db.properties"/>

类型别名

  • 给java设置一个短的名字,他只和XML配置相关

  • 减少类全限定名的冗余

    <typeAliases >
      <typeAlias type="cn.itcast.domain。User" alias="User"/>
    </typeAliases>

实例类比较少的时候使用,alias可以是任意值

<typeAliases >
  <typeAlias type="cn.itcast.domain.User" />
</typeAliases>

实体类较多的时候使用,默认名称就是这个包下面类的类名,但是注意了__首字母要小写__,如果要改就要加在实体类前面加一个注解@Alias(“你要取的名称”)

映射器(mappers)

注册绑定我们的Mapper文件

resource

  <mappers>
    <mapper resource="UserMapper.xml"/>
  </mappers>

class

  <mappers>
    <mapper class="cn.itcast.dao.UserDao"/>
  </mappers>

注意:

  • 接口和Mapper配置文件必须同名
  • 接口和Mapper配置文件必须在用一个包下

package

  <mappers>
    <package name="cn.itcast.dao"/>
  </mappers>

注意:

  • 接口和Mapper配置文件必须同名
  • 接口和Mapper配置文件必须在用一个包下

生命周期和作用域

  • SqlSessionFactoryBuilder:

    • 一旦创建了sqlSessionFactory,就不需要它了
    • 局部变量
  • SqlSessionFactory:

    • 一旦创建就应该一直存在,没有理由丢其他或者重新创建另一个实例
    • 最简单就是使用单例或者静态单例模式
  • SqlSession

    • SqlSession的实例不是线程安全的,不能被共享
    • 用完要关闭

解决属性名和字段名不一致的问题

问题

<select id="getUserList" resultType="User">
    select uid,username,password as pwd
    from mybatis.user;
  </select>

解决方法

  • 起别名,让实体类属性的名称和数据库字段名称一致

  • resultMap=""(使用结果集映射)

结果集映射resultMap

和hibernate的xxx.hbm.xml差不多,都是建立对象和表的一个映射关系

<mapper namespace="cn.itcast.dao.UserDao">
  <resultMap id="UserMap" type="User">
    <result property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="password" column="password"/>
  </resultMap>
     <!--  显示全部-->
  <select id="getUserList" resultType="User" resultMap="UserMap">
    select uid,username,password
    from mybatis.user;
  </select>
  • resultMap元素是Mybatis中最强大的元素
  • 对于简单的语句,如果能和实体类属性对应起来就不用结果映射,对于复杂的语句就要建立映射了

日志

日志工厂

数据库操作出现异常,我们需要排错,所以我们需要日志

  • SLF4J
  • LOG4J
  • NO_LOGGING
  • STDOUT_LOGGING(标准日志输出)

在Mybatis中具体使用哪个日志实现,在设置中设定

 <!--  日志-->
  <settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
  </settings>

控制台会打印很多日志信息

log4j

  • 导入Log4j的maven
<dependency>
  <groupId>log4j</groupId>
  <artifactId>log4j</artifactId>
  <version>1.2.17</version>
</dependency>
  • 编写log4j的配置文件
log4j.rootLogger=DEBUG,console

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.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
  • 测试
 //Log4j测试
  @Test
  public void test07() {
    logger.info("info:进入Log4j");
    logger.debug("debug:进入Log4j");
    logger.error("error:进入Log4j");
  }

分页

为什么使用分页技术?

  • 减少数据的处理量

注意:我们的分页是需要多个参数的,并不是像我们之前的例子中只有一个参数。当需要接收多个参数的时候,我们使用Map集合来装载

  <select id="getUserByLimit" parameterType="map" resultType="user">
    select *
    from mybatis.user
    limit ${startIndex},${pageSize}
  </select>
 @Test
  public void test08() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
//    方式一:
    try {
      UserDao userDao = sqlSession.getMapper(UserDao.class);
      Map<String, Integer> map = new HashMap<String, Integer>();
      map.put("startIndex", 1);
      map.put("pageSize", 2);
      List<User> list = userDao.getUserByLimit(map);
      for (User user : list) {
        System.out.println(user.toString());
      }
    } finally {
      //关闭sqlSession
      sqlSession.close();
    }
  }

注解开发

注解开发

 //  获取全部用户
  @Select("select * from mybatis.user")
  List<User> getUserList();
  <mappers>
    <mapper class="cn.itcast.dao.UserDao"/>
  </mappers>
  • 本质:反射机制
  • 底层:动态代理

mybatis执行原理

  //  根据ID查询用户
  @Select("select * from mybatis.user where uid=${id}")
  User getUserById(@Param("id") Integer id);
  //  insert一个用户
  @Insert("insert into mybatis.user(username,password) values(#{username},#{password})")
  Integer addUser(User user);

关于@Param()注解

  • 基本类型的参数或者String类型,需要加上
  • 引用类型不需要加
  • 如果只有一个基本类型,可以省略,但是建议大家都加上
  • 我们在SQL中引用的就是我们这里的@Param(“uid”)中设定的属性名

#{}和${}

#{}可以防止sql注入

多对一

  • 多个学生对应一个老师
  • 多个学生关联一个老师【多对一】
  • 一个老师集合多个学生【一对多】

建表

create table teacher(
teacherId int not null primary key auto_increment,
teacherName varchar(30) not null
)engine=innodb default charset=utf8;
create table student(
studentId int primary key ,
studentName varchar(30) not null,
teacherId int,
CONSTRAINT t_s_fk foreign key (teacherId) references teacher(teacherId)
)engine=innodb default charset=utf8;

实体类

package cn.itcast.pojo;

public class Student {

  private Integer id;
  private String name;
  private Teacher teacher;

 Getter and Setter...
     
  @Override
  public String toString() {
    return "Student{" +
        "id=" + id +
        ", name='" + name + '\'' +
        ", teacher=" + teacher +
        '}';
  }
}

package cn.itcast.pojo;

public class Teacher {

  private Integer id;
  private String name;

Getter and Setter...

  @Override
  public String toString() {
    return "Teacher{" +
        "id=" + id +
        ", name='" + name + '\'' +
        '}';
  }
}

public interface StudentMapper {

  public List<Student> getStudent();

  public Teacher getTeacher(Integer id);
}

按照查询嵌套处理

  <select id="getStudent" resultType="Student" resultMap="StudentMap">
    select *
    from student;
  </select>

  <resultMap id="StudentMap" type="Student">
    <!--    主键-->
    <id property="id" column="studentId"/>
    <!--    普通属性-->
    <result property="name" column="studentName"/>
    <!--    对象使用association-->
    <!--    集合使用Collection-->
    <association property="teacher" column="teacherId" javaType="Teacher" select="getTeacher"/>
  </resultMap>

  <select id="getTeacher" resultType="Teacher" resultMap="TeacherMap">
    select *
    from teacher
    where teacherId = #{id}
  </select>
  <resultMap id="TeacherMap" type="Teacher">
    <id property="id" column="teacherId"/>
    <result property="name" column="teacherName"/>
  </resultMap>

按照结果嵌套处理

 <select id="getStudent" resultMap="StudentMap">
    select studentId,studentName,student.teacherId,teacherName
    from student
           inner join teacher on student.teacherId = teacher.teacherId;
  </select>

  <resultMap id="StudentMap" type="Student">
    <id column="studentId" property="id"/>
    <result column="studentName" property="name" />
    <association property="teacher" javaType="Teacher">
      <id property="id" column="teacherId"/>
      <result property="name" column="teacherName"/>
    </association>
  </resultMap>

mysql多对一查询:

  • 子查询
  • 连接查询

一对多

按照结果嵌套处理

  <select id="getTeacher" resultType="Teacher" resultMap="TeacherMap">
    select *
    from mybatis.teacher;
  </select>
  <resultMap id="TeacherMap" type="Teacher">
    <id property="id" column="teacherId"/>
    <result property="name" column="teacherName"/>
    <collection property="studentList" column="teacherId" javaType="ArrayList" ofType="Student" select="getStudentById"/>
  </resultMap>

  <select id="getStudentById" resultType="Student" resultMap="StudentMap">
    select *
    from mybatis.student
    where tid = #{tid}
  </select>
  <resultMap id="StudentMap" type="Student">
    <id column="studentId" property="id"/>
    <result column="studentName" property="name"/>
  </resultMap>

按照查询嵌套处理

<select id="getTeacher" resultType="Teacher" resultMap="TeacherMap">
      select *
      from teacher
             left join student on teacher.teacherId = student.tid;
    </select>
    <resultMap id="TeacherMap" type="Teacher">
      <id property="id" column="teacherId"/>
      <result property="name" column="teacherName"/>
      <collection property="studentList" ofType="Student">
        <id property="id" column="studentId"/>
        <result property="name" column="studentName"/>
      </collection>
    </resultMap>

小结

  • javaType和ofType的区别
  • 保证sql的可读性,保证通俗易懂
  • 属性名和字段的问题
  • 使用好log4j日志

提高sql查询速度

  • mysql引擎
  • innoDB底层原理
  • 索引
  • 索引优化

动态SQL

什么是动态SQL:动态SQL就是根据不同的条件生成不同的SQL语句**【动态SQL就是自动拼接SQL语句】**!

if

List<Blog> queryBlog(Map map);
  <select id="queryBlog" parameterType="map" resultType="blog">
    select *
    from mybatis.blog where 1=1
    <if test="title!=null">
      and title=#{title}
    </if>
  </select>
 @Test
  public void test02() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    map.put("title", "正则表达式");
    List<Blog> list = blogMapper.queryBlog(map);
    for (Blog blog : list) {
      System.out.println(blog.toString());
    }
    sqlSession.commit();
    sqlSession.close();
  }

choose,where,otherwise

  • where+if
<select id="queryBlog" parameterType="map" resultType="blog">
    select *
    from mybatis.blog
    <where>
      <if test="title!=null">
        title=#{title}
      </if>
      <if test="author!=null">
        and author=#{author}
      </if>
      <if test="views!=null">
        and views=#{views}
      </if>
    </where>
  </select>
@Test
  public void test02() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
    HashMap map = new HashMap();
    map.put("views", "125");
    map.put("author","小赵");
    List<Blog> list = blogMapper.queryBlog(map);
    for (Blog blog : list) {
      System.out.println(blog.toString());
    }
    sqlSession.commit();
    sqlSession.close();
  }

where+choose(when+otherwise)类似于java的switch+case

  <select id="queryBlog" parameterType="map" resultType="blog">
    select *
    from mybatis.blog
    <where>
      <choose>
        <when test="author!=null">
          author=#{author}
        </when>
        <when test="views!=null">
          and views=#{views}
        </when>
        <otherwise>
          and title=#{title}
        </otherwise>
      </choose>
    </where>
  </select>

set+if

 <set>
      <if test="title!=null">
        title=#{title},
      </if>
      <if test="author!=null">
        author=#{author}
      </if>
    </set>
 @Test
  public void test05() {
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("id","8");
    map.put("author","大佬");
    Integer integer = blogMapper.updateBlog(map);
    System.out.println(integer);
    sqlSession.commit();
    sqlSession.close();
  }

trim

可以做set和when的事情

sql片段

  • 有时候,我们会将一些公共的sql抽取出来,然后服用
<sql id="update">
    <if test="title!=null">
      title=#{title},
    </if>
    <if test="author!=null">
      author=#{author}
    </if>
  </sql>
  <update id="updateBlog" parameterType="map">
    update mybatis.blog
    <set>
      <include refid="update"/>
    </set>
    where id=#{id}
  </update>
  • 最好基于单表定义SQL片段
  • 不要存在where标签

foreach

  <select id="queryBlogForeach" parameterType="map" resultType="blog">
    select * from mybatis.blog
    <where>
      <foreach collection="ids" item="id" open="and (" close=")" separator="or">
        id=#{id}
      </foreach>
    </where>
  </select>
  • 动态sql就是在拼接sql语句

Mybatis缓存

  • 查询:连接数据库,耗资源

  • 一次查询的结果,给他暂存一个可以直接取到的地方!–>内存:缓存

  • 我们再次查询相同数据的时候,直接走缓存,就不用走数据库了

  • 什么是缓存?

    • 存在内存中的临时数据
    • 将用户经常查询的数据放在缓存(内存)中,哟用户去查询数据就不用从磁盘中就是数据库中查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。
  • 为什么使用缓存?

    • 减少和数据库的交互次数,减少系统开销,提高系统效率
  • 什么样的数据能使用缓存?

    • 经常查询并且不经常修改的数据
  • mybatis定义了两级缓存:_一级缓存__和__二级缓存

一级缓存

sqlsession级别的缓存

在同一次会话期间查询的数据会放在本地缓存中,需要同样的数据,直接从缓存中拿,没必要再去查数据库

  • 缓存失效:
    • 手动清理缓存clearcache
    • 查询不同的东西
    • 增删改查操作之后,会改变原来的数据,所以必定会刷新缓存
    • 查询不同的Mapper.xml

二级缓存

会话关闭一级缓存就没了,一级缓存中的数据被保存到二级缓存中

<!--    开启全局缓存-->
    <setting name="cacheEnabled" value="true"/>
  <!--  开启二级缓存-->
  <cache/>

自定义缓存

<cache
    eviction="FIFO"
    flushInterval="60000"
    size="512"
    readOnly="true"/>

注意:实体类需要序列化

  • 小结
    • 只要开启了二级缓存,在同一个Mapper下就有效
    • 所有的数据都会先放在一级缓存中
    • 只有当会话提交,或者关闭的时候,才会提交到二级缓存

总结

  • 在Mybatis中,有两种占位符

    • #{}解析传递进来的参数数据
    • ${}对传递进来的参数原样拼接在SQL中
  • 如果我们在Hibernate中,当我们插入数据的时候,我们是可以选择是UUID策略的,那么在Mybatis是怎么做的呢??

    <!-- mysql的uuid生成主键 -->
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <selectKey keyProperty="id" order="BEFORE" resultType="string">
            select uuid()
        </selectKey>
        INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
    </insert> 
  • user对象插入到数据库后,新记录的主键要如何通过user对象返回
    <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select LAST_INSERT_ID()
        </selectKey>
        INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
    </insert>
  • resultMap和resultType区别
    • 指定输出结果的类型(pojo、简单类型、hashmap…),将sql查询结果映射为java对象,sql查询的__列名__要和resultType指定pojo的__属性名相同__,指定相同 属性方可映射成功
    • resultMap:将sql查询结果映射为java对象,如果sql查询列名和最终要映射的pojo的属性名不一致**,使用resultMap将列名和pojo的属性名做一个对应关系**
  • association和collection
    • association:将关联查询信息映射到一个pojo类中。【多的一方】
    • collection:将关联查询信息映射到一个list集合中。【一的一方】
  • 延迟加载
    • lazyLoadingEnabled:全局懒加载
    • aggressiveLazyLoading:按需加载
  • 在程序中调用的__SQL语句__是由映射文件的__命令空间(namespace)+sql片段的id__所组成的。它内部会生成一个Statement对象的。
  • 缓存
    • 一级缓存:一级缓存是一个__sqlsession__级别,sqlsession只能访问自己的一级缓存的数据
    • 二级缓存:跨sqlSession,是__mapper级别__的缓存,对于mapper级别的缓存__不同的sqlsession__是可以__共享__的
  • 缓存注意
    • Mybatis默认就是支持一级缓存的,并不需要我们配置
    • mybatis和spring整合后,不支持一级缓存,spring按照mapper的模板去生成mapper代理对象,模板中在最后__统一关闭sqlsession__
  • 为什么增删改查的时候,缓存默认就会被清空?
    • 缓存保存了__增删改后的数据__,那么再次读取时就会读到__脏数据__了!

LAST_INSERT_ID()

INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})


*  resultMap和resultType区别
    * 指定输出结果的类型(pojo、简单类型、hashmap..),将sql查询结果映射为java对象,sql查询的__列名__要和resultType指定pojo的__属性名相同__,指定相同 属性方可映射成功
    * resultMap:将sql查询结果映射为java对象,如果sql查询列名和最终要映射的pojo的属性名不一致**,使用resultMap将列名和pojo的属性名做一个对应关系** 
* association和collection
    *  association:**将关联查询信息映射到一个pojo类中。**【多的一方】
    *  collection:**将关联查询信息映射到一个list集合中。**【一的一方】
*  延迟加载
    * lazyLoadingEnabled:全局懒加载
    * aggressiveLazyLoading:按需加载
*  在程序中调用的__SQL语句__是由映射文件的__命令空间(namespace)+sql片段的id__所组成的。它内部会生成一个Statement对象的。
* 缓存
    * 一级缓存:一级缓存是一个__sqlsession__级别,sqlsession只能访问自己的一级缓存的数据
    * 二级缓存:跨sqlSession,是__mapper级别__的缓存,对于mapper级别的缓存__不同的sqlsession__是可以__共享__的
*  缓存注意
    *  Mybatis默认就是支持一级缓存的,并不需要我们配置
    *  mybatis和spring整合后,不支持一级缓存,spring按照mapper的模板去生成mapper代理对象,模板中在最后__统一关闭sqlsession__
*  为什么增删改查的时候,缓存默认就会被清空?
    *  缓存保存了__增删改后的数据__,那么再次读取时就会读到__脏数据__了!

































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员小赵OvO

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值