1. 程式人生 > >MyBatis:註解簡化一對一關係

MyBatis:註解簡化一對一關係

上期

註解式是真的好用!

一對一的關係:客戶擁有一張身份證,而身份證也只有一個客戶。

 

客戶表中有身份證的cid,可以通過這個cid匹配身份證表中的cid,拿到那個具體的身份證資訊

反之,身份證通過本身的cid匹配客戶表中的cid,以此得到客戶的資訊。

 

/*
Navicat MySQL Data Transfer

Source Server         : hc
Source Server Version : 50723
Source Host           : localhost:3306
Source Database       : cn

Target Server Type    : MYSQL
Target Server Version : 50723
File Encoding         : 65001

Date: 2018-11-07 15:32:01
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for `person`
-- ----------------------------
DROP TABLE IF EXISTS `person`;
CREATE TABLE `person` (
  `perId` int(11) NOT NULL AUTO_INCREMENT,
  `perName` varchar(255) DEFAULT NULL,
  `cardId` int(11) NOT NULL,
  PRIMARY KEY (`perId`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of person
-- ----------------------------
INSERT INTO `person` VALUES ('1', 'haha', '1');
INSERT INTO `person` VALUES ('2', '維爾瓦', '2');
INSERT INTO `person` VALUES ('3', '阿三', '3');
INSERT INTO `person` VALUES ('4', '32阿瑟東', '4');
INSERT INTO `person` VALUES ('5', '安撫', '5');

MYsql中的表,copy後匯入資料庫即可。

<dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>


        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.43</version>
        </dependency>

pom.xml 

package com.hc.model;

public class Person {
    private int perId;
    private String perName;
    private Card card;

    public Person() {
    }

    public Person(String perName) {
        this.perName = perName;
    }

    public int getPerId() {
        return perId;
    }

    public void setPerId(int perId) {
        this.perId = perId;
    }

    public String getPerName() {
        return perName;
    }

    public void setPerName(String perName) {
        this.perName = perName;
    }

    public Card getCard() {
        return card;
    }

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

}

Person類

 

package com.hc.model;

public class Card {
    private int cardId;
    private String cardName;
    private Person person;

    public Card() {
    }

    public Card(String cardName) {
        this.cardName = cardName;
    }

    public int getCardId() {
        return cardId;
    }

    public void setCardId(int cardId) {
        this.cardId = cardId;
    }

    public String getCardName() {
        return cardName;
    }

    public void setCardName(String cardName) {
        this.cardName = cardName;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}

卡類

package com.hc.mapper;

import com.hc.model.Person;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface PersonMapper {
    @Select("select * from Person")
    @Results({
            @Result(property = "card",column = "cardId",one = @One(select = "com.hc.mapper.CardMapper.selectCardByCid"))
    })
    public List<Person> allPerson();

    @Select("select * from Person where cardId=#{cardId}")
    public Person selectPersonByCid(int cardId);

}

person的MApper

person中有card的物件屬性,

Results中的Result,property 為物件屬性名,column 為關聯的id,

因為person與card相關聯的就是cardid

把cid傳給關聯物件Mapper中的方法,並獲得需要的資料

one相對應的是一個物件,如果是多個,即為many

@one中的select固定,呼叫關聯物件Mapper中的方法

 

package com.hc.mapper;

import com.hc.model.Card;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface CardMapper {
    @Select("select * from Card where cardId=#{cardId}")
    public Card selectCardByCid(int cardId);

    @Select("select * from Card")
    @Results({
            @Result(id = true,property = "cardId",column = "cardId"),
//            關聯 id 必須
            @Result(property = "person",column = "cardId",one = @One(select = "com.hc.mapper.PersonMapper.selectPersonByCid"))
    })
    public List<Card> allCard();
}

卡的Mapper

selectCardByCid:看似只是一個條件查詢,其實可以被Person mapper中的一對一方法@one呼叫

第二個方法,cardid是必須要拿到的,宣告id=true

否則,最終的資料中拿不到這個cid

但是,不宣告,又能拿到card物件,只是cid為0

 

<?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>
    <typeAliases>
        <package name="com.hc.model"/>
    </typeAliases>


    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/cn?characterEncoding=utf-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper class="com.hc.mapper.UserMapper"/>
        <mapper class="com.hc.mapper.PersonMapper"/>
        <mapper class="com.hc.mapper.CardMapper"/>
        <mapper class="com.hc.mapper.AuthorMapper"/>
        <mapper class="com.hc.mapper.BookMapper"/>
        <mapper class="com.hc.mapper.CourseMapper"/>
        <mapper class="com.hc.mapper.StudentMapper"/>
    </mappers>

</configuration>

mybatis-config.xml

物件Mapper一定要加到mappers中

package com.hc.test;

import com.hc.mapper.CardMapper;
import com.hc.mapper.PersonMapper;
import com.hc.model.Card;
import com.hc.model.Person;
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;

public class TestPerson {

    private SqlSession session;


    @Before
    public void before() {
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(getClass().getClassLoader().getResourceAsStream("myBatis-config.xml"));
        session = factory.openSession();


    }

    @Test
    public void testCard() {
        CardMapper cardMapper = session.getMapper(CardMapper.class);
        for (Card card : cardMapper.allCard()) {
            System.out.println(card.getCardId() + "\t《" + card.getCardName() + "》");
            Person person = card.getPerson();
            System.out.println(person.getPerId() + "\t" + person.getPerName());
            System.out.println("");
        }
    }

    @Test
    public void testPerson() {
        PersonMapper personMapper;
        personMapper = session.getMapper(PersonMapper.class);
        for (Person person : personMapper.allPerson()) {
            System.out.println(person.getPerId() + "\t" + person.getPerName());
            Card card = person.getCard();
            System.out.println(card.getCardId() + "\t《" + card.getCardName() + "》");
            System.out.println("");
        }
    }

    @After
    public void after() {
        session.commit();
        session.close();
    }

}

單元測試

第二個測試方法:拿到所有person,並通過person表的cid,去卡表拿到相對應的card物件。

第一個方法:

拿到所有的card,通過本身的cid,匹配person的cid,取得person物件。