mybatis黑马:表格操作(一对一、一对多)


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>
    <!--使用typeAliases配置别名,它只能配置domain中类的别名 -->
    <typeAliases>
        <!--typeAlias用于配置别名。type属性指定的是实体类全限定类名。alias属性指定别名,当指定了别名就再区分大小写
        <typeAlias type="com.jh.domain.User" alias="user"></typeAlias>-->

        <!-- 用于指定要配置别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
        <package name="com.jh.domain"></package>
    </typeAliases>

    <!--配置环境-->
    <environments default="mysql">
        <!--配置mysql的环境-->
        <environment id="mysql">
            <!--配置事务的类型-->
            <transactionManager type="JDBC"></transactionManager>
            <!--配置数据源(连接池)-->
            <dataSource type="POOLED">
                <!--配置连接数据库的4个基本信息-->
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?serverTimezone=GMT%2B8"/>
                <property name="username" value="root"/>
                <property name="password" value="jh7851192"/>
            </dataSource>
        </environment>
    </environments>

    <!--指定映射配置文件的位置,映射配置文件指的是每个dao独立的配置文件-->
    <mappers>
        <!--<mapper resource="com/jh/dao/IUserDao.xml"/>-->
        <!-- package标签是用于指定dao接口所在的包,当指定了之后就不需要在写mapper以及resource或者class-->
        <package name="com.jh.dao"></package>
    </mappers>
</configuration>

1. 一对一映射:一个用户(user)对一个账户(account)

(1)要在IAccountDao.xml中配置account和user的resultMap,还有属性名和查询列名对应关系,如下:
在这里插入图片描述
(2)sql内连接查询语句如下(返回类型是Account实体类)
resultMap=“accountUserMap”–>type=“account”

  <!--配置查询所有-->
    <select id="findAll" resultMap="accountUserMap">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;<!--内连接:account a,user u逗号是join,where是on-->
    </select>

(3)代码:(User,Account,IAccountDao,AccountTest,IAccountDao.xml)

Account.java主体类

  • 属性名与account表字段名相关;
  • 从表(account)实体应该包含一个主表(user)实体的对象引用: private User user
  • 省略了set和get,toString方法
package com.jh.domain;
import java.io.Serializable;
/**
 * 账户信息:一对一映射:一个用户(user)对一个账户(account)
 * */
public class Account implements Serializable {
    private Integer id;
    private Integer uid;
    private Double money;
    //一对一映射要求:从表(account)实体应该包含一个主表(user)实体的对象引用
    private User user;
}

IAccountDao接口

package com.jh.dao;
import com.jh.domain.Account;
import com.jh.domain.AccountUser;
import java.util.List;
/**
 * 查询所有账户,同时还要获取到当前账户的所属用户信息
 * 一对一映射:一个用户(user)对一个账户(account)
 * */
public interface IAccountDao {
    //1.查询所有账户
    List<Account> findAll();
    //2.查询所有账户,并且带有用户名称和地址信息
    List<AccountUser> findAllAccount();
}

一对一测试AccountTest.java

package com.jh.test;
/**一对一映射:一个用户(user)对一个账户(account)*/
import com.jh.dao.IAccountDao;
import com.jh.domain.Account;
import com.jh.domain.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.InputStream;
import java.util.List;
public class AccountTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IAccountDao accountDao;
    @Before//用于在测试方法执行之前执行
    public void init() throws Exception {
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory工厂模式
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession(true);//手动提交事务
        //4.获取dao的代理对象
        accountDao = sqlSession.getMapper(IAccountDao.class);
    }
    @After//用于在测试方法执行之后执行
    public void destroy() throws Exception {
        /*//提交事务
        sqlSession.commit();*/
        //6.释放资源
        sqlSession.close();
        in.close();
    }
    //一对一映射:一个用户(user)对一个账户(account)如下:
    public void testfindAll() {
        List<Account> accounts = accountDao.findAll();
        for (Account account : accounts) {
            System.out.println("---每个account的信息:包括account和user");
            System.out.println(account);
            System.out.println(account.getUser());
        }
    }
}

结果:

一对一映射:一个用户(user)对一个账户(account)---每个account的信息:包括account和user
Account{id=1, uid=46, money=1000.0}
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}
---每个account的信息:包括account和user
Account{id=2, uid=45, money=1000.0}
User{id=45, username='传智播客', address='北京金燕龙', sex='男', birthday=Sun Mar 04 12:04:06 CST 2018}
---每个account的信息:包括account和user
Account{id=3, uid=46, money=2000.0}
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}

2. 一对多映射:一个用户(user)对多个账户(account)

(1)在IUserDao.xml中配置二者关系
在这里插入图片描述
(2)sql外连接查询语句(返回类型User)

<!--配置查询所有-->
    <select id="findAll" resultMap="userAccountMap">
         select * from user u left outer join account a on u.id = a.uid<!--左外连接,左边user作主表-->
    </select>

(3)代码:(Account,User,IUserDao,UserTest,IUserDao.xml)

