MyBatis学习笔记

MyBatis学习笔记

quick start(XML方式配置)

  1. 导入依赖

    <dependency>  
     <groupId>org.mybatis</groupId>   
     <artifactId>mybatis</artifactId>   
     <version>3.4.5</version>  
    </dependency>   
    
  2. 创建SqlMapConfig.xml配置文件

    常用需要配置的项有:

    1.  <properties resource="" url="">
          <property name="" value=""/>
       </properties>
    
    2.  <settings>
           <setting name="" value=""/>
       </settings>
    
    3.  <typeAliases>
           <package name=""/>
           <typeAlias type="" alias=""></typeAlias>
       </typeAliases>
    
    4.  <environments default="mysql">
           <environment id="mysql">
               <transactionManager type="JDBC"></transactionManager>
               <dataSource type="POOLED">
                   <property name="driver" value="${dirver}"/>
                   <property name="url" value="${url}"/>
                   <property name="username" value="${username}"/>
                   <property name="password" value="${password}"/>
               </dataSource>
           </environment>
       </environments>
    
    5.<mappers>
           <mapper resource="com/xumu/learnMybatis/dao/IUserDao.xml"/>
           <mapper class="com.xumu.learnMybatis.dao.IUserDao"/>
           <package name="com.xumu.learnMybatis.dao"/>
       </mappers>
    
  3. 编写Dao接口的方法

  4. 配置Dao.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=""> 
     <!-- 配置查询所有操作 --> 
     <select id="" resultType="" parameterType="" resultMap="">  
         select * from user 
     </select> 
    </mapper>
    

    5.测试

    //引入配置,得到sqlSession
    InputStreamis = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory factory = factoryBuilder.build(is);
    SqlSession sqlSession = factory.openSession();
    IUserDao mapper = sqlSession.getMapper(IUserDao.class);
    //使用mapper的方法操作数据库
    

常用特性(xml配置,注解方式在后面介绍)

缓存

  • 一级缓存:SqlSession 级别的缓存,只要 SqlSession 没有 flush 或 close,它就存在。 一级缓存是 SqlSession 范围的缓存,当调用 SqlSession 的修改,添加,删除,commit(),close()等方法时,就会清空一级缓存。
  • 二级缓存: mapper 映射级别的缓存,多个 SqlSession 去操作同一个 Mapper 映射的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。

一级缓存自带,二级缓存需要开启,在xml配置中,需要三处配置:

  1. SqlMapConfig.xml中setting中开启二级缓存
<settings> 
 <!-- 开启二级缓存的支持 --> 
 <setting name="cacheEnabled" value="true"/>
</settings> 
因为 cacheEnabled 的取值默认就为 true,所以这一步可以省略不配置。为 true 代表开启二级缓存;为 false 代表不开启二级缓存。
  1. 配置相关的 Mapper 映射文件
<cache>标签表示当前这个 mapper 映射将使用二级缓存,区分的标准就看 mapper 的 namespace 值。 
<?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.itheima.dao.IUserDao"> 
    <!-- 开启二级缓存的支持 --> 
    <cache></cache> 
</mapper> 
  1. 配置 statement 上面的 useCache 属性
<!-- 根据 id 查询 --> 
<select id="findById" resultType="user" parameterType="int" useCache="true">  
    select * from user where id = #{uid} 
</select> 

将UserDao.xml映射文件中的<select>标签中设置 useCache=”true”代表当前这个 statement 要使用二级缓存,如果不使用二级缓存可以设置为 false。注意:针对每次查询都需要最新的数据 sql,要设置成 useCache=false,禁用二级缓存。 

动态SQL

  1. if标签
<select id="findByUser" resultType="user" parameterType="user"> 
    select * from user where 1=1 
    <if test="username!=null and username != '' ">  
        and username like #{username}  
    </if> 
    <if test="address != null">  
        and address like #{address}
    </if>  
 </select> 
注意:<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。 另外要注意 where 1=1 的作用~! 
  1. where标签
