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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...