转载

Mybatis基于xml方式实现的多表操作(增删改查)

  • 基于xml方式实现的多对多增删改查操作(一对多原理类似)
  • 基于xml方式实现的多对一增删改查操作(mybatis默认多对一 为一对一)

pom.xml导入Mybatis项目依赖坐标

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>mybatis_01</artifactId>
        <groupId>com.baoji.mybatis</groupId>
        <version>1.0-SNAPSHOT</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>mybatis_05_duobiao</artifactId>
    <packaging>jar</packaging>
    <!-- 配置mybatis所需要的jar包-->
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.2</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.44</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.12</version>
        </dependency>
    </dependencies>


</project>
复制代码

基于xml方式实现的多对多增删改查操作

第一步(配置主配置文件)

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">
<!-- mybatis 主配置文件 -->
<configuration>
    <!-- 配置properties
            可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置信息
            resource 属性: 常用的  (resource="jdbcConfig.properties")
            用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。
            url属性:
                是要求按照url的属性来写地址
                URL:  统一资源定位符,可以唯一标识一个资源的位置
                    例如 http://localhost:8080/mybatis/servlet
                         协议    主机    端口号   uri
                uri:  统一资源标识符 ,在应用中可以唯一定位一个资源的
            -->
    <properties>
        <!--配置连接数据库的四个基本信息-->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis_user?characterEncoding=gbk"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>
    <!-- 使用typeAliases起别名,它只能配置entity中类的别名-->
    <typeAliases>
        <!-- typeAlias用于配置别名,type属性指的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
        <!-- <typeAlias type="com.baoji.mybatis.entity.User" alias="user"></typeAlias> -->
        <!-- 用于要配置起别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不区分大小写-->
        <package name="com.baoji.mybatis.entity"/>
    </typeAliases>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的配置环境 -->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的四个基本信息-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <!-- mybatis的映射配置文件位置必须和dao接口的文件位置相同,包名相同时,不需要实现dao接口 -->
    <mappers>
        <!-- <mapper resource="com/baoji/mybatis/dao/IUserDao.xml"></mapper> -->
        <!-- package用于指定dao接口所在的包,当指定了之后就不需要再写mapper和resource以及class了-->
        <package name="com.baoji.mybatis.dao"/>
    </mappers>
</configuration>
复制代码

第二步(数据库创建多张表)

sql语句:
复制代码
DROP DATABASE IF EXISTS `mybatis_user`;
CREATE DATABASE IF NOT EXISTS mybatis_user DEFAULT CHARACTER SET='utf8';
USE mybatis_user;

-- 用户表
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;

SELECT * FROM USER;
-- 工资表
CREATE TABLE account(
  `ID` INT(11) NOT NULL COMMENT '编号',
  `UID` INT(11) DEFAULT NULL COMMENT '用户编号',
  `MONEY` DOUBLE DEFAULT NULL COMMENT '金额',
  PRIMARY KEY  (`ID`)	
) ENGINE=INNODB DEFAULT CHARSET=utf8;

DROP TABLE IF EXISTS `role`;

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,'校长','管理整个学校');
SELECT * FROM role;

DROP TABLE IF EXISTS `user_role`;

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 (41,1),(45,1),(41,2);
SELECT * FROM user_role;

-- 动态向工资表中添加员工外键
ALTER TABLE account ADD CONSTRAINT FK_Reference_01 FOREIGN KEY(uid) REFERENCES USER(id);

INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龙'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龙'),(45,'张三','2018-03-04 12:04:06','男','北京金燕龙'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小马宝莉','2018-03-08 11:44:00','女','北京修正');
INSERT  INTO `account`(`ID`,`UID`,`MONEY`) VALUES (1,46,1000),(2,45,1000),(3,46,2000);
SELECT * FROM USER;
SELECT * FROM account;
DELETE FROM USER WHERE id = 49;
复制代码

第三步(编写操作的实体类)

User.java  
    //多对多的映射关系   一个用户对应多个角色
    private List<Role> roles;

    public List<Role> getRoles() {
        return roles;
    }
     public void setRoles(List<Role> roles) {
        this.roles = roles;
    }
复制代码
package com.baoji.mybatis.entity;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable {
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //多对多的映射关系   一个用户对应多个角色
    private List<Role> roles;

    public List<Role> getRoles() {
        return roles;
    }

    public void setRoles(List<Role> roles) {
        this.roles = roles;
    }

    public int getId() {
        return id;
    }

    public void setId(int 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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '/'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '/'' +
                ", address='" + address + '/'' +
                '}';
    }
}
复制代码
Role.java
      //多对多的关系映射  一个角色赋予多个用户

    private List<User> users;

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }
复制代码
package com.baoji.mybatis.entity;

import java.io.Serializable;
import java.util.List;

public class Role implements Serializable {
    private int id;
    private String roleName;
    private String roleDesc;

    //多对多的关系映射  一个角色赋予多个用户

    private List<User> users;

    public List<User> getUsers() {
        return users;
    }

    public void setUsers(List<User> users) {
        this.users = users;
    }

    public int getId() {
        return id;
    }

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

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '/'' +
                ", roleDesc='" + roleDesc + '/'' +
                '}';
    }
}
复制代码

第四步(编写dao接口)

IUserDao.dao
复制代码
package com.baoji.mybatis.dao;

import com.baoji.mybatis.entity.User;

import java.util.List;

public interface IUserDao {
    //查询所有用户信息
    List<User> findAll();
}
复制代码
IRole.Dao
复制代码
package com.baoji.mybatis.dao;

import com.baoji.mybatis.entity.Role;

import java.util.List;

public interface IRoleDao {
    //查询所有角色信息
    List<Role> findAll();
}
复制代码

第五步(映射配置文件Mapper.xml)

IRoleMapper.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.baoji.mybatis.dao.IRoleDao">
    <resultMap id="roleMap" type="role">
        <id property="id" column="ID"></id>
        <result property="roleName" column="ROLE_NAME"></result>
        <result property="roleDesc" column="ROLE_DESC"></result>
            <!-- 配置集合关系映射-->
        <!--
         property : 封装用户的属性名
         ofType : 返回对象类型
            -->
        <collection property="users" ofType="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="birthday" column="birthday"></result>
            <result property="sex" column="sex"></result>
            <result property="address" column="address"></result>
        </collection>
    </resultMap>
    //按角色查询所对应的用户信息
    <select id="findAll" resultMap="roleMap">
        select u.*,r.id as rid,r.role_name,r.role_desc from role r
        left outer join user_role ur on r.id = ur.rid
        left outer join user u on u.id = ur.uid
    </select>
</mapper>
复制代码
IUserDao.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.baoji.mybatis.dao.IUserDao">
        <resultMap id="userRoleMap" type="user">
            <!-- 封装角色集合的关系映射 -->
            <collection property="roles" ofType="role">
                <id property="id" column="id"></id>
                <result property="roleName" column="ROLE_NAME"></result>
                <result property="roleDesc" column="ROLE_DESC"></result>
            </collection>
        </resultMap>
    //按用户查询所对应的角色信息
    <select id="findAll" resultMap="userRoleMap">
        select u.*,r.id as rid,r.role_name,r.role_desc from user u
        left outer join user_role ur on u.id = ur.uid
        left outer join role r on r.id = ur.rid
    </select>
</mapper>
复制代码

第六步(编写测试类)

IUser.test
复制代码
package com.baoji.mybatis.test;