<!-- 根据用户信息查询 -->  
<select id="findByUser" resultType="user" parameterType="user">   
    <include refid="defaultSql"></include>   
    <where> 
        <if test="username!=null and username != '' ">     
            and username like #{username}    
        </if> 
        <if test="address != null">     
            and address like #{address}    
        </if>   
    </where>  
</select>
  1. foreach标签
<!-- 查询所有用户在 id 的集合之中 -->  
<select id="findInIds" resultType="user" parameterType="queryvo">  
    <!--  select * from user where id in (1,2,3,4,5); --> 
    <include refid="defaultSql"></include>   
    <where> 
        <if test="ids != null and ids.size() > 0">     
            <foreach collection="ids" open="id in ( " close=")" item="uid"  separator=",">                      #{uid}     
            </foreach>    
        </if>   
    </where>  
</select> 

SQL 语句:    
    select 字段 from user where id in (?) 
<foreach>标签用于遍历集合,它的属性:  
collection:代表要遍历的集合元素,注意编写时不要写#{}  
open:代表语句的开始部分  
close:代表结束部分 
item:代表遍历集合的每个元素,生成的变量名  
sperator:代表分隔符 

多表查询

1对1

1.定义一个包含两个实体的新类

2.使用resultMap配置

<resultMap type="account" id="accountMap"> 
    <id column="aid" property="id"/>  
    <result column="uid" property="uid"/>  
    <result column="money"  property="money"/> 
    <!-- 它是用于指定从表方的引用实体属性的 -->  
    <association property="user" javaType="user">  
        <id column="id" property="id"/>  
        <result column="username" property="username"/>  
        <result column="sex" property="sex"/>   
        <result column="birthday" property="birthday"/>  
        <result column="address" property="address"/> 
    </association>  
</resultMap>   

1对多

<?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.itheima.dao.IUserDao">   
 <resultMap type="user" id="userMap">  
     <id column="id" property="id"></id> 
     <result column="username" property="username"/>  
     <result column="address" property="address"/> 
     <result column="sex" property="sex"/>  
     <result column="birthday" property="birthday"/>  
     <!-- collection 是用于建立一对多中集合属性的对应关系 ofType 用于指定集合元素的数据类型  --> 
     <collection property="accounts" ofType="account">  
         <id column="aid" property="id"/> 
         <result column="uid" property="uid"/>   
         <result column="money" property="money"/> 
     </collection> 
 </resultMap> 
 
 <!-- 配置查询所有操作 --> 
    <select id="findAll" resultMap="userMap"> 
        select u.*,a.id as aid ,a.uid,a.money from user u left outer join account a on u.id =a.uid  </select> 
</mapper> 
collection:部分定义了用户关联的账户信息。表示关联查询结果集 
property="accList" :关联查询的结果集存储在 User 对象的上哪个属性。 
ofType="account" :指定关联查询的结果集中的对象类型即List中的对象类型。此处可以使用别名,也可以使用全限定名。 

多对多

可以看成两个1对多

延迟加载

使用association

  1. 开启延迟加载
<settings> 
    <setting name="lazyLoadingEnabled" value="true"/>  
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  1. 配置resultMap
<resultMap type="account" id="accountMap">  
    <id column="aid" property="id"/> 
    <result column="uid" property="uid"/>  
    <result column="money" property="money"/> 
    <!-- 它是用于指定从表方的引用实体属性的 --> 
    <association property="user"javaType="user" select="com.itheima.dao.IUserDao.findById"column="uid">  
    </association> 
</resultMap>   

使用Collection

  1. 开启延迟加载
<settings> 
    <setting name="lazyLoadingEnabled" value="true"/>  
    <setting name="aggressiveLazyLoading" value="false"/>
</settings>
  1. 配置resultMap
<resultMap type="user" id="userMap">  
    <id column="id" property="id"></id>  
    <result column="username" property="username"/> 
    <result column="address" property="address"/>  
    <result column="sex" property="sex"/>  
    <result column="birthday" property="birthday"/> 
    <!-- collection 是用于建立一对多中集合属性的对应关系    ofType 用于指定集合元素的数据类型    select 是用于指定查询账户的唯一标识(账户的 dao 全限定类名加上方法名称)    column 是用于指定使用哪个字段的值作为条件查询    --> 
    <collection property="accounts" ofType="account"      select="com.itheima.dao.IAccountDao.findByUid"     column="id">  
    </collection> 
