mybatis学习笔记

mybatis配置文件解析说明

1.中的logImpl属性配置指定使用LOG4J输出日志
2.元素配置一个包的别名,通常确定一个类的时候需要使用类的全限定名称,配置别名后,在使用类的时候不需要写包名的部分
3.环境配置中主要配置了数据库连接
mybatis-config配置文件

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

    <settings>
     <setting name="logImpl" value="LOG4J"/>
<!--数据库中使用user_name,java属性使用userName,这种方式,开启下面的配置,可以实现不需要别名和resultMap达到自动映射-->
  <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <typeAliases>
        <package name="com.picc.mybatis.model"></package>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="UNPOOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://192.168.2.253:3306/mytest"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--这种方式适用没有接口的时候,很繁琐-->
    <mappers>
        <mapper resource="mapper/CountryMapper.xml"/>
        <mapper resource="mapper/UserMapper.xml"/>
        <mapper resource="mapper/RoleMapper.xml"/>
        <mapper resource="mapper/RolePrivilegeMapper.xml"/>
        <mapper resource="mapper/UserRoleMapper.xml"/>
        <mapper resource="mapper/PrivilegeMapper.xml"/>
    </mappers>
    <!--这种方式使用于有接口的方式,而且简单,,查找包下所有的接口
     循环对接口进行如下操作
     1.判断接口对应的命名空间是否存在
     2.加载接口对应的xml文件,将接口权限定名转化为路径,搜索。xml后缀的资源,找到就解析xml
	-->
     <mappers>
       <package name="com.picc.mybatis.mapper"></package>
    </mappers>

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">
<!--如果不关联可以设置成不重复任意的名称-->
<!--当mapper接口和xml关联的时候,namespace需要设置成接口的权限定名称,mybatis内部通过这个命名空间将接口和xml关联起来-->
<mapper namespace="com.picc.mybatis.mapper.UserMapper">
<!--resultMap通过设置列和属性的对应关系来实现查询列自动映射到属性的,除了这种方式还可以在查询语句中使用别名来达到自动映射的功能-->
<!--resultmap只是用来完成字段映射的功能,当返回类型使用resulttype的时候,使用别名的来映射-->
    <resultMap id="userMap" type="SysUser">
    <!--通过构造方法注入-->
       <constructor>
       <idArg  column="id" javaType="long"></idArg>
       <arg  column="user_name" javaType="String"></arg>
       </constructor>
   <!--通过setter方式注入-->
        <result property="userPassword" column="user_password"></result>
        <result property="userEmail" column="user_email"></result>
        <result property="userInfo" column="user_info"></result>
        <result property="headImg" column="head_img" jdbcType="BLOB"></result>
        <result property="createTime" column="create_time" jdbcType="TIMESTAMP"></result>
    </resultMap>
   <resultMap id="roleMap" type="SysRole">
   		<!--多表关联查询,字段映射可以通过下面的方式来实现对象的映射-->
        <association property="user" resultMap="userMap"></association>
    </resultMap>
    <select id="selectById" resultMap="userMap">
        SELECT * FROM sys_user where id = #{id};
    </select>