import com.baoji.mybatis.dao.IUserDao;
import com.baoji.mybatis.entity.User;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserTest {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private IUserDao userDao;
    //编写初始化方法(将重复代码封装至此)

    @Before  //此注解是在测试方法之前执行
    public void init() throws IOException {
        //1、读取配置文件
        in = Resources.getResourceAsStream("SqlMapperConfig.xml");
        //2、创建sqlSessionFactory工厂
        factory = new SqlSessionFactoryBuilder().build(in);
        //3、使用工厂创建sqlSession对象
        sqlSession = factory.openSession();
        //4、使用sqlSession获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }
    @After  //此注解实在测试方法之后执行
    //创建关闭资源方法
    public void destory() throws IOException {
        //提交事务两种方式(只有提交事务,数据库才能插入成功)
        //方式一:关闭资源前添加提交事务(sqlSession.commit();)
        //方式二:在创建sqlSession时事务参数设置为true
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @Test
    //查询所有用户信息
    public void test(){
        List<User> list = userDao.findAll();
        for(User users:list){
            System.out.println("每个用户的信息");
            System.out.println(users);
            System.out.println(users.getRoles());
        }
    }

}
复制代码
IRole.test
复制代码
package com.baoji.mybatis.test;

import com.baoji.mybatis.dao.IRoleDao;
import com.baoji.mybatis.dao.IUserDao;
import com.baoji.mybatis.entity.Role;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class RoleTest {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private IRoleDao roleDao;
    //编写初始化方法(将重复代码封装至此)

    @Before  //此注解是在测试方法之前执行
    public void init() throws IOException {
        //1、读取配置文件
        in = Resources.getResourceAsStream("SqlMapperConfig.xml");
        //2、创建sqlSessionFactory工厂
        factory = new SqlSessionFactoryBuilder().build(in);
        //3、使用工厂创建sqlSession对象
        sqlSession = factory.openSession();
        //4、使用sqlSession获取dao的代理对象
        roleDao = sqlSession.getMapper(IRoleDao.class);
    }
    @After  //此注解实在测试方法之后执行
    //创建关闭资源方法
    public void destory() throws IOException {
        //提交事务两种方式(只有提交事务,数据库才能插入成功)
        //方式一:关闭资源前添加提交事务(sqlSession.commit();)
        //方式二:在创建sqlSession时事务参数设置为true
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }
    @Test
    public void test(){
        //查询所有角色
        List<Role> list = roleDao.findAll();
        for(Role roles:list){
            System.out.println("每个角色的信息");
            System.out.println(roles);
            System.out.println(roles.getUsers());
        }
    }
}
复制代码

项目目录截图

Mybatis基于xml方式实现的多表操作(增删改查)

基于xml方式实现的多对一增删改查操作

第一步(配置主配置文件)

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">
<!-- mybatis 主配置文件 -->
<configuration>
    <!-- 配置properties
            可以在标签内部配置连接数据库的信息,也可以通过属性引用外部配置信息
            resource 属性: 常用的  (resource="jdbcConfig.properties")
            用于指定配置文件的位置,是按照类路径的写法来写,并且必须存在于类路径下。
            url属性:
                是要求按照url的属性来写地址
                URL:  统一资源定位符,可以唯一标识一个资源的位置
                    例如 http://localhost:8080/mybatis/servlet
                         协议    主机    端口号   uri
                uri:  统一资源标识符 ,在应用中可以唯一定位一个资源的
            -->
    <properties>
        <!--配置连接数据库的四个基本信息-->
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatis_user?characterEncoding=gbk"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </properties>
    <!-- 使用typeAliases起别名,它只能配置entity中类的别名-->
        <typeAliases>
        <!-- typeAlias用于配置别名,type属性指的是实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
       <!-- <typeAlias type="com.baoji.mybatis.entity.User" alias="user"></typeAlias> -->
            <!-- 用于要配置起别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不区分大小写-->
        <package name="com.baoji.mybatis.entity"/>
    </typeAliases>
    <!-- 配置环境 -->
    <environments default="mysql">
        <!-- 配置mysql的配置环境 -->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的四个基本信息-->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!-- 指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件 -->
    <!-- mybatis的映射配置文件位置必须和dao接口的文件位置相同,包名相同时,不需要实现dao接口 -->
    <mappers>
        <!-- <mapper resource="com/baoji/mybatis/dao/IUserDao.xml"></mapper> -->
        <!-- package用于指定dao接口所在的包,当指定了之后就不需要再写mapper和resource以及class了-->
        <package name="com/baoji/mybatis/dao"/>
    </mappers>
</configuration>
复制代码

第二步(编写实体类)

Account.java
     //一对多:从表实体应该包含一个主表实体的引用
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }
复制代码
package com.baoji.mybatis.entity;

import java.io.Serializable;

public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private double money;
    //一对多:从表实体应该包含一个主表实体的引用
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.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 double getMoney() {
        return money;
    }

    public void setMoney(double money) {
        this.money = money;
    }

    @Override
    public String toString() {
        return "Account{" +
                "id=" + id +
                ", uid=" + uid +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}

复制代码
User.java
复制代码
package com.baoji.mybatis.entity;

import com.sun.xml.internal.messaging.saaj.packaging.mime.util.LineInputStream;

import java.io.Serializable;
import java.util.Date;
import java.util.List;

public class User implements Serializable {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

 
    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;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '/'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '/'' +
                ", address='" + address + '/'' +
                '}';
    }
}
复制代码

