美文网首页
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

    1. 认识一蛤什么是懒加载 什么是懒加载?所谓懒加载,简单说就是按需加载,用于查询结果存在一对一或一对多的情况,在...

  • mybatis-notes:写一个很简单的入门级mybatis

    昨晚看了那么久了博客了,今天准备自己写一个demo试试。 1、新建一个数据库作为测试练手 2、在eclipse中新...

  • 写一个简单的故事

    “我们是跨国,姐弟,网恋,在一起太难了”。当这些从你的嘴里一个词一个词的说出来,我知道了你面临着什么样的...

  • 写一个简单的server

    服务器我们也有了,就是我们的电脑。 但我们还没有提供HTTP的程序,用脚本就可以提供HTTP服务,不管是Bash脚...

  • 简单的写

    我是一个16级的大学生,现在在沈阳读书。说来很俗,我小时候也很喜欢写东西,初一时写过一点玄幻作品,主要启发于斗破和...

  • 简单的写

    简单的写出自己的心事,简单的表达出自己的苦闷。 简单的写出现在自己的境况,没有女朋友,没有工作,没钱,没车,没房,...

  • 简单的写

    简单的写一点自己的感想,唐山的打人事件,为什么过了这么久了,这是还没有结束,我们看到的都是网友门的猜测和愤怒,嫌疑...

  • 简单的写,深刻的写

    如果不记录,就会忘,忘了就仿佛没有存在过。 所以,简单的写,深刻的写。

  • 简单的测试简单的写

    Section A 大部分写Rails的人都是被手把手的教着TDD、BDD这些东西的,尽管职业生涯中,并没有怎么(...

  • 简单写

网友评论

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

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