MyBatis框架----多表查询与动态sql

目录

1.多表查询

1.1多对一

(1)  第一种方式 通过链表查询。

(2)第二种方式 通过嵌套查询。----两次查询。

 1.2 一对多

2.动态SQL

(1)if和where一起用

  (2)  [choose when otherwise] 和where

  (3)set标签---修改部分字段

  (4) foreach 批量处理


1.多表查询

        1.1多对一

                        例子: 根据学生id查询学生信息与班级信息

                        (1)  第一种方式 通过链表查询。

                          1. 创建两张具有逻辑外键或物理外键的数据表

                            班级表

                         学生表

                2. 常见数据表对应的实体类 

                班级实体类

public class Cls {
    private Integer id;
    private String cname;
    


    public Cls() {
    }

    public Cls(Integer id, String cname) {
        this.id = id;
        this.cname = cname;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "Cls{" +
                "id=" + id +
                ", cname='" + cname + '\'' +
                '}';
    }
}

                 学生实体类:

public class Stu {
    private Integer id;
    private String name;
    private String classid;
    //学生类里面需要创建一个班级类的实体类!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    private Cls cls;

    public Stu() {
    }

    public Stu(Integer id, String name, String classid, Cls cls) {
        this.id = id;
        this.name = name;
        this.classid = classid;
        this.cls = cls;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassid() {
        return classid;
    }

    public void setClassid(String classid) {
        this.classid = classid;
    }

    public Cls getCls() {
        return cls;
    }

    public void setCls(Cls cls) {
        this.cls = cls;
    }

    @Override
    public String toString() {
        return "Stu{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", classid='" + classid + '\'' +
                ", cls=" + cls +
                '}';
    }
}

                 3.创建学生dao层接口并定义方法

public interface StuDao {
    Stu selectstuandclassbystuid(int id);
}

                4.在映射文件中写对应的dao接口方法中的sql语句

<?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.aaa.qy145.ten.cys.dao.StuDao">

    <select id="selectstuandclassbystuid" resultMap="getstu">
        select * from stu s join class c on s.uclassid=c.id where s.id = #{id}
    </select>


    <!--  
        <id>标签:实体类中属性与数据库主键对应 使用的标签
        <result>标签: 实体类其他属性与数据库的列名对应 使用的标签
        上面只适用于 八大基本类型与String类型的简单属性  
        若是实体类属性 应使用<association>复杂标签

        <association>标签: property:对应学生类中的实体类的变量名(cls)
                            javaType:对应的是该变量名对应的实体类(Cls)的路径
          该标签中书写 javaType对应的实体类(Cls)的属性名与数据表名之间的关系
          如果实体类(Cls)属性名与数据表名相同 可不写 但必须要在 
                    <association>标签内书写 autoMapping="true"
    -->

    <resultMap id="getstu" type="com.aaa.qy145.ten.cys.entity.Stu">
        <id property="id" column="id"/>
        <result property="name" column="uname"/>
        <result property="classid" column="uclassid"/>
        <association property="cls" javaType="com.aaa.qy145.ten.cys.entity.Cls" autoMapping="true">
            <id property="id" column="id"/>
            <result property="cname" column="classname"/>
        </association>
    </resultMap>



</mapper>

                5.在配置文件中注册映射文件并测试

                注册:

    <mappers>
        <mapper resource="Mapper/StuMapper.xml"/>
    </mappers>

                测试:

 @Test
    public void test01() throws IOException {
        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();
        
        StuDao stuDao = session.getMapper(StuDao.class);
        Stu stu = stuDao.selectstuandclassbystuid(1001);
        System.out.println(stu);
    }

                结果:

         (2)第二种方式 通过嵌套查询。----两次查询。

                1.  在学生映射文件中写对应的dao接口方法中的sql语句



<!--
    该sql语句只根据学生id查找学生数据表中的所有数据

-->

<select id="selectstuandclassidbystuid" resultMap="getstuandclassid">
        select * from  stu where stu.id=#{id}
</select>


    <resultMap id="getstuandclassid" type="com.aaa.qy145.ten.cys.entity.Stu">
                <id property="id" column="id"/>
                <result property="name" column="uname"/>
                <result property="classid" column="uclassid"/>