第三步(配置dao层)

IAccountDao.java
复制代码
package com.baoji.mybatis.dao;

import com.baoji.mybatis.entity.Account;
import com.baoji.mybatis.entity.AccountUser;

import java.util.List;

public interface IAccountDao {
    //查询所有账号
    public List<Account> findAll();
    //查询所有账号下用户的账户名和地址
    public List<AccountUser> findAllAccount();
}
复制代码
IUserDao.java
复制代码
package com.baoji.mybatis.dao;

import com.baoji.mybatis.entity.User;

import java.util.List;

public interface IUserDao {
    //查询所有用户信息,同时获取用户下所用账户的信息
    public List<User> findAll();
    //根据id查询用户信息
    public User findById(Integer id);
}
复制代码

第四步(映射配置文件Mapper.xml)

Mapper.xml
复制代码
IAccountDao.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.baoji.mybatis.dao.IAccountDao">
    <!-- 定义封装account和user的resultMap-->
    <resultMap id="accountUserMap" type="account">
         <id property="id" column="id"></id>
         <result property="uid" column="uid"></result>
         <result property="money" column="money"></result>
         <!-- 一对一的关系映射 封装user-->
    <!--
     property:表示对应的关联属性
     column: 表示外键关联的字段
     javaType: 表示要返回的对象类型
     association: 配置一对一映射关系
        -->
    <association property="user" column="uid" javaType="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
    </association>
</resultMap>
        <!-- 查询所有操作 -->
<select id="findAll" resultMap="accountUserMap">
        select u.*,a.id as aid,a.uid,a.money from user as u,account as a where u.id = a.uid;
    </select>
    <!-- 查询账户下用户的账户名和地址信息 -->
    <select id="findAllAccount" resultType="accountuser">
        select a.*,u.username,u.address from user as u,account as a where u.id = a.uid;
    </select>

</mapper>
复制代码
IUserDao.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.baoji.mybatis.dao.IUserDao">
    <!-- 配置user的resultMap -->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="birthday" column="birthday"></result>
        <result property="sex" column="sex"></result>
        <result property="address" column="address"></result>
            <!-- 配置user对象中accounts集合的映射关系-->
        <!--
            property: 代表实体类封装的集合变量名
            ofType: 代表集合所返回的对象
        -->
            <collection property="accounts" ofType="account">
               <id property="id" column="aid"></id>
                <result property="uid" column="uid"></result>
                <result property="money" column="money"></result>
            </collection>
    </resultMap>
    <!-- 查询所有操作 -->
    <select id="findAll" resultMap="userAccountMap">
        select * from user as u left outer join account as a on u.id = a.uid
    </select>
    <!-- 根据id查询信息 -->
    <select id="findById" parameterType="int" resultType="user">
        select * from user where id = #{id}
    </select>
</mapper>
复制代码

第五步(编写测试类)

AccountTest.java
复制代码
package com.baoji.mybatis.test;

