自学内容网 自学内容网

MyBatis最佳实践:多表联查

第一章:一对多查询

  1. 多表设计:
    1. 一对一:其实一对一可以设计成一张表
    2. 一对多
    3. 多对一
    4. 多对多
  2. 搭建开发环境:
    1. 执行建表语句:
      CREATE TABLE `user` (
        `id` int(11) NOT NULL auto_increment,
        `username` varchar(32) NOT NULL COMMENT '用户名称',
        `birthday` datetime default NULL COMMENT '生日',
        `sex` char(1) default NULL COMMENT '性别',
        `address` varchar(256) default NULL COMMENT '地址',
        PRIMARY KEY  (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      ​
      insert  into `user`(`id`,`username`,`birthday`,`sex`,`address`) values 
          (1,'老王','2018-02-27 17:47:08','男','北京'),
          (2,'熊大','2018-03-02 15:09:37','女','上海'),
          (3,'熊二','2018-03-04 11:34:34','女','深圳'),
          (4,'光头强','2018-03-04 12:04:06','男','广州');
      CREATE TABLE `account` (
        `ID` int(11) NOT NULL COMMENT '编号',
        `UID` int(11) default NULL COMMENT '用户编号',
        `MONEY` double default NULL COMMENT '金额',
        PRIMARY KEY  (`ID`),
        KEY `FK_Reference_8` (`UID`),
        CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
      ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
      ​
      insert  into `account`(`ID`,`UID`,`MONEY`) values (1,1,1000),(2,2,1000),(3,3,2000);
    2. 编写 Account 的 JavaBean 类:
      public class Account {
      
          private Integer id;
          private Integer uid;
          private String money;
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public Integer getUid() {
              return uid;
          }
      
          public void setUid(Integer uid) {
              this.uid = uid;
          }
      
          public String getMoney() {
              return money;
          }
      
          public void setMoney(String money) {
              this.money = money;
          }
      
          @Override
          public String toString() {
              return "Account{" +
                      "id=" + id +
                      ", uid=" + uid +
                      ", money='" + money + '\'' +
                      '}';
          }
      }

    3. 编写 AccountMapper 接口:
      public interface AccountMapper {
      
      }
    4. 编写 AccountMapper.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.qcby.mapper.AccountMapper">
      
      </mapper>
    5. 主配置文件中引入映射配置文件:
      <mappers>
          <mapper resource="Mapper/UserMapper.xml"/>
          <mapper resource="Mapper/AccountMapper.xml"/>
      </mappers>
  3. 多对一查询(一对一查询):
    1. 需求:查询的数据中包含 account 所有的字段,再包含用户的名称和地址
    2. 在 Account 类中添加 User 的属性,表示该账户只属于这个用户:
      public class Account {
      
          private Integer id;
          private Integer uid;
          private String money;
      
          private User user;
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public Integer getUid() {
              return uid;
          }
      
          public void setUid(Integer uid) {
              this.uid = uid;
          }
      
          public String getMoney() {
              return money;
          }
      
          public void setMoney(String money) {
              this.money = money;
          }
      
          public User getUser() {
              return user;
          }
      
          public void setUser(User user) {
              this.user = user;
          }
      
          @Override
          public String toString() {
              return "Account{" +
                      "id=" + id +
                      ", uid=" + uid +
                      ", money='" + money + '\'' +
                      ", user=" + user +
                      '}';
          }
      }
    3. 在 AccountMapper 接口中编写查询的方法:
      public interface AccountMapper {
          public List<Account> findAll();
      
      }
    4. 编写配置文件:
      <?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.qcby.mapper.AccountMapper">
      
          <!-- 进行数据封装 -->
          <resultMap id="accountMap" type="com.qcby.model.Account">
              <result property="id" column="id"/>
              <result property="uid" column="uid"/>
              <result property="money" column="money"/>
              <association property="user" javaType="com.qcby.model.User">
                  <result property="username" column="username"/>
                  <result property="address" column="address"/>
              </association>
          </resultMap>
      
          <!-- 内连接查询 -->
          <select id="findAll" resultMap="accountMap">
              select a.*,u.username,u.address from account a,user u where a.uid = u.id;
          </select>
      
      </mapper>
    5. 测试方法:
      public class Demo01 {
      
          /**
           * 多对一查询
           *
           */
          @Test
          public void findAll() throws IOException {
              //加载主配置文件到输入流
              InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
              //创建 SqlSessionFactory 对象,创建 SqlSession 对象
              SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
      
              //创建 SqlSession 对象
              SqlSession session = factory.openSession();
      
              //获取代理对象
              AccountMapper accountMapper = session.getMapper(AccountMapper.class);
      
              //查询
              List<Account> all = accountMapper.findAll();
      
              for (Account a : all){
                  System.out.println(a);
              }
      
              //关闭资源
              session.close();
              inputStream.close();
          }
      }
  4. 一对多查询:
    1. 如果想查询 select u.*,a.money form user u left join account a on u.id = a.uid 语句中的内容
    2. 在 User 类中添加 List 的属性:
      public class User implements Serializable {
          private static final long serialVersionUID = 525400707336671154L;
          private Integer id;
          private String username;
          private Date birthday;
          private String sex;
          private String address;
      
          private List<Integer> ids;
      
          private List<Account> accounts;
      
          public List<Integer> getIds() {
              return ids;
          }
      
          public void setIds(List<Integer> ids) {
              this.ids = ids;
          }
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getUsername() {
              return username;
          }
      
          public void setUsername(String username) {
              this.username = username;
          }
      
          public Date getBirthday() {
              return birthday;
          }
      
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          public String getSex() {
              return sex;
          }
      
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          public String getAddress() {
              return address;
          }
      
          public void setAddress(String address) {
              this.address = address;
          }
      
          public List<Account> getAccounts() {
              return accounts;
          }
      
          public void setAccounts(List<Account> accounts) {
              this.accounts = accounts;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "id=" + id +
                      ", username='" + username + '\'' +
                      ", birthday=" + birthday +
                      ", sex='" + sex + '\'' +
                      ", address='" + address + '\'' +
                      ", ids=" + ids +
                      ", accounts=" + accounts +
                      '}';
          }
      }
    3. 在 UserMapper 接口中定义方法:
      public interface UserMapper {
          //查询一对多
          public List<User>  findOneToMony();
      
      }
    4. 编写配置文件:
      <?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.qcby.mapper.UserMapper">
      
          <!-- 配置 resultMap,用来进行数据封装
              id="唯一的名称,用来被引用的唯一标识"
              type="进行封装数据的类型"
          -->
          <resultMap id="userMap" type="com.qcby.model.User">
              <!-- property="JavaBean 中的属性"-->
              <!-- colum="表中的字段"-->
              <result property="id" column="id"/>
              <result property="username" column="username"/>
              <result property="birthday" column="birthday"/>
              <result property="sex" column="sex"/>
              <result property="address" column="address"/>
              <collection property="accounts" ofType="com.qcby.model.Account">
                  <result property="money" column="money"/>
              </collection>
          </resultMap>
      
          <!-- 一对多查询 -->
          <select id="findOneToMony" resultMap="userMap">
              select u.*,a.money from user u left join account a on u.id = a.uid;
          </select>
      
      </mapper>
    5. 编写测试方法:
      public class Demo01 {
       
          /**
          * 一对多查询
          */
          @Test
          public void findOneToMoney() throws IOException {
              //加载主配置文件到输入流
              InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
              //创建 SqlSessionFactory 对象,创建 SqlSession 对象
              SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
      
              //创建 SqlSession 对象
              SqlSession session = factory.openSession();
      
              //获取代理对象
              UserMapper userMapper = session.getMapper(UserMapper.class);
      
              List<User> oneToMony = userMapper.findOneToMony();
      
              for (User u : oneToMony){
                  System.out.println(u);
              }
      
              //关闭资源
              session.close();
              inputStream.close();
          }
      }

第二章:多对多查询

  1. 执行 SQL 语句,创建表结构:
    CREATE TABLE `role` (
      `ID` int(11) NOT NULL COMMENT '编号',
      `ROLE_NAME` varchar(30) default NULL COMMENT '角色名称',
      `ROLE_DESC` varchar(60) default NULL COMMENT '角色描述',
      PRIMARY KEY  (`ID`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ​
    insert  into `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) values (1,'组长','管理整个组'),(2,'班主任','管理整个班级'),(3,'校长','管理整个学校');
    ​
    CREATE TABLE `user_role` (
      `UID` int(11) NOT NULL COMMENT '用户编号',
      `RID` int(11) NOT NULL COMMENT '角色编号',
      PRIMARY KEY  (`UID`,`RID`),
      KEY `FK_Reference_10` (`RID`),
      CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
      CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
    ​
    insert  into `user_role`(`UID`,`RID`) values (1,1),(1,2),(2,2);
  2. 编写 JavaBean 对象:
    public class Role implements Serializable {
        private static final long serialVersionUID = 4836306672907553166L;
    
        private Integer id;
        private String role_name;
        private String role_desc;
    
        private User user;
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getRole_name() {
            return role_name;
        }
    
        public void setRole_name(String role_name) {
            this.role_name = role_name;
        }
    
        public String getRole_desc() {
            return role_desc;
        }
    
        public void setRole_desc(String role_desc) {
            this.role_desc = role_desc;
        }
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        @Override
        public String toString() {
            return "Role{" +
                    "id=" + id +
                    ", role_name='" + role_name + '\'' +
                    ", role_desc='" + role_desc + '\'' +
                    ", user=" + user +
                    '}';
        }
    }
  3. 编写接口:
    public interface RoleMapper {
         public List<Role> findAll();
    }
  4. 编写配置文件:
    <?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.qcby.mapper.RoleMapper">
    
        <resultMap id="roleMap" type="com.qcby.model.Role">
            <result property="id" column="id"/>
            <result property="role_name" column="role_name"/>
            <result property="role_desc" column="role_desc"/>
            <collection property="user" ofType="com.qcby.model.User">
                <result property="username" column="username"/>
            </collection>
        </resultMap>
    
        <select id="findAll" resultMap="roleMap">
            select r.*,u.username from user u,user_role ur,role r where u.id = ur.UID and ur.RID = r.ID;
        </select>
    </mapper>
  5. 编写 SqlMapConfig.xml 配置文件:
    <!-- 加载映射的配置文件 -->
    <mappers>
        <mapper resource="Mapper/UserMapper.xml"/>
        <mapper resource="Mapper/AccountMapper.xml"/>
        <mapper resource="Mapper/RoleMapper.xml"/>
    </mappers>
  6. 编写测试类:
    public class Demo01 {
    
        @Test
        public void run() throws IOException {
            //加载配置文件
            InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
    
            //创建工厂对象
            SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    
            //构建 session
            SqlSession session = factory.openSession();
    
            RoleMapper roleMapper = session.getMapper(RoleMapper.class);
    
            List<Role> all = roleMapper.findAll();
            for (Role r: all){
                System.out.println(r);
            }
    
            session.close();
            in.close();
        }
    }

原文地址:https://blog.csdn.net/SOS_suyan/article/details/145312051

免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!