Mybatis 学习笔记

1.什么是Mybatis

   orm 框架;
   支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架;
  避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集;
  可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
2.Mybatis 功能架构
   API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
   数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
   基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑
3.Mybatis 核心组件
     SqlSessionFactoryBuilder(构造器). 它会根据代码或者配置来生成SqlSessionFactory,采用的是分布构建的builder模式
     SqlSessionFactory(工厂接口).  它可以生成SqlSession,采用的是工厂模式
     SqlSession(会话). 它可以发送SQL语句返回结果,也可以获取Mapper接口
     SQL Mapper(映射器).  它由一个Java接口和一个XML文件(或注解)构成,需要给出对应的SQL和映射规则,它可以发送SQL并返回结果
4.Mybatis  SqlSessionFactory构建
   基础配置文件,用来构建上下文环境 mybatis-config.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"/>
    
    <!--为实体类配置别名-->
    <typeAliases>
        <typeAlias type="com.mybatisdemo.pojo.User" alias="user"/>
        <typeAlias type="com.mybatisdemo.pojo.Role" alias="role"/>
    </typeAliases>
    
    <!--数据库的描述信息-->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据库,POOLED表示这里使用了连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>
    
    <!--引入映射器-->
    <mappers>
        <mapper resource="mappings/UserMapper.xml"/>
        <mapper resource="mappings/RoleMapper.xml" />
    </mappers>
</configuration>

生成SqlSessionFactory

// 生成SqlSessionFactory实例,采用单例模式
public class SqlSessionFactoryUtil {
    
    private static SqlSessionFactory sqlSessionFactory = null;
    private static String resource = "mybatis-config.xml";
    
    private SqlSessionFactoryUtil(){
        
    }
    
    public static SqlSessionFactory getSqlSessionFactory(){
        if(sqlSessionFactory == null){
            try {
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream(resource)); 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return sqlSessionFactory;
    }
}

将配置文件mybatis-config.xml文件用流的方式读取,然后通过SqlSessionFactoryBuilder的builder方法去生成SqlSessionFactory就可以了

5.Mybatis 获取SqlSession

    

 

 注意:sqlSession在使用完之后要及时关闭,以免浪费连接资源

6.Mybatis  映射

   1)xml方式:

       映射器接口:  

public interface UserMapper {
    // 根据id查找用户
    User getUserById(long id);
    // 根据用户名查找用户
    List<User> getUserByName(String userName);
}

     创建映射器:

<?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.mybatisdemo.mapper.UserMapper">
     <resultMap id="userMap" type="user">
        <id property="userId" column="user_id"/>
        <result property="userName" column="user_name"/>
        <result property="password" column="password"/>
        <result property="realName" column="real_name"/>
        <result property="sex" column="sex" typeHandler="org.apache.ibatis.type.EnumOrdinalTypeHandler"/>
        <result property="userImg" column="user_img" typeHandler="org.apache.ibatis.type.BlobInputStreamTypeHandler"/>
        <result property="roleId" column="role_id"/>
    </resultMap>
    <select id="getUserById" parameterType="long" resultMap="userMap">
        select * from t_user where user_id=#{id}
    </select>
 
    <select id="getUserByName" parameterType="string" resultMap="userMap">
        select * from t_user where user_name like concat('%',#{userName},'%')
    </select>
</mapper>

    SqlSession获取映射器:

public void test(){
    SqlSession sqlSession = SqlSessionFactoryUtil.getSqlSession();
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User user = userMapper.getUserById(1L);
    sqlSession.close();
}

    2)注解形式:  

public interface UserMapper {
    // 根据id查找用户
    @Select("select * from t_user where user_id=#{id}")
    User getUserById(long id);
}

7.Mybatis Sql语句中 #{} ${}

    #{}是预编译处理  #在底层会转换为 jdbc 中使用 PreparedStatement 时?预编译

    ${}是字符串替换  $转换为 Statement 的字符串拼接

    注意:#{} 可以防止 SQL 注入漏洞,提高安全性。${}不能
8.Mybatis  Sql语句模糊查询

 

   SELECT * FROM t_usr WHERE name like '%${name}%'

   SELECT * FROM t_usr WHERE name like CONCAT('%',#{name},'%'))

9.Mybatis 缓存技术

   在没有配置的默认情况下,它只支持一级缓存(一级缓存只相对于同一个 SqlSession 而言)。

  1)一级缓存:使用了 HashMap 的存储方式,key 为 hashCode+sqlid+SQL 语句,value 为从查询出来映射的 java 对象。每次使用同一个 SqlSession 发起请求时,检查 sql 语句是否已经存在,如果存在则从缓存中返回映射的 java 对象,所以多次查询同一条 sql语句避免访问多次数据库;在BaseExecutor中实现

  2)二级缓存:SqlSessionFactory 的缓存,默认不开启。如果要开启需要在 xxx.mapper.xml 中配置。mybatis 要求返回的 POJO 对象必须是可序列化的(实现 Serializable 接口);在CachingExecutor中实现

    

 

   注意:  eviction:缓存回收策略

10.Mybatis 映射文件的常用标签

 

 

11.Mybatis  获取自动生成的主键(id) 

    insert 方法总是返回一个 int 值 ,这个值代表的是插入的行数。
   如果采用自增长策略,自动生成的键值在 insert 方法执行完后可以被设置到传入的参数对象中。
<insert id=”insertname” usegeneratedkeys=”true” keyproperty=”id”>
 insert into names (name) values (#{name})
</insert>

12.Mybatis 映射文件中namespace标签

   在 MyBatis 中,可以为每个映射文件起一个唯一的命名空间,这样定义在这个映射文件中的每个 SQL 语句就成了定义在这个命名空间中的一个 ID。只要我们能够保证每个命名空间中这个 ID 是唯一的,即使在不同映射文件中的语句 ID 相同,也不会再产生冲突了
  在开发中一般命名空间指向操作的接口详细位置。 
13.Mybatis 参数传递
   1)正常传递
 Actor selectActorById(Long id);
 <select id="selectActorById"  resultType="canger.study.chapter04.bean.Actor">
        select actor_id as id, first_name as firstName ,last_name as lastName from acto where actor_id=#{abc}
 </select>
Actor actor = mapper.selectActorById(1L)

 2)@Param

Boolean insertActorByParamString(@Param("firstName")String var1, @Param("lastName")String var2);
 <insert id="insertActorByParamString">
        insert into actor(first_name,last_name) values (#{firstName},#{lastName})
    </insert>
 Boolean result = mapper.insertActorByParamString("James", "Harden");
    System.out.println(result)

14.Mybatis 多表操作

  1)一对多

  2)多对一

    

14.Mybatis 是否支持延迟加载

     Mybatis 仅支持 association 关联对象和 collection 关联集合对象的延迟加载
     原理:使用 CGLIB 创建目标对象的代理对象,当调用目标方法时,进入拦截器方法,比如调用 a.getB().getName(),拦截器 invoke()方法发现 a.getB()是 null 值,那么就会单独发送事先保存好的查询关联 B 对象的 sql,把 B 查询上来,然后调用a.setB(b),于是 a 的对象 b 属性就有值了,接着完成 a.getB().getName()方法的调用。

 15.Mybatis 执行器(executor)

 

 

posted @ 2020-03-10 16:23  Jaine  阅读(158)  评论(0编辑  收藏  举报