import com.baoji.mybatis.dao.IAccountDao;

import com.baoji.mybatis.entity.Account;
import com.baoji.mybatis.entity.AccountUser;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class AccountTest {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private IAccountDao dao;
    //编写初始化方法(将重复代码封装至此)

    @Before  //此注解是在测试方法之前执行
    public void init() throws IOException {
        //1、读取配置文件
        in = Resources.getResourceAsStream("Config.xml");
        //2、创建sqlSessionFactory工厂
        factory = new SqlSessionFactoryBuilder().build(in);
        //3、使用工厂创建sqlSession对象
        sqlSession = factory.openSession();
        //4、使用sqlSession获取dao的代理对象
        dao = sqlSession.getMapper(IAccountDao.class);
    }
    @After  //此注解实在测试方法之后执行
    //创建关闭资源方法
    public void destory() throws IOException {
        //提交事务两种方式(只有提交事务,数据库才能插入成功)
        //方式一:关闭资源前添加提交事务(sqlSession.commit();)
        //方式二:在创建sqlSession时事务参数设置为true
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @Test
    //查询所有信息
    public void testFindAll(){
        List<Account> list = dao.findAll();
        for(Account accounts:list){
            System.out.println(accounts);
            System.out.println(accounts.getUser());
        }
    }
    @Test
    //查询所有信息
    public void testFindAllAccount(){
        List<AccountUser> list = dao.findAllAccount();
        for(Account accounts:list){
            System.out.println(accounts);
        }

    }
}
复制代码
IUserTest.java
复制代码
package com.baoji.mybatis.test;

import com.baoji.mybatis.dao.IUserDao;
import com.baoji.mybatis.entity.User;
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.After;
import org.junit.Before;
import org.junit.Test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class UserTest {
    private InputStream in;
    private SqlSessionFactory factory;
    private SqlSession sqlSession;
    private IUserDao userDao;
    //编写初始化方法(将重复代码封装至此)

    @Before  //此注解是在测试方法之前执行
    public void init() throws IOException {
        //1、读取配置文件
        in = Resources.getResourceAsStream("Config.xml");
        //2、创建sqlSessionFactory工厂
        factory = new SqlSessionFactoryBuilder().build(in);
        //3、使用工厂创建sqlSession对象
        sqlSession = factory.openSession();
        //4、使用sqlSession获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }
    @After  //此注解实在测试方法之后执行
    //创建关闭资源方法
    public void destory() throws IOException {
        //提交事务两种方式(只有提交事务,数据库才能插入成功)
        //方式一:关闭资源前添加提交事务(sqlSession.commit();)
        //方式二:在创建sqlSession时事务参数设置为true
        sqlSession.commit();
        sqlSession.close();
        in.close();
    }

    @Test
    //查询所有信息
    public void testFindAll(){
        List<User> list = userDao.findAll();
        for(User users:list){
            System.out.println("每个用户的信息");
            System.out.println(users);
            System.out.println(users.accounts);
        }
        }
}
复制代码

敲黑板

特别注意:

dao接口所在的包名一定要和xml配置文件的位置一致(包括包名称和位置) 如果不一致会报

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found) 异常

org.apache.ibatis.binding.BindingException: Invalid bound statement (not found)问题,即在mybatis中dao接口与mapper配置文件在做映射绑定的时候出现问题,简单说,就是接口与xml要么是找不到,要么是找到了却匹配不到。

Mybatis基于xml方式实现的多表操作(增删改查)

照着修改之后,问题依旧存在。最终花费了好大的力气才找到自己代码问题的根源。dao接口与xml的文件名不一致。

接口名与接口文件名都是DepartmentDao, 而配置文件名为DeparmentDao.xml,费了很大的劲才看到两者名字查一个t字母。修改后就一切正常了。

这是一个很容易忽视的点。

记住:接口名与Mybatis的映射文件名一定要一模一样。

原文  https://juejin.im/post/5dc5645ee51d45092d32cfcd
正文到此结束
Loading...