User.java

  • User属性名与user表字段名相关
  • 主表实体应该包含从表实体的集合引用
    private List< Account>accounts;
  • 省略set和get,toString()方法
package com.jh.domain;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**一对多关系映射:一个用户(user)对多个账户(account)*/
public class User implements Serializable {
    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;
    //一对多关系映射:主表实体应该包含从表实体的集合引用
    private List<Account>accounts;
}

IUserDao.java接口

package com.jh.dao;
import com.jh.domain.User;
import java.util.List;
/**
 * 用户的持久层接口:
 * 一对多关系映射:一个用户(user)对多个账户(account)
 * */
public interface IUserDao {
    //1.查询所有用户,同时获取到用户下所有账户的信息
    List<User>findAll();
    //2.根据id查询用户信息
    User findById(Integer userId);
}

UserTest.java一对多测试类

package com.jh.test;
/**一对多关系映射:一个用户(user)对多个账户(account)*/
import com.jh.dao.IUserDao;
import com.jh.domain.Account;
import com.jh.domain.AccountUser;
import com.jh.domain.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.InputStream;
import java.util.List;
public class UserTest {
    private InputStream in;
    private SqlSession sqlSession;
    private IUserDao userDao;
    @Before//用于在测试方法执行之前执行
    public void init() throws Exception {
        //1.读取配置文件,生成字节输入流
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2.获取SqlSessionFactory工厂模式
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //3.获取SqlSession对象
        sqlSession = factory.openSession(true);//手动提交事务
        //4.获取dao的代理对象
        userDao = sqlSession.getMapper(IUserDao.class);
    }

    @After//用于在测试方法执行之后执行
    public void destroy() throws Exception {
        /*//提交事务
        sqlSession.commit();*/
        //6.释放资源
        sqlSession.close();
        in.close();
    }
    @Test
    public void testfindAll() {
        List<User> users = userDao.findAll();
        for (User user : users) {
            System.out.println("---每个用户的信息:包括account和user");
            System.out.println(user);
            System.out.println(user.getAccounts());
        }
    }
}

结果:

测试查询所有(一对多关系映射结果):抽取一个一对多的,"一个老王对2个账户"
User{id=46, username='老王', address='北京', sex='男', birthday=Wed Mar 07 17:37:26 CST 2018}
[Account{id=null, uid=46, money=1000.0}, Account{id=null, uid=46, money=2000.0}]

3. 2个完整的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.jh.dao.IAccountDao">
<!--一对一映射:一个用户(user)对一个账户(account)--> 
    <!--定义封装account和user的resultMap -->
    <resultMap id="accountUserMap" type="account">
        <id property="id" column="aid"></id>
        <result property="uid" column="uid"></result>
        <result property="money" column="money"></result>
        <!--一对一的关系映射:配置封装user的内容:以uid这个字段来获取关系映射-->
        <association property="user" column="uid" javaType="user">
            <id property="id" column="id"></id>
            <result property="username" column="username"></result>
            <result property="address" column="address"></result>
            <result property="sex" column="sex"></result>
            <result property="birthday" column="birthday"></result>
        </association>
    </resultMap>

    <!--配置查询所有-->
    <select id="findAll" resultMap="accountUserMap">
        select u.*,a.id as aid,a.uid,a.money from account a,user u where u.id=a.uid;<!--内连接:account a,user u逗号是join,where是on-->
    </select>

    <!--查询账户和用户信息-->
    <select id="findAllAccount" resultType="accountuser">
        select a.*,u.username,u.address from account a,user u where u.id=a.uid;
    </select>

    <!--根据id查询用户-->
    <select id="findById" parameterType="INT" resultType="com.jh.domain.Account">
        select * from account where id=#{Uid}<!--这里id命名无所谓-->
    </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.jh.dao.IUserDao">
<!--一对多关系映射:一个用户(user)对多个账户(account)-->

    <!-- 定义User的resultMap-->
    <resultMap id="userAccountMap" type="user">
        <id property="id" column="id"></id>
        <result property="username" column="username"></result>
        <result property="address" column="address"></result>
        <result property="sex" column="sex"></result>
        <result property="birthday" column="birthday"></result>
        <!-- 配置user对象中accounts集合的映射 -->
        <collection property="accounts" ofType="account">
            <id column="aid" property="id"></id>
            <result column="uid" property="uid"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>

    <!--配置查询所有-->
    <select id="findAll" resultMap="userAccountMap">
         select * from user u left outer join account a on u.id = a.uid<!--左外连接,左边user作主表-->
    </select>

    <!--根据id查询用户-->
    <select id="findById" parameterType="INT" resultType="com.jh.domain.User">
        select * from user where id=#{Uid}<!--这里id命名无所谓-->
    </select>

    <!--了解的内容:抽取重复的sql语句-->
    <sql id="defaultUser">
        select * from user
    </sql>
</mapper>
发布了88 篇原创文章 · 获赞 14 · 访问量 4891

猜你喜欢

转载自blog.csdn.net/JH39456194/article/details/104362146