美文网首页
mybatis-notes:写一个简单的demo-mybatis

mybatis-notes:写一个简单的demo-mybatis

作者: 09c72470861c | 来源:发表于2018-07-26 01:24 被阅读0次

    1. 认识一蛤什么是懒加载

    什么是懒加载?所谓懒加载,简单说就是按需加载,用于查询结果存在一对一或一对多的情况,在mybatis中体现在<association>和<collection>的参数中,当要不用到这种关系的数据的时候就不向数据库查询,要用的时候才再次发送一条语句来查询,这样大大节省了数据库资源也提高了查询效率。

    2. 便于理解,来个场景

    上面的介绍也是很多网上很多人的说法,这样就太笼统、抽象了,举个例子:
    比如我的demo中的Teacher类中属性有
    t_id(int型),
    t_name(String型),
    stuList(List型),
    其中stuList顾名思义既是这个老师教的学生的集合。
    而Student类是对应的student表,里面的属性有
    id(int型),
    stu_name(String型),
    age(int型),
    t_id(int型),
    其中student表中的t_id和teacher表中的t_id是对应的。
    那么懒加载就来了,如果我要查询这个老师的所有信息,但是现在我还不想看他到底教哪些学生,那么后台就会先查询这个老师的除了学生表之外的信息。当我要看这个老师到底教了哪些学生时,再向数据库发送一条sql单独查询哪些学生的属性带有这个老师的t_id。

    3. 具体代码实现

    要用到懒加载,就要多用到两个jar包,asm和cglib:

    jar
    导了jar后,需要在总config.xml中进行一些配置:
        <settings>
            <!-- 日志 -->
            <setting name="logImpl" value="STDOUT_LOGGING" />
            <!-- 打开延迟加载的开关 -->
            <setting name="lazyLoadingEnabled" value="true" />
            <!-- 将积极加载改为消极加载即按需要加载 -->
            <setting name="aggressiveLazyLoading" value="false" />
        </settings>
    

    其中懒加载相关的配置只有后两行,不过第一行的日志有助于跟进mabatis的执行。

    然后dao中写好接口TeacherDao.java

    package demo.cyj.dao;
    import demo.cyj.pojo.Teacher;
    public interface TeacherDao {
        public Teacher findTeacherByTname(String tname);    
    }
    
    

    后面就是重头了,mapperTeacherMapper.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="demo.cyj.dao.TeacherDao">
        <select id="findTeacherByTname" resultType="Teacher" resultMap="getTeacher">
            select t.t_id t_id,t.t_name t_name from teacher t where t.t_name =#{name}
        </select>
    
        <resultMap type="Teacher" id="getTeacher">
            <collection ofType="Student" property="stuList" fetchType="lazy" column="t_name" select="findTeacherByTnameLazy" />
        </resultMap>
    
        <select id="findTeacherByTnameLazy" resultType="Student" >
            select s.id id,s.stu_name stu_name,s.stu_age age,s.t_id t_id from student s left join teacher t on t.t_id = s.t_id where t.t_name=#{name} 
        </select>       
    </mapper>
    

    可以看到,这个有懒加载的查询分为了两个<select>和一个<resultMap>,
    如果你的表字段和类的属性名不同,可以通过取别名或在<resultMap>中额外做字段匹配的配置),
    <resultMap>中的<collection>就是配置一对多关系的标签,
    <association>是一对一的标签),
    在<collection>中,

    • ofType="Student"指定了这个集合的存放(组装对象)类型,类似泛型;
    • property="stuList"指定了这个集合在Teacher类中的属性名;
    • fetchType="lazy"指定了哪种加载方式;
    • column="t_name"指定了上一条sql中查询出来的结果中的哪一列的值会被传递到下一条sql中作为条件值;
    • select="findTeacherByTnameLazy"指定了下一条被执行的<select>的id名;

    而在第二条<select>中就要将id和上一条的select中配置的名字一致,resultType="Student"指定了查询结果组装为Student类对象。

    最后写测试类Test.java

    package demo.cyj;
    
    import java.io.IOException;
    import java.io.InputStream;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import demo.cyj.dao.StudentDao;
    import demo.cyj.dao.TeacherDao;
    import demo.cyj.pojo.Student;
    import demo.cyj.pojo.Teacher;
    
    public class Test { 
        public static void main(String[] args) throws IOException {
            String src = "config.xml";
            InputStream inputStream = Resources.getResourceAsStream(src);
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sessionFactory.openSession(true);
            
            //绑定
            TeacherDao td = sqlSession.getMapper(TeacherDao.class);
            Teacher t= td.findTeacherByTname("htc");
            System.out.println(t.getT_id());
        }
    }
    

    运行后可以看到控制台打印的结果:

    只展示id的情况
    这是因为这段代码System.out.println(t.getT_id());,我只想看这个名为htc的老师的id是多少,所以只向数据库发送了一条sql,没有去查stuList的信息。
    然后修改代码:
    public class Test { 
        public static void main(String[] args) throws IOException {
            String src = "config.xml";
            InputStream inputStream = Resources.getResourceAsStream(src);
            SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession = sessionFactory.openSession(true);
            
            //绑定
            TeacherDao td = sqlSession.getMapper(TeacherDao.class);     
            Teacher t= td.findTeacherByTname("htc");
            System.out.println(t);
        }
    }
    

    修改的代码为System.out.println(t);,即打印该名为htc的老师的所有信息,包括stuList.
    运行后可以看到控制台打印的结果:

    展示所有数据的情况
    控制台信息太长没显示完,附一个控制台信息:
    ==>  Preparing: select t.t_id t_id,t.t_name t_name from teacher t where t.t_name =? 
    ==> Parameters: htc(String)
    <==    Columns: t_id, t_name
    <==        Row: 1, htc
    <==      Total: 1
    ==>  Preparing: select s.id id,s.stu_name stu_name,s.stu_age age,s.t_id t_id from student s left join teacher t on t.t_id = s.t_id where t.t_name=? 
    ==> Parameters: htc(String)
    <==    Columns: id, stu_name, age, t_id
    <==        Row: 8, 黑拐, 43, 1
    <==        Row: 9, 拐, 50, 1
    <==        Row: 10, 拐棍, 50, 1
    <==        Row: 11, 大黑拐, 30, 1
    <==        Row: 12, 小黑拐, 12, 1
    <==        Row: 13, 拐哥, 29, 1
    <==        Row: 14, 胡黑拐, 123, 1
    <==      Total: 7
    Teacher [t_id=1, t_name=null, stuList=[Student [id=8, stu_name=黑拐, age=43, t_id=1], Student [id=9, stu_name=拐, age=50, t_id=1], Student [id=10, stu_name=拐棍, age=50, t_id=1], Student [id=11, stu_name=大黑拐, age=30, t_id=1], Student [id=12, stu_name=小黑拐, age=12, t_id=1], Student [id=13, stu_name=拐哥, age=29, t_id=1], Student [id=14, stu_name=胡黑拐, age=123, t_id=1]]]
    
    

    可以看到,这次的sql语句有两条了,一次是查询该老师的基本信息,一次是查询该老师教的学生的列表。


    总结一下:

    • 懒加载就是按需加载,如果有的数据需要关联其他表查询,而暂时又不用展示,就可以先不查询它,等到要展示的时候才查询它
    • 还是要仔细,越是不熟的东西就越要看清楚了,不然很多时间都会浪费在寻找格式等错误上

    相关文章

      网友评论

          本文标题:mybatis-notes:写一个简单的demo-mybatis

          本文链接:https://www.haomeiwen.com/subject/xscvmftx.html