Mybatis多表联合查询和Mybatis动态sql

一对一查询:

建表:

CREATE TABLE `servants` (
   `id` int(10) NOT NULL AUTO_INCREMENT,
   `name` varchar(20) COLLATE utf8_bin DEFAULT NULL,
   `cla` varchar(20) COLLATE utf8_bin DEFAULT NULL,
   `address` varchar(20) COLLATE utf8_bin DEFAULT NULL,
   PRIMARY KEY (`id`)
 ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8 COLLATE=utf8_bin
CREATE TABLE `master` (
   `mid` int(10) DEFAULT NULL,
   `master` varchar(20) COLLATE utf8_bin DEFAULT NULL,
   `desc` varchar(20) COLLATE utf8_bin DEFAULT NULL,
   KEY `FK_cla` (`mid`),
   CONSTRAINT `FK_cla` FOREIGN KEY (`mid`) REFERENCES `servants` (`id`)
 ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin

实体类:get/set方法

public class Servants {
    private Integer id;
    private String name;
    private String cla;
    private String address;
    private  Master master;     //当前servants对应的master
public class Master {
    private Integer mid;
    private String master;
    private String desc;

ServantsMapper接口:

import com.fsn.beans.Servants;
public interface ServantsMapper {
    public Servants getByName(String name);
}

sqlMapConfig.xml:

<?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>
<environments default="dev">
    <environment id="dev">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="com.mysql.jdbc.Driver"/>
            <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&amp;useSSL=false"/>
            <property name="username" value="root"/>
            <property name="password" value="123"/>
        </dataSource>
    </environment>
</environments>
<mappers>
    <mapper resource="mapper/ServantsMapper.xml"/>
    <mapper resource="mapper/MasterMapper.xml"/>
</mappers>
</configuration>

ServantsMapper.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="com.fsn.mapper.ServantsMapper">
      <resultMap id="newServants" type="com.fsn.beans.Servants">
              <id property="id" column="id"></id>
              <result property="name" column="name"></result>
              <result property="cla" column="cla"></result>
              <result property="address" column="address"></result>
        <association property="master" javaType="com.fsn.beans.Master">
                <id property="mid" column="mid"></id>
                <result property="master" column="master"></result>
                <result property="desc" column="desc"></result>
        </association>
      </resultMap>
        <select id="getByName" resultMap="newServants">
                select s.*,m.* from servants s ,master m where s.id=m.mid and s.name='黑狗'
        </select>
</mapper>

<!--
         association : 一对一的查询标签 查询的结果就是一个对象
         property: 对应的对象在当前类中声明的属性名称
         javaType: 声明我们查询结果的类型
         id  result: 将我们的查询结果构建一个新的结果封装对象
     -->
<!--
        mybatis 将查询结果封装成对象
        1: 使用ResultSetMeData 获取查询列的名称   
        2: 使用 列名称 充当属性名称  通过java中的反射机制获取属性对象
        3: 使用属性对象给当前属性的赋值
     -->

测试类:

import com.fsn.beans.Servants;
import com.fsn.mapper.ServantsMapper;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class ServantsSelectTest {
    @Test
    public void test(){
        String filename="sqlMapConfig.xml";
        try {
            InputStream is=Resources.getResourceAsStream(filename);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
            SqlSession sqlSession=sqlSessionFactory.openSession();
            ServantsMapper servantsMapper=sqlSession.getMapper(ServantsMapper.class);
            Servants servants = servantsMapper.getByName("黑狗");
            System.out.println(servants.getName()+"的master"+servants.getMaster().getMaster()+"是一个"+servants.getMaster().getDesc());
            sqlSession.commit();
            sqlSession.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

一对多查询:

新建三张表:

实体类:

public class Users {
    private Integer uid;
    private String uname;
    private String uphone;
    private Car car;
    private List<Orders> ordersList; //一个用户对应多个订单对象
public class Car {
    private Integer cid;
    private String cdes;
    private  Double total;
public class Orders {
    private Integer oid;
    private String odes;
    private  Double total;
    private Integer ofk; //user表中的主键对应的外键字段

UsersMapper接口:

import com.fsn.beans.Users;
public interface UsersMapper {
    public Users getInfoByUphone(String uphone);
}

sqlMapConfig.xml:

 <mapper resource="mapper/UsersMapper.xml"/>

UsersMapper.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="com.fsn.mapper.UsersMapper">

<resultMap id="BaseResultMap" type="com.fsn.beans.Users">
    <id property="id" column="id"></id>
    <result property="uname" column="uname"></result>
    <result property="uphone" column="uphone"></result>
</resultMap>

<resultMap id="newUsers" type="com.fsn.beans.Users" extends="BaseResultMap">
    <collection property="ordersList" ofType="com.fsn.beans.Orders">
        <id property="oid" column="oid"></id>
        <result property="odes" column="odes"></result>
        <result property="total" column="total"></result>
        <result property="ofk" column="ofk"></result>
    </collection>
</resultMap
<select id="getInfoByUphone" resultMap="newUsers">
  SELECT u.*,o.* FROM USER u,orders o WHERE u.uid=o.ofk AND uphone="12345"
    </select>
</mapper>

<!--
          collection: 表示的是多方查询的关联标签 list类型集合的
          ofType: 将查询结果封转成对应的类型
       -->

测试类:

import com.fsn.beans.Users;
import com.fsn.mapper.UsersMapper;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class UserSelectMoreTest {
    @Test
    public void test(){
        String filename="sqlMapConfig.xml";
        SqlSession sqlSession = null;
        try {
            InputStream is=Resources.getResourceAsStream(filename);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession();
            UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
            Users infoByUphone = usersMapper.getInfoByUphone("12345");
            System.out.println(infoByUphone.getUname()+"\t"+infoByUphone.getOrdersList().size());
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.commit();
        sqlSession.close();
    }
}

多对多查询:

增加2张表:对应关系:

实体类:

public class Users {
    private Integer uid;
    private String uname;
    private String uphone;
    private Car car;
    private List<Orders> ordersList; //一个用户对应多个订单对象
public class Orders {
    private Integer oid;
    private String odes;
    private  Double total;
    private Integer ufk; //user表中的主键对应的外键字段
    private List<Orderdetail> orderdetails;
public class Orderdetail {
    private Integer odid;
    private Double subtotal;
    private Integer count;
    private Integer ofk;
    private Integer gfk;
    //一个详情对象 关联一个商品对象
    private Goods goods;
public class Goods {
    private Integer gid;
    private String gname;
    private Double gprice;

UsersMapper接口:

import com.fsn.beans.Users;
public interface UsersMapper {
    public  Users getAllInfoByUphone(String uphone);
}

mapper/UsersMapper.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="com.fsn.mapper.UsersMapper">

<resultMap id="BaseResultMap" type="com.fsn.beans.Users">
    <id property="id" column="id"></id>
    <result property="uname" column="uname"></result>
    <result property="uphone" column="uphone"></result>
</resultMap>


    <resultMap id="newUsers2" type="com.fsn.beans.Users" extends="BaseResultMap">
        <collection property="ordersList" ofType="com.fsn.beans.Orders">
        <id property="oid" column="oid"></id>
            <result property="odes" column="odes"></result>
            <result property="total" column="total"></result>
            <result property="ufk" column="ufk"></result>
            <collection property="orderdetails" ofType="com.fsn.beans.Orderdetail">
                <id property="odid" column="odid"></id>
                <result property="subtotal" column="subtotal"></result>
                <result property="count" column="count"></result>
                <result property="gfk" column="gfk"></result>
                <result property="ofk" column="ofk"></result>
                <association property="goods" javaType="com.fsn.beans.Goods">
                    <id property="gid" column="gid"></id>
                    <result property="gname" column="gname"></result>
                    <result property="gprice" column="gprice"></result>
                </association>
            </collection>
        </collection>
    </resultMap>
    <select id="getAllInfoByUphone" resultMap="newUsers2">

 SELECT u.*,o.*,od.*,g.* FROM USER u,orders o,orderdetail od,goods g WHERE u.uid=o.ufk AND o.oid=od.ofk AND od.gfk=g.gid AND u.uphone=#{uphone}

    </select>
</mapper>

测试类:

import com.fsn.beans.Orderdetail;
import com.fsn.beans.Orders;
import com.fsn.beans.Users;
import com.fsn.mapper.UsersMapper;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;

public class UserSelectMoreTest {
    @Test
    public void test(){
        String filename="sqlMapConfig.xml";
        SqlSession sqlSession = null;
        try {
            InputStream is=Resources.getResourceAsStream(filename);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession();
            UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
            Users allInfoByUphone = usersMapper.getAllInfoByUphone("12345");
            System.out.println(allInfoByUphone.getUname());
            for (Orders orders : allInfoByUphone.getOrdersList()) {
                System.out.println(orders.getOdes());
                for (Orderdetail orderdetail : orders.getOrderdetails()) {
                    System.out.println(orderdetail.getCount()+"\t"+orderdetail.getGoods().getGname());
                }

            }

        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.commit();
        sqlSession.close();
    }
}

一对一的嵌套查询:

表user,car不变

实体类 不用改

mapper接口:

UserMapper:

 public Users getUserByUname(String uname);

CarMappe:

public interface CarMapper {
    public Car getCarByUid(Integer uid);
}

UsersMapper.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="com.fsn.mapper.UsersMapper">
<resultMap id="BaseResultMap" type="com.fsn.beans.Users">
    <id property="id" column="id"></id>
    <result property="uname" column="uname"></result>
    <result property="uphone" column="uphone"></result>
</resultMap>

<resultMap id="newusers" type="com.fsn.beans.Users" extends="BaseResultMap">
    <association property="car" javaType="com.fsn.beans.Car" column="uid" select="com.fsn.mapper.CarMapper.getCarByUid">

    </association>
</resultMap>
<select id="getUserByUname" resultMap="newusers" >
    select u.* from user u where u.uname=#{uname}
</select>
</mapper>
    
    <!-- 
   column 就是我们执行对应的select语句获取的uid的值
   select : 调用其他工作空间下的一个查询(这个查询需要一个参数--用户主键)
-->

CarMapper.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="com.fsn.mapper.CarMapper">
<resultMap id="BaseResultMap" type="com.fsn.beans.Car">
<id property="cid" column="cid"></id>
        <result property="cdes" column="cdes"></result>
        <result property="total" column="total"></result>
        
</resultMap>
<select id="getCarByUid" resultMap="BaseResultMap">
        select * from car where cid=#{uid}
</select>
</mapper>

测试类:

   @Test
    public void test(){
        String filename="sqlMapConfig.xml";
        SqlSession sqlSession = null;
        try {
            InputStream is=Resources.getResourceAsStream(filename);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession();
            UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
            Users user = usersMapper.getUserByUname("黑狗");
            System.out.println(user.getUname()+"\t"+user.getCar().getCdes());
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.commit();
        sqlSession.close();
    }

一对多的嵌套查询:

建表:user orders

建立数据模型

UserMapper接口:

  public Users getInfoByUphone(String uphone); 

OrdersMapper接口:

public interface OrdersMapper {
   //根据用户uid查询用户订单
    public List<Orders> getOrdersByUid(Integer uid);
}

OrdersMapper.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="com.fsn.mapper.OrdersMapper">
        <resultMap id="BaseResultMap" type="com.fsn.beans.Orders">
               <id property="oid" column="oid"></id>
                <result property="odes" column="odes"></result>
                <result property="total" column="total"></result>
                <result property="ufk" column="ufk"></result>
        </resultMap>
        <select id="getOrdersByUid" resultMap="BaseResultMap">
                select * from orders where ufk=#{uid}
        </select>
    
</mapper>

UsersMapper.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="com.fsn.mapper.UsersMapper">
<resultMap id="BaseResultMap" type="com.fsn.beans.Users">
    <id property="id" column="id"></id>
    <result property="uname" column="uname"></result>
    <result property="uphone" column="uphone"></result>
</resultMap>
<resultMap id="newUser" type="com.fsn.beans.Users" extends="BaseResultMap">
    <collection property="ordersList" ofType="com.fsn.beans.Orders"
    column="uid" select="com.fsn.mapper.OrdersMapper.getOrdersByUid">
    </collection>
</resultMap>
    <select id="getInfoByUphone" resultMap="newUser">

        select u.* from user u where uphone=#{uphone}
    </select>

</mapper>

测试类:

    @Test
    public void test(){
        String filename="sqlMapConfig.xml";
        SqlSession sqlSession = null;
        try {
            InputStream is=Resources.getResourceAsStream(filename);
            SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
            sqlSession = sqlSessionFactory.openSession();
            UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
            Users infoByUphone = usersMapper.getInfoByUphone("12345");
            System.out.println(infoByUphone.getUname()+"\t"+infoByUphone.getOrdersList().size());
        } catch (IOException e) {
            e.printStackTrace();
        }
        sqlSession.commit();
        sqlSession.close();
    }
}

结果:2条查询结果的拼接

Mybatis动态SQL

表:user

UserMapper接口:

 public Integer updateUser(Users users);

UsersMapper.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="com.fsn.mapper.UsersMapper">
    <update id="updateUser" parameterType="com.fsn.beans.Users">

        update user
        <set>
            <if test="uname!=null">
                uname=#{uname},
            </if>
            <if test="uphone!=null">
                uphone=#{uphone},
            </if>
        </set>
        <where>
            uid=#{uid}
        </where>
    </update>
</mapper>

测试类:

    @Test
public void test(){
    String filename="sqlMapConfig.xml";
    SqlSession sqlSession = null;
    try {
        InputStream is=Resources.getResourceAsStream(filename);
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
        sqlSession = sqlSessionFactory.openSession();
        UsersMapper usersMapper = sqlSession.getMapper(UsersMapper.class);
       Users users=new Users();
       users.setUname("法狗");
       users.setUid(2);
       usersMapper.updateUser(users);
    } catch (IOException e) {
        e.printStackTrace();
    }
    sqlSession.commit();
    sqlSession.close();
}
}

where 标签:

 <!--
       where标签最后被mybatis解析成where关键字
       where标签会忽略到紧邻着where关键字的sql中的 and  or
       where标签中没有成立的条件那么where自动失效
       -->

if 标签:

<!--
   if标签是判断标签 如果test属性值为true那么就执行标签中间的sql
          	如果test值为false 那么就忽略标签中间的内容
   if标签的判断的判断表达式 可以判断null值  可以进行数值判断  对				应属性值可以调用当前类中的方法
   if标签的判断内容可以是用 and 或者是 or进行一个多条件判断
   test中使用的判断的变量的名称必须是我们传入类型的属性名称
        注意:如果传入的是一个普通类型的数据,那么我们在代码中必须使用 @Param("名称") 指定名称
        -->

set 标签:

进行数据更新的时候使用的标签
       <!--
           set标签会被mybatis解析成我们的set关键字
           set标签会自动的忽略最后一个成立条件的逗号
       -->
posted @ 2020-06-30 22:21  zero6  阅读(500)  评论(0)    收藏  举报