1. 程式人生 > >MyBatis之基於XML的表之間映射

MyBatis之基於XML的表之間映射

rop iat mage ati 也有 9.png font out 既然

數據庫表之間的關系有3種,一對一、一對多、多對多。既然是ORM,這肯定是必須有的。在學習EF的時候也有涉及,今天就是參考著EF的來學習下MyBatis的表關系映射。

一、準備工作

1.準備Model和Table

既然是要涉及表的一對一、一對多、多對多的關系,那肯定得先準備好實體關系,以及表。下面建了四個對象四個表。User<->Card是一對一關系,User<->Course一對多關系,User<->Role多對多關系。

User

技術分享圖片
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `NAME` 
varchar(20) DEFAULT NULL, `age` int(11) DEFAULT NULL, `status` varchar(20) DEFAULT 0, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
View Code 技術分享圖片
package Cuiyw.MyBatis.Model;

import java.util.List;

public class User {
    @Override
    public String toString() {
        
// TODO Auto-generated method stub return "User [id=" + Id + ", name=" + Name + ", age=" + Age + ",status="+Status+"]"; } public int getId() { return Id; } public void setId(int id) { Id = id; } public String getName() { return Name; }
public void setName(String name) { Name = name; } public int getAge() { return Age; } public void setAge(int age) { Age = age; } private int Id; private String Name; private int Age; private UserState Status; private Card card; public Card getCard() { return card; } public void setCard(Card card) { this.card = card; } private List<Role> roles; private List<Course> courses; public List<Course> getCourses() { return courses; } public void setCourses(List<Course> courses) { this.courses = courses; } public List<Role> getRoles() { return roles; } public void setRoles(List<Role> roles) { this.roles = roles; } public UserState getStatus() { return Status; } public void setStatus(UserState status) { this.Status = status; } }
View Code

Card

技術分享圖片
CREATE TABLE `card` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `cardNo` varchar(20) NOT NULL,
  `city` varchar(45) NOT NULL,
  `address` varchar(100) NOT NULL,
  `userid` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
View Code 技術分享圖片
package Cuiyw.MyBatis.Model;

public class Card {
    
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return  "Card [id=" + getId() + ", cardNo=" + cardNo + ", city=" + city + ",address="+address+",userid="+userid+"]";

    }
    private int id;
    private String cardNo;
    private String city;
    private String address;
    private int userid;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getCardNo() {
        return cardNo;
    }
    public void setCardNo(String cardNo) {
        this.cardNo = cardNo;
    }
    public String getCity() {
        return city;
    }
    public void setCity(String city) {
        this.city = city;
    }

}
View Code

Course

技術分享圖片
CREATE TABLE `course` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `userid` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
View Code 技術分享圖片
package Cuiyw.MyBatis.Model;

public class Course {

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return  "Course [id=" + getId() + ", name=" + name +",userid="+userid+"]";

    }
    private int id;
    private String name;
    private int userid;
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}
View Code

Role

技術分享圖片
CREATE TABLE `role` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `desp` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
View Code 技術分享圖片
package Cuiyw.MyBatis.Model;

import java.util.List;

public class Role {
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return  "Role [id=" + getId() + ", name=" + name +",desp="+desp+"]";

    }
    private int id;
    private String name;
    private String desp;
    private List<User> users;
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDesp() {
        return desp;
    }
    public void setDesp(String desp) {
        this.desp = desp;
    }
    public List<User> getUsers() {
        return users;
    }
    public void setUsers(List<User> users) {
        this.users = users;
    }
}
View Code

User_Role

