Mybatis筆記4

来源:https://www.cnblogs.com/train99999/archive/2019/07/16/11198105.html
-Advertisement-
Play Games

mybatis中多對多的步驟 示例:用戶和角色,一個用戶可以有多個角色,一個角色可以賦予多個用戶 步驟: 1. 建立兩張表:用戶表,角色表,讓用戶表和角色表具有多對多的關係,需要使用中間表,中間表中包含兩張表的主鍵,在中間表中是外鍵 2. 建立兩個實體類:用戶實體類和角色實體類,讓用戶和角色的實體類 ...


mybatis中多對多的步驟

示例:用戶和角色,一個用戶可以有多個角色,一個角色可以賦予多個用戶

步驟:

  1. 建立兩張表:用戶表,角色表,讓用戶表和角色表具有多對多的關係,需要使用中間表,中間表中包含兩張表的主鍵,在中間表中是外鍵
  2. 建立兩個實體類:用戶實體類和角色實體類,讓用戶和角色的實體類能體現出來多對多的關係,各自包含對方一個集合引用
  3. 建立兩個配置文件,用戶的配置文件,角色的配置文件
  4. 實現配置:當我們查詢用戶時,可以同時得到用戶所包含的角色信息,當我們查詢角色時,可以同時得到角色的所賦予的用戶信息

資料庫表的創立

img

實體類的建立

用戶實體類

package com.itheima.domain;

import java.io.Serializable;
import java.util.Date;
import java.util.List;


public class User implements Serializable {

    private Integer id;
    private String username;
    private String address;
    private String sex;
    private Date birthday;

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

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getAddress() {
        return address;
    }

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

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

角色實體類

package com.itheima.domain;

import java.io.Serializable;

public class Role implements Serializable {
    private Integer roleId;
    private String roleName;
    private String roleDesc;

    public Integer getRoleId() {
        return roleId;
    }

    public void setRoleId(Integer roleId) {
        this.roleId = roleId;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "roleId=" + roleId +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }
}

映射文件配置

用戶映射文件

<?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.itheima.dao.IUserDao">
    <!--定義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>
    </resultMap>
    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
       SELECT * FROM USER u LEFT OUTER JOIN account a ON u.id=a.uid;
    </select>

    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{uid}
    </select>
</mapper>

角色映射文件

<?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.itheima.dao.IRoleDao">
    <!--定義role表的ResultMap-->
<resultMap id="roleMap" type="role">
    <id property="roleId" column="id"></id>
    <result property="roleName" column="role_name"></result>
    <result property="roleDesc" column="role_desc"></result>
</resultMap>
    <!--查詢所有-->
  <select id="findAll" resultMap="roleMap">
      select * from role;
  </select>
</mapper>

測試類

package com.itheima.test;

import com.itheima.dao.IRoleDao;
import com.itheima.dao.IUserDao;
import com.itheima.domain.Role;
import com.itheima.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;

/**
 * @author 黑馬程式員
 * @Company http://www.ithiema.com
 *
 * 測試mybatis的crud操作
 */
public class RoleTest {

    private InputStream in;
    private SqlSession sqlSession;
    private IRoleDao roleDao;

    @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的代理對象
        roleDao = sqlSession.getMapper(IRoleDao.class);
    }

    @After//用於在測試方法執行之後執行
    public void destroy()throws Exception{
        //提交事務
       // sqlSession.commit();
        //6.釋放資源
        sqlSession.close();
        in.close();
    }

    @Test
    //查詢所有賬戶,同時包含用戶名稱和地址
    public void testFindAllAccountUser(){
        List<Role> roles = roleDao.findAll();
        for(Role role:roles){
            System.out.println(role);
        }

    }


}

單表操作成功

img

實現配置:當我們查詢角色時,可以同時得到角色的所賦予的用戶信息

首先實體類需要添加一個屬性

private List<User> users;

SQL語句的寫法

SELECT u.*,r.id AS rid ,r.role_name,role_desc FROM role r
LEFT OUTER JOIN user_role ur ON r.id=ur.rid
LEFT OUTER JOIN USER u ON u.id = ur.uid;

img

img

有了SQL語句就可以寫映射配置文件了

<?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.itheima.dao.IUserDao">
    <!--定義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>
    </resultMap>
    <!-- 查詢所有 -->
    <select id="findAll" resultMap="userAccountMap">
       SELECT * FROM USER u LEFT OUTER JOIN account a ON u.id=a.uid;
    </select>

    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user">
        select * from user where id = #{uid}
    </select>
</mapper>

img

實現配置:當我們查詢用戶時,可以同時得到用戶所包含的角色信息,

SQL語句寫法

SELECT u.*,r.id AS rid ,r.role_name,role_desc FROM USER u
LEFT OUTER JOIN user_role ur ON u.id=ur.uid
LEFT OUTER JOIN role r ON r.id = ur.rid;

JNDI

JNDI(Java Naming and Directory Interface Java命名和目錄介面)是SUN公司提供的一種標準的Java命名系統介面。目的是模仿windows系統中的註冊表

Mybatis中的延遲載入

