Mybatis進階之表之間的關係

Mybatis

輸入映射 支持的類
    八大基礎數據類型
    list map pojo
    包裝類型
    可以通過對象導航的方式不斷向下獲取
    例如:#{user.username}
輸出映射
    八大基礎數據類型
    list map pojo
    輸出包裝類型時 需要自動映射字段

根據ID查找對象

User.java

package com.lanou.bean;

public class User {
    private int id;
    private String name;
    private String password;
    private String sex;
    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 getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", sex=" + sex + "]";
    }

}

根據ID查找對象

public interface UserDao {
    // 根據ID查找對象
    public User findUserById(int id);

}

UserDao.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.lanou.dao.UserDao">
    <select id="findUserById" parameterType="Integer" resultType="User" >
        select * from User where id = #{param}
    </select>
</mapper>

MybatisTest.java

public class MybatisTest {
    @Test
    public void test() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = builder.build(inputStream);
        SqlSession session = factory.openSession();
        UserDao dao = session.getMapper(UserDao.class);
        User user = dao.findUserById(6);
        System.out.println(user);
    }
}

使用包裝類

UserDataObj.java

package com.lanou.bean;

public class UserDataObj {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "UserDataObj [user=" + user + "]";
    }
}

UserDao.java

public interface UserDao {
    // 根據ID查找對象
    public User findUserById(int id);
    // 使用包裝類添加對象
    public int insertUserByUserDataObj(UserDataObj obj);
}

UserDao.xml

<mapper  namespace="com.lanou.dao.UserDao">
    <select id="findUserById" parameterType="Integer" resultType="User" >
        select * from User where id = #{param}
    </select>

    <insert id="insertUserByUserDataObj" parameterType="UserDataObj">
        insert into user values (
        null,
        #{user.name},
        #{user.password},
        #{user.sex}
        )
    </insert>
</mapper>

MybatisTest.java

public void test1() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    User user = new User();
    user.setName("劉邦");
    user.setPassword("12345");
    user.setSex("男");
    UserDataObj obj = new UserDataObj();
    obj.setUser(user);
    UserDao dao = session.getMapper(UserDao.class);
    int i = dao.insertUserByUserDataObj(obj);
    System.out.println(i);
    session.commit();
}

標籤根據多個id查詢一堆user

根據一堆id查詢user, id in (1,2,3) foreach標籤用來遍歷參數
collection 指定被遍歷的集合
item 每一次遍歷得到的變量seperator
open 開始標記
close 結束標記

UserDao.java

public interface UserDao {
    // 根據ID查找對象
    public User findUserById(int id);
    // 使用包裝類添加對象
    public int insertUserByUserDataObj(UserDataObj obj);

    public List<User> selectUserByIds(Integer[] ids);
}

UserDao.xml

當我們傳的參數是一個數組時
java中沒有對應的包裝類型
可以寫object 也可以不寫
parameterType 作用是規範書寫 怕你轉錯類型

遍歷數組時 參數的名字是固定的 array
遍歷ArrayList時 參數的名字是固定的 list
Mybatis參數映射的原理
其實就是把你傳過來的參數轉成map 以鍵值對的方式傳遞
所以基礎數據類型的獲取方式是${value} value也是固定的


<select id="selectUserByIds" parameterType="java.lang.Object" resultType="User">
    select * from user where id in
    <foreach collection="array" item="item" separator="," open="(" close=")">
        #{item}
    </foreach>
</select>

MybatisTest.java

public void test2() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    Integer[] ids = new Integer[] {6,10,11}; 
    UserDao dao = session.getMapper(UserDao.class);
    List<User> list = dao.selectUserByIds(ids);
    for (User user : list) {
        System.out.println(user);
    }
}

將參數Integer[]改爲List

UserDao.java

public interface UserDao {
    // 根據ID查找對象
    public User findUserById(int id);
    // 使用包裝類添加對象
    public int insertUserByUserDataObj(UserDataObj obj);

    public List<User> selectUserByIds(List<Integer> ids);
}

UserDao.xml

<select id="selectUserByIds" parameterType="java.util.List" resultType="User">
    select * from user where id in
    <foreach collection="list" item="item" separator="," open="(" close=")">
        #{item}
    </foreach>
</select>

MybatisTest.java

public void test2() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    List<Integer> list = new ArrayList<>();
    list.add(6);
    list.add(10);
    UserDao dao = session.getMapper(UserDao.class);
    List<User> list2 = dao.selectUserByIds(list);
    for (User user : list2) {
        System.out.println(user);
    }
}

常用標籤

條件判斷

根據姓名和性別同時查詢

UserDao.java

public interface UserDao {
    // 根據ID查找對象
    public User findUserById(int id);
    // 使用包裝類添加對象
    public int insertUserByUserDataObj(UserDataObj obj);
    // 根據一組id進行查詢
    public List<User> selectUserByIds(List<Integer> ids);
    // 根據姓名和性別同時進行查詢
    public User getUser(User u);
}