技術分享圖片
CREATE TABLE `user_role` (
  `userid` int(11) NOT NULL,
  `roleid` int(11) NOT NULL,
  PRIMARY KEY (`userid`,`roleid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
View Code

2.準備映射

上一篇博客是單個表的映射關系,我們也先把但表的映射準備好。

技術分享圖片
    <resultMap type="Card" id="cardResult">
        <result column="id" property="id"/>
        <result column="no" property="cardNo"/>
        <result column="city" property="city"/>
        <result column="address" property="address"/>
        <result column="userid" property="userid"/>
    </resultMap>

    <resultMap type="Course" id="courseResult">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="userid" property="userid"/>
    </resultMap>
    <resultMap type="Role" id="roleResult">
        <result column="id" property="id"/>
        <result column="name" property="name"/>
        <result column="desp" property="desp"/>
        <result column="userid" property="userid"/>
    </resultMap>
View Code

二、關系映射

加入我們需要執行下面的sql查詢數據,那怎麽映射到實體model上呢?

技術分享圖片
    <select id="getuser" parameterType="int" 
        resultType="User" resultMap="userResult">
        select a.id as user_id,a.name as user_name,a.age as user_age,a.status as user_status,
b.id as card_id,b.cardNo as card_cardNo,b.userid as card_userid,
b.city as card_city,b.address as card_address,c.id as course_id,c.name as course_name,
c.userid as course_userid,e.name as role_name,e.desp as role_desp 
from user a left join card b on a.id=b.userid            
left join course c on a.id=c.userid 
left join user_role d on a.id=d.userid 
left join role e on d.roleid=e.id where a.id=#{id}
    </select>
View Code

技術分享圖片

我們可以這樣寫來映射User。

技術分享圖片
    <resultMap type="User" id="userResult">
        <result column="user_id" property="id"/>
        <result column="user_name" property="name"/>
        <result column="user_age" property="age"/>
        <result column="user_status" property="status" typeHandler="Cuiyw.MyBatis.Model.ValuedEnumTypeHandler"/>
        <association property="card" javaType="Card" columnPrefix="card_">
            <result column="id" property="id"/>
            <result column="no" property="cardNo"/>
            <result column="city" property="city"/>
            <result column="address" property="address"/>
            <result column="userid" property="userid"/>
        </association>
        <collection property="courses" javaType="ArrayList" ofType="Course" columnPrefix="course_">
            <result column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="userid" property="userid"/>
        </collection>
        <collection property="roles" javaType="ArrayList" ofType="Role" columnPrefix="role_">
            <result column="id" property="id"/>
            <result column="name" property="name"/>
            <result column="desp" property="desp"/>
            <result column="userid" property="userid"/>
        </collection>
    </resultMap>
View Code

上面的xml種有兩個重要的節點。

association關聯:關聯的結果查詢,就是在查詢出結果後,根據查詢的列和resultMap定義的對應關系,來創建對象並寫入值,例如user的card屬性。

collection:用來映射class中的List列表類型的屬性。

還有就是JavaType和ofType:JavaType和ofType都是用來指定對象類型的,但是JavaType是用來指定pojo中屬性的類型,而ofType指定的是映射到list集合屬性中pojo的類型。

三、優化

上面的xml配置確實可以映射User,但是在映射Card、Course和Role的時候把映射關系都放在的id=userResult的resultMap中,這樣如果以後還有要映射Card、Course、Role的時候還要再寫一遍,復用性不高。其實我們可以在association和collection節點增加屬性resultMap。

技術分享圖片
    <resultMap type="User" id="userResult">
        <result column="user_id" property="id"/>
        <result column="user_name" property="name"/>
        <result column="user_age" property="age"/>
        <result column="user_status" property="status" typeHandler="Cuiyw.MyBatis.Model.ValuedEnumTypeHandler"/>
        <association property="card" javaType="Card" resultMap="cardResult" columnPrefix="card_"></association>
        <collection property="courses" javaType="ArrayList" ofType="Course" resultMap="courseResult" columnPrefix="course_"></collection>
        <collection property="roles" javaType="ArrayList" ofType="Role" resultMap="roleResult" columnPrefix="role_"></collection>
    </resultMap>
View Code

而resultMap的值正是我們上面單表準備的映射resultMap。

四、驗證

技術分享圖片
        //mybatis的配置文件
        String resource = "Config.xml";
        //使用MyBatis提供的Resources類加載mybatis的配置文件(它也加載關聯的映射文件)
        Reader reader = Resources.getResourceAsReader(resource); 
        //構建sqlSession的工廠
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        //創建能執行映射文件中sql的sqlSession
        SqlSession session = sessionFactory.openSession(true);
//        System.out.println("新增");
        String statement="Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
        System.out.println("查詢單個");
         statement="Cuiyw.MyBatis.DBMapping.UserMapper.getuser";
         User user=session.selectOne(statement, 2);
         Card card=user.getCard();
         
         List<Course>courses=user.getCourses();
         List<Role>roles=user.getRoles();
         session.close();
         System.out.println(user.toString());
         System.out.println(card.toString());
         for(int i=0;i<courses.size();i++)
         {
             System.out.println(courses.get(i).toString());
         }
         for(int i=0;i<roles.size();i++)
         {
             System.out.println(roles.get(i).toString());
         }
View Code

技術分享圖片

五、總結

這篇主要是學習表的關系映射,association、collection的使用,上面演示了一對一、一對多,對於多對多,可以把它當作兩個一對多,這裏只是演示了User對Role的一對多,Role對User的也是一樣,這裏就省了。具體可以參考官網:http://www.mybatis.org/mybatis-3/zh/sqlmap-xml.html

MyBatis之基於XML的表之間映射