問題:在一對多中,當我們有一個用戶,他有100個賬戶。在查詢用戶的時候,要不要把關聯的賬戶查出來?在查詢賬戶的時候,要不要把關聯的用戶查出來?

在查詢用戶時,用戶下的賬戶信息應該是,什麼時候使用,什麼時候載入。

在查詢賬戶時,賬戶的所屬用戶信息應該是隨著賬戶查詢是一起查詢出來。

什麼是延遲載入:在真正使用數據時才發起查詢,不用的時候不查詢,按需載入(懶載入)0.

什麼是立即載入:不管用不用,只要一調用方法,馬上發起查詢。

在對應的四種表關係中:一對多,多對多通常採用延遲載入,多對一,一對一:通常採用立即載入。

Mybatis中的緩存

什麼是緩存:存在於記憶體中的 臨時數據

一級緩存:指定是Mybatis中SqlSession對象的緩存,當我們執行查詢後,查詢的結果會同時存入到SqlSession為我們提供一塊區域中,該區域的結構是一個map。當我們再次查詢同樣的數據,mybatis會先去sqlsession中查詢是否有,有的話直接拿出來用,當SqlSession對象消失是,mybatis一級緩存也就消失了

二級緩存:它指的是Mybatis中SqlSessionFactory對象的 緩存,由同一個SqlSessionFactory對象創建的SqlSession共用其緩存

二級 緩存的使用步驟:

第一步:讓Mybatis框架支持二級緩存(SqlMapConfig.xml中配置)

<settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

第二步:讓當前的映射文件支持二級緩存(在IUserDao.xml中配置)

 <!--開啟user支持二級緩存-->
    <cache/>

第三步:讓當前的操作支持二級緩存(select標簽中配置)

    <!-- 根據id查詢用戶 -->
    <select id="findById" parameterType="INT" resultType="user" useCache="true">
        select * from user where id = #{uid}
    </select>

test類

public void testFirstLevelCache(){
        SqlSession sqlSession1 = factory.openSession();
        IUserDao dao1 = sqlSession1.getMapper(IUserDao.class);
        User user1 = dao1.findById(41);
        System.out.println(user1);
        sqlSession1.close();//一級緩存消失

        SqlSession sqlSession2 = factory.openSession();
        IUserDao dao2 = sqlSession2.getMapper(IUserDao.class);
        User user2 = dao2.findById(41);
        System.out.println(user2);
        sqlSession2.close();

        System.out.println(user1 == user2);
    }

img

mybatis使用註解開發

package com.itheima.dao;

import com.itheima.domain.User;
import org.apache.ibatis.annotations.Select;

import java.util.List;
//在mybatis中,有CRUD一共四個註解
//@Select @Insert @Update @Delete
public interface IUserDao {
    //查詢所有
    @Select("select * from user")
    List<User> findAll();
}

img


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • vector 是最簡單、最常用的數據存儲形式。 vector 似乎一組可以通過索引來訪問的順序存儲的數據元素。 我們可以用 vector 名和索引號的組合來表示一個具體的數據元素 例如:v[0]是5,v[1]是7。 vector 的索引號總是從“0”開始,每次加1. vector “知道自己的大小” ...
  • 經過接近1個月的時間,ElasticSearch6.x實戰教程終於成冊。這本實戰教程小冊有很多不足(甚至可能有錯誤),也是第一次完整推出一個系列的教程。 1年前,我開始真正接觸ES,在此之前僅停留在知道的階段,甚至連瞭解都算不上。1年後跳槽,新的知識新的領域爆炸式的噴涌而出,分散式、ES、Redis ...
  • 消費組和消費者 1. 消費組和消費者是一對多的關係。 2. 同一個消費組的消費者可以消費多個分區,且是獨占的。 3. 消費者的分區分配策略由介面 定義,內置三種分配策略 、`RoundRobinAssignor StickyAssignor`,支持自定義策略。 4. 不同消費組可以消費相同的分區,互 ...
  • 題目 不同路徑 1 一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。 機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。 問總共有多少條不同的路徑? 輸入說明 例如,上圖是一個 7 x 3 的網格。有多少可能的路 ...
  • ![img](https://mmbiz.qpic.cn/mmbiz_jpg/1flHOHZw6Rs7yEJ6ItV43JZMS7AJWoMSZtxicnG0iaE0AvpUHI8oM7lxz1rRsmaa4IfbolVRG2WQwhXrchmVWS8Q/640?tp=webp&wxfrom=5&w ...
  • 二維數組遍歷: 外迴圈控制的是二維數組的長度,其實就是一維數組的個數。 內迴圈控制的是一維數組的長度。 外迴圈控制的是二維數組的長度,其實就是一維數組的個數。 內迴圈控制的是一維數組的長度。 結果: ...
  • ![](http://ww4.sinaimg.cn/large/006tNc79ly1g4ztauvhzej30p00dw45p.jpg) ## 前言 當應用開發中,我們要為一個對象在原有功能上進行擴展增強時,往往採用繼承的方式,而繼承過多時就會使得功能類更加複雜,不利於維護,而設計模式中裝飾者模式 ...
  • ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...