        <!--
            column: 对应的是 学生数据表与班级数据表的 外键列名 
            select: 对应的是 班级映射文件里的 根据班级id查找班级信息 的sql语句的对应路径
        -->
        <association property="cls" javaType="com.aaa.qy145.ten.cys.entity.Cls"
                     column="uclassid"                     
           select="com.aaa.qy145.ten.cys.dao.ClsDao.getclassbyclassid">

        </association>

          2.  在班级映射文件中写根据班级id查找班级信息的sql语句

<mapper namespace="com.aaa.qy145.ten.cys.dao.ClsDao">


    <!-- 
        因为班级实体类中属性名与列名不同 采用第二中 别名方法:列名的别名与实体类的属性名相同即可    
        也可使用resultMap方法 两种方法都可以 
    -->

    <select id="getclassbyclassid" resultType="com.aaa.qy145.ten.cys.entity.Cls">
        select id id,classname cname from class where id=#{id}
    </select>

</mapper>

        3.在配置文件中注册两张表的映射文件 并测试

        注册:

 <mappers>
        <mapper resource="Mapper/StuMapper.xml"/>
        <mapper resource="Mapper/ClasMapper.xml"/>
    </mappers>

        测试:

@Test
    public void test01()throws IOException {

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();


        StuDao stuDao = session.getMapper(StuDao.class);
        Stu stu = stuDao.selectstuandclassbystuid(1001);
        System.out.println(stu);
    }

        测试结果:

 

 1.2 一对多

        例:根据班级id查找班级信息以及班级内所有学生  

        1. 使用上例多对一的数据表

        2.创建数据表对应的实体类

        学生类:

public class Stu {
    private Integer id;
    private String name;
    private String classid;


    public Stu() {
    }

    public Stu(Integer id, String name, String classid) {
        this.id = id;
        this.name = name;
        this.classid = classid;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getClassid() {
        return classid;
    }

    public void setClassid(String classid) {
        this.classid = classid;
    }

    @Override
    public String toString() {
        return "Stu{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", classid='" + classid + '\'' +
                '}';
    }
}

        班级类:

public class Cls {
    private Integer id;
    private String cname;
    //班级中有很多学生 所以需要创建一个学生类的集合
    private List<Stu> stus;

    public Cls() {
    }

    public Cls(Integer id, String cname, List<Stu> stus) {
        this.id = id;
        this.cname = cname;
        this.stus = stus;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    public List<Stu> getStus() {
        return stus;
    }

    public void setStus(List<Stu> stus) {
        this.stus = stus;
    }

    @Override
    public String toString() {
        return "Cls{" +
                "id=" + id +
                ", cname='" + cname + '\'' +
                ", stus=" + stus +
                '}';
    }
}

        3.创建班级dao接口

public interface ClsDao {
    Cls selectclassandstubyclassid(int id);
}

       4.在班级表的映射文件中写dao接口方法的对应sql

<mapper namespace="com.aaa.qy145.ten.cys.dao.ClsDao">

<!-- 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
        如果两个表中没有相同的列名 可以直接 select *  ....   
        但是由于班级表跟学生表中的主键都为 id  
        因此需要将其中一个由别名展示  不然查询到的数据会显示不完整 
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
-->

<select id="selectclassandstubyclassid" resultMap="getclass">
    select c.*,s.id sid,s.uname name,s.uclassid classid from class c join stu s on c.id = s.uclassid where c.id=#{id}
</select>
    <resultMap id="getclass" type="com.aaa.qy145.ten.cys.entity.Cls">
        <id property="id" column="id"/>
        <result property="cname" column="classname"/>
        <collection property="stus" ofType="com.aaa.qy145.ten.cys.entity.Stu" autoMapping="true">
            <id property="id" column="sid"/>
        </collection>
    </resultMap>
</mapper>

5.测试

@Test
    public void test02()throws IOException{

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();


        ClsDao clsDao = session.getMapper(ClsDao.class);
        Cls cls = clsDao.selectclassandstubyclassid(1);
        System.out.println(cls);
    }

测试结果:

 上述为第一种链表查询  第二种嵌套查询与多对一第二种相同 略

2.动态SQL

         所谓动态sql 便是sql语句根据条件而发生改变。 一般用到的方法为:

元素    作用描述
if条件判断但条件判断
choos(when、otherwise)条件选择,相当Java when多条件分支判断
where、set       辅助 处理sql语句拼接问题
foreache循环循环

                首先创建一个数据表 并存入数据

         创建对应实体类与dao接口 并创建sql方法

       

 

 

(1)if和where一起用