<!--当多表关联查询的时候,可以将语句写在相关表对应的任意一个xml中
-->
    <select id="selectAll" resultType="SysUser">
        SELECT id, user_name userName, user_password userPassword,user_email userEmail,
            user_info userInfo,head_img headImg,create_time createTime
        from sys_user;
    </select>
    <!--多表查询,可以在涉及的多表中任何一个表中创建一下语句,如果要映射多表的数据,则需要在role中创建user属性-->
        <select id="selectRolesByUserId" resultType="SysRole">
        select  r.id,r.role_name roleName,r.enabled,r.create_by createBy,
            r.create_time createTime,u.user_name as "Sysuser.userName",
            u.user_email as "Sysuser.userEmail"
        from sys_user u
        inner join sys_user_role ur on u.id = ur.user_id
        inner join sys_role r on r.id = ur.role_id
        where u.id= #{uid}
    </select>
    <!--useGeneratedKeyss设置为true,来取出由数据库内部生成的主键的值,将其赋值给keyProperty配置的id值,但是只支持主键自增的主键的数据库-->
    <insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
 insert into sys_user (id, user_name, user_password,    user_email,user_info, head_img, create_time) values (#{id} , #{userName} , #{userPassword} , #{userEmail}		,#{userInfo} , #{headImg, jdbcType=BLOB},
   #{createTime, jdbcType= TIMESTAMP})
    </insert>
    <!--这种方式即支持主键自增的数据库,也支持非自增的数据库,在mysql中order="AFTER",
       因为主键值在插入成功后才能获取,而oracle先从序列获取值,然后作为主键插入order="before"
      -->
  <insert id="insertUser2">
  insert into sys_user (id, user_name, user_password, user_email,user_info, head_img, create_time) values (#{id} , #{userName} , #{userPassword} , #{userEmail},
#{userInfo} , #{headImg, jdbcType=BLOB},
#{createTime, jdbcType= TIMESTAMP})
   <selectKey keyColumn="id" resultType="long" keyProperty="id" order="AFTER">
     select LAST_INSERT_ID()
   </selectKey>
 </insert>
</mapper>
public class CountryMapperTest {
  private static SqlSessionFactory sqlSessionFactory;
  @BeforeClass
  public static void init() throws Exception{
  //通过Resources将配置文件读取到reader
    Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
  //在创建sqlSessionFactory的过程中,解析mybatis-config中的信息,读取到mapper时,将mapper.xml全部读取进行具体方法的解析,极细完之后,sqlSessionFactory就包含了所有的属性配置和sql信息
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
    reader.close();
  }

  public SqlSession getSqlSession(){
  	//sqlSesiion默认不开启自动提交
    return sqlSessionFactory.openSession();
  }
  @Test
  public void testSelectAll(){
    SqlSession sqlSession = getSqlSession();
    try {
    //只有xml,不和接口关联的情况,使用下面的语句
      List<Country> countryList = sqlSession.selectList ("selectall");
      System.out.println(countryList.get(0).getCountryname());
    } finally {
      sqlSession.close();
    }
  // 接口和xml关联的情况
  @Test
  public void testselectRolesByUserId() {
    SqlSession sqlSession = getSqlSession();
    try {
      // 创建接口的代理对象,对象名称以$proxy123表示
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      //调用接口中的方法
      List<SysRole> sysRole = mapper.selectRolesByUserId(1);
      System.out.println(sysRole.get(0).getUser().getUserName());
    } finally {
      sqlSession.close();
    }
  }
  }

mybatis缓存配置

一级缓存

mybatis的一级缓存存在于sqlsession的生命周期中,在同一个sqlsession中查询时,mybatis会把执行的方法和参数通过算法生成缓存的键值,将键值和结果存在一个map对象中。如果同一个sqlsession中执行的方法和参数完全一致,那么通过算法会生成相同的键值,当map缓存对象中已经存在该键值时,则会返回缓存中的对象。

<select id=”selectByid” flushCache=”true” resultMap=’”userMap”> 
</select>

flushCache=true会在查询数据前,清空当前的一级缓存,因此该方法每次都会重新从数据库中查询数据。。任何的insert update delete操作都会清空一级缓存

二级缓存

mybatis 的二级缓存存在于sqlsessionFactory的生命周期中,在mybatis-config.xml设置下面的配置

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

cacheEnabled设置为true,二级缓存开启
mybatis的二级缓存是和命名空间绑定的,即二级缓存需要配置在Mapper.xml映射文件中,或者配置在mapper.java接口中

<?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.picc.mybatis.mapper.UserMapper">
	<cache/>
</mapper>

默认的二级缓存有以下的效果
1.映射文件中的所有select语句将会被缓存。
2.映射文件中的所有insert update delete语句会刷新缓存
3.缓存会使用LRU最近最少使用的算法来收回
4.缓存会存储集合或对象的1024个引用
5.缓存会被视为 read/write (可读/可写)的,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
6.根据时间表(如 no Flush Interval ,没有刷新间隔),缓存不会以任何时间顺序来刷新。
所有的这些属性都可以通过缓存元素的属性来修改

属性介绍:
evicion(收回策略)
LRU(最近最少使用的):移除最长时间不被使用的对象,这是默认值。
FIFO(先进先出):按对象进入缓存的顺序来移除它们。
SOFT(软引用):移除基于垃圾回收器状态和软引用规则的对象。
WEAK(弱引用):更积极地移除基于垃圾收集器状态和弱引用规则的对象。

flushinterval(刷新间隔)
可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况不设置,即没有刷新间隔,缓存仅仅在调用语句时刷新。

size(引用数目)
可以被设置为任意正整数,要记住缓存的对象数目和运行环境的可用内存资源数目。默认值是1024 。

readOnly(只读)
属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改,这提供了很重要的性能优势。

可读写的缓存会通过序列化返回缓存对象的拷贝,这种方式会慢一些,但是安全,因此默认是 false。
readOnly=true只读,二级缓存会返回相同的实例,使用map来存储缓存值
readOnly=false可读写的缓存,使用SerializedCache序列化缓存来实现可读写缓存类,并通过序列化和反序列化来保证通过缓存获取数据时,得到是一个新的实例
ration 缓存命中率

  @Test
  public void testUserSelectByid() {
    SqlSession sqlSession = getSqlSession();
    try {
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      SysUser sysUser = mapper.selectById(1);
      sysUser.setUserName("haha");
      System.out.println(sysUser.getUserName());    //haha
      SysUser sysUser1 = mapper.selectById(1);
      System.out.println(sysUser1.getUserName());   //haha
      System.out.println(sysUser==sysUser1);        //true
    } finally {
      sqlSession.close();
    }
    SqlSession sqlSession1 = getSqlSession();
    try {
      UserMapper mapper = sqlSession1.getMapper(UserMapper.class);
      SysUser sysUser = mapper.selectById(1);
      System.out.println(sysUser.getUserName());    //haha
      SysUser sysUser1 = mapper.selectById(1);
      System.out.println(sysUser1.getUserName());   //haha
      System.out.println(sysUser==sysUser1);        //true
    } finally {
      sqlSession.close();
    }
  }

命中率
在这里插入图片描述

mutates提供的缓存是基于map实现的内存缓存,当需要缓存大量数据的时候,不能仅仅通过提高内存来使用mybatis的二级缓存,还可以通过EhCache缓存框架或redis缓存数据库来实现二级缓存

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值