</resultMap> 
 
<collection>标签: 
     主要用于加载关联的集合对象 
select 属性:  
     用于指定查询 account 列表的 sql 语句,所以填写的是该 sql 映射的 id 
column 属性:  
     用于指定 select 属性的 sql 语句的参数来源,上面的参数来自于 user 的 id 列,所以就写成 id 这一个字段名

注解方式配置Mybatis

常用注解

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

@Results:可以与@Result 一起使用,封装多个结果集

@ResultMap:实现引用

@Results 定义的封装

@One:实现一对一结果集封装

@Many:实现一对多结果集封装

@SelectProvider: 实现动态 SQL 映射

@CacheNamespace:实现注解二级缓存的使用

根据实例快速复习

@Select("select * from user")  
@Results(id="userMap",    
value= {     
    @Result(id=true,column="id",property="userId"),
    @Result(column="username",property="userName"),
    @Result(column="sex",property="userSex"),
    @Result(column="address",property="userAddress"),
    @Result(column="birthday",property="userBirthday")    
})  
List<User> findAll(); 
@Select("select * from user where id = #{uid} ")  
@ResultMap("userMap")  
User findById(Integer userId); 
@Insert("insert into user(username,sex,birthday,address)values(#{username},#{sex},#{birthday},#{address} )") @SelectKey(keyColumn="id",keyProperty="id",resultType=Integer.class,before = false, statement = { "select last_insert_id()" })  
int saveUser(User user);   
@Update("update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday} where id =#{id} ")  
int updateUser(User user); 
@Delete("delete from user where id = #{uid} ")  
int deleteUser(Integer userId);   
@Select("select * from user where username like #{username} ")  
List<User> findByName(String name); 

配置SqlMapConfig.xml

<!-- 配置映射信息 -->  
<mappers>
  <!-- 配置 dao 接口的位置,它有两种方式 第一种:使用 mapper 标签配置 class 属性 第二种:使用 package 标签,直接指定 dao 接口所在的包    --> 
   <package name="com.itheima.dao"/>  
</mappers> 

多表查询

实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。

注意:聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的 javaType (一般为 ArrayList)但是注解中可以不定义;

1对1

@Select("select * from account")  
@Results(id="accountMap",    
         value= {     
             @Result(id=true,column="id",property="id"),
             @Result(column="uid",property="uidjava"),
             @Result(column="money",property="money"),
             @Result(column="uid",property="user",
                     one=@One(select="com.itheima.dao.IUserDao.findById",
                              fetchType=FetchType.LAZY))    
         })  
List<Account> findAll(); 

1对多

@Select("select * from user")  
@Results(id="userMap",    
         value= {     
             @Result(id=true,column="id",property="userId"),
             @Result(column="username",property="userName"),
             @Result(column="sex",property="userSex"),
             @Result(column="address",property="userAddress"),
             @Result(column="birthday",property="userBirthday"),
             @Result(column="id",property="accounts",
                     many=@Many(
                         select="com.itheima.dao.IAccountDao.findByUid",
                         fetchType=FetchType.LAZY)       
                    )    
         })  
List<User> findAll();

@Many: 
 相当于<collection>的配置  select 属性:代表将要执行的 sql 语句  fetchType 属性:代表加载方式,一般如果要延迟加载都设置为 LAZY 的值 

开启二级缓存

  1. 在 SqlMapConfig.xml 中开启二级缓存支持
<!-- 配置二级缓存 --> 
<settings> 
    <!-- 开启二级缓存的支持 -->  
    <setting name="cacheEnabled" value="true"/> 
</settings>
  1. 在持久层接口中使用注解配置二级缓存
@CacheNamespace(blocking=true)//mybatis 基于注解方式实现配置二级缓存 
public interface IUserDao {
    
} 
 
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,772评论 6 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,458评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,610评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,640评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,657评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,590评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,962评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,631评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,870评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,611评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,704评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,386评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,969评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,944评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,179评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,742评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,440评论 2 342

推荐阅读更多精彩内容