        根据 name sex 来查询数据。如果 name 为空,那么将只根据 sex 来查询;如果 sex 也为空 则查询所有
        
<!--     #{参数名}   参数名:与map集合中的key对应才可获得传来的参数



         如果name为空,那么将只根据sex来查询;如果sex也为空 则查询所有

          where:可以帮你添加where关键 并且把第一个and | or去除
    --> 
<select id="selectbysome" resultMap="my01">
       select * from student
        <where>
        <if test="sname!=null and sname!=''">
            and s_name=#{sname}
        </if>
        <if test="ssex!=null and ssex!=''">
            and  s_sex=#{ssex}
        </if>
        </where>
</select>

测试:

@Test
    public void test03()throws IOException{

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();



        StudentDao studentDao = session.getMapper(StudentDao.class);
        Map<String,String> map = new HashMap<String, String>();
        //从网页中得到参数值 并且封装到map对象中。
        map.put("sname","李云");
        map.put("ssex","男");
        List<Student> list = studentDao.selectbysome(map);
        System.out.println(list);
    }

 (2)  [choose when otherwise] 和where

        根据 name sex 来查询数据 若name有数据则之按照name查询 若name没数据 则按照sex查询 若sex也没数据则查询id为1的学生  

<!--   
      choose +where
      when:当条件满足时不会执行下面的when和other  都不满足则执行otherwise

  -->

<select id="selectbysexorname" resultMap="my01">
        select * from student
        <where>
            <choose>
                <when test="name!=null and name!=''">
                    and s_name=#{name}
                </when>
                <when test="sex!=null and sex!=''">
                    and s_sex=#{sex}
                </when>
                <otherwise>
                    s_id=1
                </otherwise>
            </choose>
        </where>
    </select>

测试:

@Test
    public void test05()throws IOException{

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();



        StudentDao studentDao = session.getMapper(StudentDao.class);
        Map<String,String> map = new HashMap<String, String>();
        //从网页中得到参数值 并且封装到map对象中。
        map.put("sex","男");
        List<Student> list = studentDao.selectbysexorname(map);
        System.out.println(list);
    }

 (3)set标签---修改部分字段

        在 UPDATE 更新列中使用 if 标签 有时候我们不希望更新所有的字段, 只更新有变化的字段
<!--
    修改部分列的值。
      set 可以帮你添加set关键字 并且去除最后的逗号。
-->


 <update id="updateall">
        update student
        <set>
            <if test="name!=null and name!=''">
                s_name=#{name},
            </if>
            <if test="birth!=null and birth!=''">
                s_birth=#{birth}
            </if>
            <if test="sex!=null and sex!=''">
                s_sex=#{sex}
            </if>
        </set>
        where s_id = #{id}
    </update>

测试:

@Test
    public void test04()throws IOException{

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();



        StudentDao studentDao = session.getMapper(StudentDao.class);
        Map<String,String> map = new HashMap<String, String>();
        //从网页中得到参数值 并且封装到map对象中。
        map.put("id","05");
        map.put("name","哈哈");
        map.put("sex","男");
        int i = studentDao.updateall(map);
        System.out.println("受影响的行数:"+i);
        session.commit();
    }

 (4) foreach 批量处理

        查询id=01020304的学生。

<!-- 
     foreach:
         collection:要遍历的集合和数组名
         item: 每次遍历时赋值的元素变量名
         open: 以什么开始
         close:以什么结束
         separator: 分隔符
        
        List<Student> selectbysomeid(@Param("ids") int[] ids);
    #{参数名}:  要与对应方法的@Param("参数名")   相对应
            
            
-->

<select id="selectbysomeid" resultMap="my01">
        select * from student where s_id in
        <foreach collection="ids" item="tid" open="(" close=")" separator=",">
            #{tid}
        </foreach>
    </select>

测试:

@Test
    public void test06()throws IOException{

        Reader reader = Resources.getResourceAsReader("mybatis.xml");
        SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(reader);
        SqlSession session = sqlSessionFactory.openSession();


        StudentDao studentDao = session.getMapper(StudentDao.class);
        int[] ids = {1,3,4};
        List<Student> list = studentDao.selectbysomeid(ids);
        for(Student s:list){
            System.out.println(s);
        }
    }

 

最后,mybatis框架的基本使用到此结束,感谢浏览 ^_^

  • 4
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值