UserDao.xml

之所以需要1=1 因爲如果name爲空 則不加1=1時 sql語句爲
select * from user where and sex = #{sex} 
或sex爲空 
select * from user where and name = #{sex} 
當加上1=1select * from user where 1=1 and sex = #{sex} 
select * from user where 1=1 and name = #{name} 
select * from user where 1=1 and name = #{name} and sex = #{sex} 


<select id="getUser" parameterType="User" resultType="User">
    select * from user where 1=1
    <if test="name != null and name != ''">
        and name = #{name}
    </if>
    <if test="sex != null and name !=''">
        and sex = #{sex}
    </if>
</select>

UserDao.xml

public void test3() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
    User user = new User();
    user.setName("劉邦");
    user.setSex("男");
    UserDao dao = session.getMapper(UserDao.class);
    User user2 = dao.getUser(user);
    System.out.println(user2);
}

where標籤

where標籤的作用 執行內部的邏輯並拼接到外部的sql中 會自動刪除第一個and

<select id="getUser" parameterType="User" resultType="User">
    select * from user 
    <where>
        <if test="name != null and name != ''">
            and name = #{name}
        </if>
        <if test="sex != null and name !=''">
            and sex = #{sex}
        </if>
    </where>
</select>

sql標籤

如果有很多重複的sql語句 沒有必要每次寫 可以對它進行抽取
<sql id="selectUser">
    select * from User
</sql>

<select id="findUserById" parameterType="int" resultType="com.lanou.bean.User">
    <include refid="selectUser"></include> where id = #{param}
</select>

一對多查詢

在數據庫中建立兩張表 分別爲user和orders user爲主表 orders爲從表 orders中有一個鍵是外鍵
參照user主表中的id

AutoMapping 設爲true 可以自動將列名與屬性名稱對應數據映射
    一對一 javaType用來指定集合內元素的類型 必須寫 否則空指針異常

實現:
    在查詢user數據時自動查詢出對應的orders數據
    1.實體類中添加屬性
    2.接口中添加方法
    3.mapper實現sql
    4.手動映射關聯數據

user類

user與orders是一對多的關係 user中需要一個集合 用來保存orders中的信息
package com.lanou.bean;

import java.util.List;

public class User {
    private int id;
    private String name;
    private String password;
    private String sex;
    private List<Orders> orders;
    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 getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public List<Orders> getOrders() {
        return orders;
    }
    public void setOrders(List<Orders> orders) {
        this.orders = orders;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", sex=" + sex + ", orders=" + orders
                + "]";
    }
}

Orders.java

package com.lanou.bean;

public class Orders {
    private int id;
    private String name;
    private double price;
    private int 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;
    }
    public double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    @Override
    public String toString() {
        return "Orders [id=" + id + ", name=" + name + ", price=" + price + ", userid=" + userid + "]";
    }
}

UserDao.java

public interface UserDao {
    // 選擇用戶及其對應的訂單
    public List<User> selectUsersAndOrders();
}

UserDao.xml

<mapper  namespace="com.lanou.dao.UserDao">

    <resultMap type="User" id="UserMap" autoMapping="true">
        <result property="id" column="u_id"/>
        <result property="name" column="u_name"/>
        <collection property="orders" autoMapping="true" ofType="Orders">
            <result property="name" column="o_name"/>
            <result property="id" column="o_id"/>
        </collection>
    </resultMap>


    <select id="selectUsersAndOrders" resultMap="UserMap">
        SELECT *,
        User.id as u_id,
        User.name as u_name,
        Orders.name as o_name,
        Orders.id as o_id
        FROM User left join Orders 
        ON User.id = Orders.userid
    </select>
</mapper>

MybatisTest.java

public class MybatisTest {
    @Test
    public void test3() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = builder.build(inputStream);
        SqlSession session = factory.openSession();
        UserDao dao = session.getMapper(UserDao.class);
        List<User> list = dao.selectUsersAndOrders();
        for (User user : list) {
            System.out.println(user);
        }
    }
}

一對一查詢

一個員工可以有多張訂單 一張訂單對應一個員工 從員工角度看 員工與訂單是一對多關係
從訂單角度看 訂單與員工是一對一關係 即一張訂單對應一個員工 

實現:獲取訂單時 自動獲取user
創建映射文件 添加方法用來獲取所有訂單數據

Orders.java

public class Orders {
    private int id;
    private String name;
    private double price;
    private int userid;
    private User user;


    public User getUser() {
        return user;
    }
    public void setUser(User user) {
        this.user = user;
    }
    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 double getPrice() {
        return price;
    }
    public void setPrice(double price) {
        this.price = price;
    }
    public int getUserid() {
        return userid;
    }
    public void setUserid(int userid) {
        this.userid = userid;
    }
    @Override
    public String toString() {
        return "Orders [id=" + id + ", name=" + name + ", price=" + price + ", userid=" + userid + ", user=" + user
                + "]";
    }
}

OrderDao.java

