MyBatis 關聯關係的實現之一對一

 

有2個實體:用戶、會員卡,一個用戶只能辦理一張會員卡,即一對一。java

 

 

user_tb : 引入card_tb的主鍵card_no做爲外鍵。sql

 

 

card_tb:數據庫

 

 


 

 

方式一:使用擴展類實現一對一

(1)在pojo包下新建User類:

package com.chy.pojo;

public class User {
    private Integer id;  //主鍵
    private String name;  //姓名
    private String tel;  //手機號
    private String address;  //地址

    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 getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", tel='" + tel + '\'' +
                ", address='" + address + '\'' +
                '}';
    }
}

 

 

(2)在pojo包下新建User的擴展類UserExt,繼承User,並把Card的屬性添加進來,提供對應的getter、setter方法。

package com.chy.pojo;

public class UserExt extends User {
    private Integer no;
    private float money;

    public Integer getNo() {
        return no;
    }

    public void setNo(Integer no) {
        this.no = no;
    }

    public float getMoney() {
        return money;
    }

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

    @Override
    public String toString() {
        return super.toString()+",Card{" +
                "no=" + no +
                ", money=" + money +
                '}';
    }
}

先alt+insert插入toString(),再拼接上User的toString(),而後修改下就ok。apache

 

 

(3)編寫UserMapper接口、UserMapper.xml

package com.chy.mapper;

import com.chy.pojo.UserExt;

public interface UserMapper {
    public UserExt queryUserExtById(Integer id);
}
<?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.chy.mapper.UserMapper">
    <select id="queryUserExtById" parameterType="integer" resultType="userext">
        SELECT user_tb.*,card_tb.* FROM user_tb,card_tb WHERE user_tb.id=#{id} AND user_tb.card_no=card_tb.no
     </select>
</mapper>

 

 

(4)使用

package com.chy.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

 

     SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        UserExt userExt = mapper.queryUserExtById(1);
        System.out.println(userExt);
        sqlSession.close();

 

 

總結

  • 使用擴展類實現一對一,主要靠映射文件中的sql語句,寫的sql語句每每很複雜
  • 由於要在「一」中添加另外一個「一」的屬性,若是另外一個「一」的屬性較多,添加起來就比較麻煩,即適合屬性少的
  • 沒有體現實體之間的關聯關係(一個pojo中包含另外一個pojo)

 

 


 

 

方式二:使用嵌套查詢實現一對一

(1)給2個「一」都編寫pojo類,須要在一個「一」中關聯另外一個「一」

package com.chy.pojo;

public class User {
    private Integer id;  //主鍵
    private String name;  //姓名
    private String tel;  //手機號
    private String address;  //地址
    private Card card;  //與之關聯的另外一個「一」

    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 getTel() {
        return tel;
    }

    public void setTel(String tel) {
        this.tel = tel;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public Card getCard() {
        return card;
    }

    public void setCard(Card card) {
        this.card = card;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", tel='" + tel + '\'' +
                ", address='" + address + '\'' +
                ", card=" + card +
                '}';
    }
}

 

package com.chy.pojo;

public class Card {
    private Integer no;  //會員卡編號
    private Float money;  //餘額

    public Integer getNo() {
        return no;
    }

    public void setNo(Integer no) {
        this.no = no;
    }

    public Float getMoney() {
        return money;
    }

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

    @Override
    public String toString() {
        return "Card{" +
                "no=" + no +
                ", money=" + money +
                '}';
    }
}

 

 

(2)給這2個pojo類都編寫Mapper接口、xml映射文件

public interface CardMapper {
    public Card queryCardByUserId(Integer no);
}
<?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.chy.mapper.CardMapper">
    <select id="queryCardByNo" parameterType="integer" resultType="card">
        SELECT * FROM card_tb WHERE no=#{no}
     </select>
</mapper>

 

 

package com.chy.mapper;

import com.chy.pojo.User;

public interface UserMapper {
    public User queryUserById(Integer id);
}
<?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.chy.mapper.UserMapper">
    <select id="queryUserById" parameterType="integer" resultMap="userResultWithCard">
        SELECT * FROM user_tb WHERE id=#{id}
     </select>
    <resultMap id="userResultWithCard" type="user">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
        <association property="card" column="card_no" javaType="card" select="com.chy.mapper.CardMapper.queryCardByNo"/>
    </resultMap>
</mapper>

sql語句都是查詢當前pojo類對應的數據表,但UserMapper使用<resultMap>的<association>元素指定了嵌套查詢。session

  • property屬性指定當前pojo類中表示另外一個「一」的屬性名
  • column屬性指定當前數據表中關聯另外一個「一」的列(外鍵)
  • javaType屬性指定與當前pojo類關聯的另外一個「一」的數據類型。
  • select屬性指定要使用的另外一個「一」的哪一個sql元素關聯(namespace+id),執行當前<select>查詢時,會自動嵌套另外一個「一」的<select>進行查詢。

 

 

(3)使用

package com.chy.utils;

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 java.io.IOException;
import java.io.InputStream;

public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    static {
        try {
            InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

 

package com.chy.test;

import com.chy.mapper.UserMapper;
import com.chy.pojo.User;
import com.chy.utils.MyBatisUtils;
import org.apache.ibatis.session.*;
import java.io.IOException;

public class Test {
    public static void main(String[] args) {
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user = mapper.queryUserById(1);
        System.out.println(user);
        sqlSession.close();
    }
}

 

總結:

使用嵌套查詢體現了實體之間的關聯關係,但一條查詢會觸發另外一個與之關聯的查詢,另外一個查詢若是有與之關聯的查詢,也會觸發.....鏈式反應,極大地下降了查詢效率和數據庫的性能,不推薦。mybatis

 

 


 

 

方式三:使用嵌套結果實現一對一

其餘步驟與嵌套查詢同樣,不一樣的有2點:app

(一)UserMapper.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.chy.mapper.UserMapper">
    <select id="queryUserById" parameterType="integer" resultMap="userResultWithCard">
        SELECT user_tb.*,card_tb.* FROM user_tb,card_tb WHERE id=#{id}
     </select>
    <resultMap id="userResultWithCard" type="user">
        <id property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="tel" column="tel"/>
        <result property="address" column="address"/>
        <association property="card" javaType="card">
            <id property="no" column="card_no"/>
            <result property="money" column="money"/>
        </association>
    </resultMap>
</mapper>

sql語句變了,由於是一次查詢,因此要查到全部須要的數據。ide

  • property屬性指定表示另外一個「一」的屬性名(成員變量名)
  • javaType指定另外一個「一」的數據類型
  • <id>元素是關鍵,property指定另外一個「一」的pojo類的哪一個屬性是主鍵,column指定哪一個列與另外一個「一」關聯(外鍵)。
  • <result>配置另外一個「一」的映射

 

 

(二)由於不須要嵌套CardMapper的<select>進行查詢,因此不須要CardMapper接口、CardMapper.xml。

 

總結

嵌套結果體現了實體之間的關聯關係,且要寫的代碼更少,配置簡單。推薦使用。性能

相關文章
相關標籤/搜索