public interface OrderDao {
    public List<Orders> selectAllOrdersAndUser();
}

OrderDao.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.lanou.dao.OrderDao">
    <resultMap type="Orders" id="OrdersMap" autoMapping="true">
        <result property="id" column="o_id"/>
        <result property="name" column="o_name"/>
        <association property="user" autoMapping="true" javaType="User">
            <result property="id" column="u_id"/>
            <result property="name" column="u_name"/>
        </association>
    </resultMap>

    <select id="selectAllOrdersAndUser" resultMap="OrdersMap">
        select *,
        Orders.id as o_id,
        Orders.name as o_name,
        User.id as u_id,
        User.name as u_name
        from Orders left join
        User on Orders.userid = User.id
    </select>
</mapper>

MybatisTest2.java

public class MybatisTest2 {
    @Test
    public void test3() throws IOException {
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory factory = builder.build(inputStream);
        SqlSession session = factory.openSession();
        OrderDao dao = session.getMapper(OrderDao.class);
        List<Orders> list = dao.selectAllOrdersAndUser();
        for (Orders orders : list) {
            System.out.println(orders);
        }
    }
}

多對多

現有group和user
  需求 查詢user同時查詢相關的groups
  需求 查詢groups 同時查詢相關的user

建立user表 建立groups表 兩表之間的聯繫是一張中間表

Groups.java

package com.lanou.bean;

import java.util.List;

public class Groups {
    private int g_id;
    private String g_name;
    private String g_msg;
    private String g_manager;

    private List<User> users;

    public int getG_id() {
        return g_id;
    }

    public void setG_id(int g_id) {
        this.g_id = g_id;
    }

    public String getG_name() {
        return g_name;
    }

    public void setG_name(String g_name) {
        this.g_name = g_name;
    }

    public String getG_msg() {
        return g_msg;
    }

    public void setG_msg(String g_msg) {
        this.g_msg = g_msg;
    }

    public String getG_manager() {
        return g_manager;
    }

    public void setG_manager(String g_manager) {
        this.g_manager = g_manager;
    }

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

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

    @Override
    public String toString() {
        return "groups [g_id=" + g_id + ", g_name=" + g_name + ", g_msg=" + g_msg + ", g_manager=" + g_manager
                + ", users=" + users + "]";
    }
}

User.java

package com.lanou.bean;

import java.util.List;

public class User {
    private int id;
    private String name;
    private String password;
    private String sex;
    private List<Groups> groups;
    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 getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public List<Groups> getGroups() {
        return groups;
    }
    public void setGroups(List<Groups> groups) {
        this.groups = groups;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", password=" + password + ", sex=" + sex + ", groups=" + groups
                + "]";
    }

}

UserDao.java

public interface UserDao {
    // 選擇用戶及其對應的羣組
    public List<User> selectUsersAndGroups();
}

UserDao.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.lanou.dao.UserDao">

    <resultMap type="User" id="UserMap" autoMapping="true">
        <result property="id" column="id"/>
        <collection property="groups" autoMapping="true" ofType="Groups">
        </collection>
    </resultMap>
    <select id="selectUsersAndGroups" resultMap="UserMap">
        select *
        from user 
        left join u_r_g on user.id = u_r_g.uid
        left join groups on u_r_g.gid = groups.g_id
    </select>
</mapper>

MybatisTest3.java

public void test3() throws IOException {
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory factory = builder.build(inputStream);
    SqlSession session = factory.openSession();
     UserDao dao = session.getMapper(UserDao.class);
     List<User> user = dao.selectUsersAndGroups();
     for (User user2 : user) {
        System.out.println(user2);
    }
}

這裏寫圖片描述

Groups對User

groupsDao.java

public interface groupsDao {
    // 獲取所有羣組和對應的用戶
    public List<Groups> selectAllGroups();
}

groupsDao.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.lanou.dao.groupsDao">
    <resultMap type="Groups" id="GroupsMap" autoMapping="true">
        <result property="id" column="id"/>
        <collection property="users" ofType="User" autoMapping="true">  
        </collection>
    </resultMap>

    <select id="selectAllGroups" resultMap="GroupsMap">
        select * FROM
        groups left join u_r_g on groups.g_id = u_r_g.gid
        left join user on u_r_g.uid = user.id
    </select>
</mapper>

MybatisTestnVnTest3.java

public class MybatisTestnVnTest3 {
    @Test
    public void testFun1() throws IOException{
        // 構建器
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        // 讀取配置文件
        InputStream input = Resources.getResourceAsStream("SqlMapConfig.xml");
        // 1.獲取會話工廠
        SqlSessionFactory factory = builder.build(input);
        // 2.獲取會話
        SqlSession session = factory.openSession();
        // 3.crud
        groupsDao mapper = session.getMapper(groupsDao.class);
        List<Groups> groups = mapper.selectAllGroups();
        for (Groups groups2 : groups) {
            System.out.println(groups2);
        }

    }
}

這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章