<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      Mybatis(黑馬)

      1.框架概述

      課程介紹

      三層架構和ssm框架的對應關系

      jdbc操作數據庫的問題分析

      • jdbc代碼回顧
      java
      
      public static void main(String[] args) {
      Connection connection = null;
      PreparedStatement preparedStatement = null;
      ResultSet resultSet = null;
      try {
      //加載數據庫驅動
      Class.forName("com.mysql.jdbc.Driver");
      //通過驅動管理類獲取數據庫鏈接
      connection = DriverManager
      .getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","ro
      ot", "root");
      //定義 sql 語句 ?表示占位符
      String sql = "select * from user where username = ?";
      傳智播客——專注于 Java、.Net 和 Php、網頁平面設計工程師的培訓
      北京市昌平區建材城西路金燕龍辦公樓一層 電話:400-618-9090
      //獲取預處理 statement
      preparedStatement = connection.prepareStatement(sql);
      //設置參數,第一個參數為 sql 語句中參數的序號(從 1 開始),第二個參數為設置的
      參數值
      preparedStatement.setString(1, "王五");
      //向數據庫發出 sql 執行查詢,查詢出結果集
      resultSet = preparedStatement.executeQuery();
      //遍歷查詢結果集
      while(resultSet.next()){
       System.out.println(resultSet.getString("id")+"
       "+resultSet.getString("username"));
      }
      } catch (Exception e) {
      e.printStackTrace();
      }finally{
      //釋放資源
      if(resultSet!=null){
      try {
      resultSet.close();
      } catch (SQLException e) {
      e.printStackTrace();
      }
      }
      if(preparedStatement!=null){
      try {
      preparedStatement.close();
      } catch (SQLException e) {
      e.printStackTrace();
      }
      }
      if(connection!=null){
      try {
      connection.close();
      } catch (SQLException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
      }
      }
      }
      }
      上邊使用 jdbc 的原始方法(未經封裝)實現了查詢數據庫表記錄的操作
      

      在傳統的jdbc中,我們為啥實現查詢這個功能,需要配置獲取連接,獲取預處理對象,關閉資源這些操作。但是這些操作是重復的。我們程序員應該將個更多的精力放在解決需求(sql語句(使用sql語句實現需求))上面去,而不是放在這些非業務的操作上去。

      mybatis概述

      環境搭配--前期準備

      • 數據庫和實驗用表的準備
      
      CREATE DATABASE mybatis1;
      
      
      CREATE TABLE `user` (
        `id` INT(11) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR(32) NOT NULL COMMENT '用戶名稱',
        `birthday` DATETIME DEFAULT NULL COMMENT '生日',
        `sex` CHAR(1) DEFAULT NULL COMMENT '性別',
        `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
        PRIMARY KEY  (`id`)
      ) ENGINE=INNODB DEFAULT CHARSET=utf8;
      
      
      
      INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`)
       VALUES (41,'老王','2018-02-27 17:47:08','男','北京'),
       (42,'小二王','2018-03-02 15:09:37','女','北京金燕龍'),
       (43,'小二王','2018-03-04 11:34:34','女','北京金燕龍'),
       (45,'傳智播客','2018-03-04 12:04:06','男','北京金燕龍'),
       
       
       (46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小馬寶莉','2018-03-08 11:44:00','女','北京修正');
      
      
      SELECT * FROM USER
      
      • 環境搭建的步驟

      • 可能需要用到的依賴

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
          <modelVersion>4.0.0</modelVersion>
      
          <groupId>groupId</groupId>
          <artifactId>day1</artifactId>
          <version>1.0-SNAPSHOT</version>
          <packaging>jar</packaging><!--打包方法-->
          <!--依賴-->
          <dependencies>
              <!--mybatis-->
              <dependency>
                  <groupId>org.mybatis</groupId>
                  <artifactId>mybatis</artifactId>
                  <version>3.5.14</version>
              </dependency>
      
              <!--mysql驅動-->
              <dependency>
                  <groupId>mysql</groupId>
                  <artifactId>mysql-connector-java</artifactId>
                  <version>6.0.6</version>
              </dependency>
      
              <!--測試-->
              <dependency>
                  <groupId>junit</groupId>
                  <artifactId>junit</artifactId>
                  <version>4.12</version>
                  <scope>test</scope>
              </dependency>
              <!--日志-->
              <dependency>
                  <groupId>log4j</groupId>
                  <artifactId>log4j</artifactId>
                  <version>1.2.16</version>
              </dependency>
          </dependencies>
      
      
          <properties>
              <maven.compiler.source>8</maven.compiler.source>
              <maven.compiler.target>8</maven.compiler.target>
              <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
          </properties>
      
      </project>
      

      • domain
      package com.itheima.domain;
      
      import java.io.Serializable;
      import java.util.Date;
      
      /*user表對應的實體類*/
      public class User implements Serializable {
          private Integer id;
          private String username;
          private Date birthday;
          private String sex;
          private String address;
      
          public User() {
          }
      
          public User(Integer id, String username, Date birthday, String sex, String address) {
              this.id = id;
              this.username = username;
              this.birthday = birthday;
              this.sex = sex;
              this.address = address;
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return username
           */
          public String getUsername() {
              return username;
          }
      
          /**
           * 設置
           * @param username
           */
          public void setUsername(String username) {
              this.username = username;
          }
      
          /**
           * 獲取
           * @return birthday
           */
          public Date getBirthday() {
              return birthday;
          }
      
          /**
           * 設置
           * @param birthday
           */
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          /**
           * 獲取
           * @return sex
           */
          public String getSex() {
              return sex;
          }
      
          /**
           * 設置
           * @param sex
           */
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          /**
           * 獲取
           * @return address
           */
          public String getAddress() {
              return address;
          }
      
          /**
           * 設置
           * @param address
           */
          public void setAddress(String address) {
              this.address = address;
          }
      
          public String toString() {
              return "User{id = " + id + ", username = " + username + ", birthday = " + birthday + ", sex = " + sex + ", address = " + address + "}";
          }
      }
      
      
      • mybatis主配置文件
      <?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">
      <!--mybatis主配置文件-->
      <configuration>
          <!--配置環境-->
          <environments default="mysql">
              <environment id="mysql">
                  <!--配置事務類型-->
                  <transactionManager type="JDBC"></transactionManager>
                  <!--配置連接池(數據源)-->
                  <dataSource type="POOLED">
                  <!--配置連接池的信息-->
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <property name="url" value="jdbc:mysql://localhost:3306/mybatis1"/>
                      <property name="username" value="root"/>
                      <property name="password" value="888888"/>
      
                  </dataSource>
              </environment>
          </environments>
          <!--指定映射配置文件的位置,映射配置文件指的是每個dao獨立的配置文件-->
          <mappers>
              <mapper resource="com/itheima/dao/IUserDao.xml"/>
          </mappers>
      </configuration>
      
      • userDao映射配置文件
      <?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">
         <!--配置查詢所有-->
          <select id="findAll">
              select * from user
          </select>
      </mapper>
      

      主配置文件和映射配置文件的約束在資料里面有

      環境搭配的注意事項

      mybatis的入門

      package com.itheima.test;
      
      
      
      
      
      import com.itheima.dao.IUserDao;
      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 javax.annotation.Resource;
      import java.io.InputStream;
      import java.util.List;
      
      public class MyBatisTest {
          public static void main(String[] args) throws   Exception{
              //1.讀取配置文件
              InputStream in =  Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.創建SqlSessionFactory工廠
              SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
              SqlSessionFactory factory = builder.build(in);
              //3.使用工廠生產sqlSession對象
         SqlSession sqlSession = factory.openSession();
         //4.使用sqlSession創建dao接口的代理對象
         IUserDao userDao = sqlSession.getMapper(IUserDao.class);
         //5.使用代理對象執行方法
              final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
              }
              //6.釋放資源
              sqlSession.close();
          }
      }
      
      
      • 在mybatis3.4.5中需要加上resultType,但是在mybatis 3.5.4就不用加resultType也可以識別出來
      • 將會出現下面的異常

      入門案例中的設計模式分析

      mybatis注解開發和編寫dao實現類的方法

      • 使用注解的方式實現前面的入門案例


        寫dao的實現類也可以完成相同的功能,但是讓代碼過于繁雜,程序員無法將精力集中在業務中

      3.自定義mybatis

      執行查詢的所有分析

      • 前提要求實體類屬性和表的列名一致
        關注點1.如何創建代理對象以及使用的設計模式帶來的優勢2.這個過程中調用的組合關系
        不必關注點:1.jdbc的執行2.xml的解析不需要去深究

        為什么將映射文件中的全類名和SQL語句封裝成一個對象而不是參數?
        如果封裝成參數,則有多條sql語句的時候不知道誰和誰是對應的(全類名和sql語句是一一對應的)

      mybatis自定義編寫---根據測試類中缺少的創建類和接口

      • 根據前面的分析進行編寫
        首先我們pom.xml中將mybatis刪除掉

      mybatis自定義編寫---解析xml的工具類的介紹

      • 因為xml解析的原理不是很重要,我們使用工具類來完成
        我們直接從資料中導入XMLconfigBuilder用于XML解析



        此時已經基本理解XML對配置文件的解析操作。了解了映射關系
        個人理解:
      • 1.讀取主配置文件
        我們將讀取主配置文件的信息以流傳遞給xml解析器:1.先將主配置文件中連接數據庫所需要的屬性解析出來,并將其的值設置給Configuration配置類中的屬性2.根據映射文件的位置找到映射文件(然后開始解析映射文件)3.得到映射文件中所有的mapper標簽(一個mapper代表這個dao的一個方法)4.獲取映射文件的屬性(映射文件的路徑)傳遞給loadMapperConfiguration())函數將映射關系封裝成一個MAp集合5 將返回的map對象追加到Configuration配置類的Map集合(專門記錄映射關系)中.
      • loadMapperConfiguration(String mapperPath)方法--專門封裝映射關系(解析映射文件)
        1.方法中傳入了映射文件的路徑2.創建map集合 Map<String,Mapper> mappers3. in = Resources.getResourceAsStream(mapperPath)獲取文件中的數據到流中4.將流中的數據傳入解析器開始解析5.獲取namespace(dao全限定列名)作為key的一部分6.獲取所有的select標簽7.循環遍歷select標簽,獲取id值(方法名)和namespace一起作為key名。得到resultType值和select語句,他們被一起封裝成Mapper對象,并將它們作為value值8.將key和value一起封裝成mapper對象,并返回

      自定義mybatis編碼--創建2個默認實現類并分析類之間的操作

      實現基于xml查詢所有的操作

      對mybatis執行過程的概述
      本質上只是干了2件事:1.解析XML文件2.創建代理對象
      我們將XML文件的信息傳入解析器后,解析器將進行解析,得到連接信息(driver,username,password,url)和映射信息(被代理類全類名+方法名和增強的方法)(select語句+返回類型))并將他們封裝在Configuration類中

      1.根據連接信息將會注冊驅動并獲取連接對象,并創建預處理對象2.session.getMapper(IUserDao.class);將會創建代理對象3.當調用相應的方法時,將通過映射關系查找出要執行的增強后的方法并執行

      對mybatis中代理模式的理解

      • 1.mybatis代理模式來執行sql語句,即在動態生成的代理方法中只是執行SQL,而沒有原始方法(沒有原始的被代理類)
      • 2.我們的映射關系,可以理解為AOP中的切入點方法和通知方法相互綁定。和代理類中增強部分方法調用原始方法一樣,所以我們的映射關系可以抽象成代理類
        (如果我知道動態生成的代理類的結構,也會是這樣的結構)
      • 3.既然我們生成的代理類就是一個映射,所以我們也可以說我們的dao是一個映射mapper

      Mybatis的CRUD

      • 學習內容

      回顧自定義mybatis的流程分析

      基于注解的自定義再分析


      回顧環境搭配---實現查詢所有功能

      • 配置文件的約束都是直接引入的

      • dao
      package com.athuima.dao;
      
      import com.athuima.domain.User;
      
      import java.util.List;
      
      public interface UserDao {
        List<User>findAll();
      }
      
      
      • 主配置文件
      <?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">
      <!--mybatis是主配置文件-->
      <configuration>
         <environments default="mysql"><!--環境名稱-->
             <environment id="mysql">
                 <!--事務類型-->
                 <transactionManager type="JDBC"></transactionManager>
                 <!--配置連接池-->
                 <dataSource type="POOLED">
                     <!--配置連接的信息-->
                     <property name="driver" value="com.mysql.jdbc.Driver"/>
                     <property name="url" value="jdbc:mysql://localhost:3306/mybatis1?useUnicode=true&amp;characterEncoding=UTF-8"/>
                     <property name="username" value="root"/>
                     <property name="password" value="888888"/>
      
                 </dataSource>
             </environment>
         </environments>
      
      <!--配置映射文件的位置-->
          <mappers>
              <mapper resource="com/athuima/dao/userDao.xml"></mapper>
          </mappers>
      
      
      </configuration>
      
      • 映射配置文件
      <?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.athuima.dao.UserDao">
          <select id="findAll" resultType="com.athuima.domain.User">
              select * from user;
          </select>
      </mapper>
      
      • 測試類
       @Test
          public void test() throws Exception{
              //1.讀取主配置文件數據
              InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.創建工廠
              SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in);
              //3.利用工廠生成數據庫操作對象sqlSession
              final SqlSession sqlSession = sqlSessionFactory.openSession();
              //4.使用sqlSession生成代理對象
              final UserDao userDao = sqlSession.getMapper(UserDao.class);
            //5.使用代理對象執行方法
              final List<User> list = userDao.findAll();
              //6.遍歷結果集
              for (User user : list) {
                  System.out.println(user);
              }
          }
      

      注意:當我們切換成使用注解時,一定要將原來目錄下的映射文件清除或者是換一個位置

      保存操作

      我們按照xml配置來實現

      • userDao.xml中
      <mapper namespace="com.athuima.dao.UserDao">
          <select id="findAll" resultType="com.athuima.domain.User">
              select * from user;
          </select>
          <insert id="save" parameterType="com.athuima.domain.User">/*傳入sql語句參數的類型*/
              insert into user (username,sex,birthday,address)values (#{username},#{sex},#{birthday},#{address});
          </insert>
      </mapper>
      
      • 主配置文件
      <!--配置映射文件的位置-->
          <mappers>
              <!--使用xml配置-->
              <mapper resource="com/athuima/dao/userDao.xml"></mapper>
              <!--使用注解-->
             <!-- <mapper class="com.athuima.dao.UserDao"></mapper>-->
          </mappers>
      
      • dao
      public interface UserDao {
      /*  @Select("select * from user")*/
        List<User>findAll();
        int save(User user);//保存方法
      }
      
      • 測試方法
      package com.test;
      
      import com.alibaba.druid.pool.DruidDataSource;
      import com.athuima.dao.UserDao;
      import com.athuima.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.lang.reflect.Field;
      import java.util.Date;
      import java.util.List;
      
      public class MybatisTest {
          private   InputStream in;
          private SqlSession sqlSession;
          private UserDao userDao;
          //抽取關閉資源的方法
          @After//在測試方法之后執行
          public void close() throws Exception {
              //提交事務
              sqlSession.commit();
              sqlSession.close();
              in.close();
          }
          @Before//在測試方法之前執行
          //抽取初始化方法
          public void init() throws Exception{
              //1.讀取主配置文件數據
              in = Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.創建工廠
              SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in);
              //3.利用工廠生成數據庫操作對象sqlSession
              sqlSession = sqlSessionFactory.openSession();
              //4.使用sqlSession生成代理對象
           userDao = sqlSession.getMapper(UserDao.class);
          }
          @Test
          public void testSelect() throws Exception{
              //5.使用代理對象執行方法
              final List<User> list = userDao.findAll();
              //6.遍歷結果集
              for (User user : list) {
                  System.out.println(user);
              }
          }
          @Test
          public void testSave() throws Exception{
              User user = new User();
              user.setUsername("石文濤");
              user.setSex("男");
              user.setBirthday(new Date());
              user.setAddress("北京");
              //5.使用代理對象執行方法
              final int row = userDao.save(user);
              System.out.println(row);
            
          }
      }
      
      



      當我們執行sql后,沒有報錯,但是數據的插入沒有成功

      我們需要在操作的最后進行手動事務提交

      修改和刪除操作

      • 映射文件
       <!--更新用戶-->
          <update id="updateUser" parameterType="com.athuima.domain.User">
              update user set username=#{username},address=#{address},sex=#{sex} ,birthday=#{birthday} where id=#{id};
          </update>
          <!--刪除用戶-->
          <delete id="deleteUser" parameterType="java.lang.Integer">
              delete from user where id = #{dswwwxsssss}
          </delete>
      
      • dao
       int updateUser(User user);
        int deleteUser(Integer id);
      
      • 測試
       @Test
          public void testUpdateUser() throws Exception{
              User user = new User();
              user.setId(53);
              user.setSex("女");
              user.setUsername("火云邪神");
              user.setAddress("湯成一片");
              userDao.updateUser(user);
      
          }
          @Test
          public void testDeleteUser() throws Exception{
            userDao.deleteUser(51);
      
          }
      


      其他的操作和前面的一樣

      查詢一個和模糊查詢

      • 映射文件
      • dao
       //查詢一個用戶
        User findById(Integer id);
        /*模糊查詢*/
        List<User> findByUsername(String username);
      
      • 測試
       @Test
          public void testSelectOne() throws Exception{
              final User user = userDao.findById(51);
              System.out.println(user);
      
          }
          @Test
          public void testFindByUsername() throws Exception{
              final List<User> users = userDao.findByUsername("%王%");
              for (User user : users) {
                  System.out.println(user);
              }
      
          }
      

      查詢返回單值操作

      • 映射文件
       <!--查詢總數據的條數-->
          <select id="findTotalCount" parameterType="int">
                  select count(*) from user;
          </select>
      
      • dao
        int findTotalCount();

      • 測試

        @Test
          public void testFindTotalCount() throws Exception{
              final int count = userDao.findTotalCount();
              System.out.println(count);
          }
      

      2種模糊查詢寫法細節分析

      保存操作的細節---獲取保存數據的id

      ** SELECT LAST_INSERT_ID();這個sqk語句可以查詢出最后保存的id號,需要在你插入操作之后歷即調用 **

      • 映射文件
       <!--插入用戶-->
          <insert id="save" parameterType="com.athuima.domain.User">/*傳入sql語句參數的類型*/
           <!--配置插入操作之后,獲取插入數據的Id-->
           <!--order:表明在最后一次插入操作之后執行-->
           <!--keyColumn:對應的列,keyProperty:對應的屬性-->
           <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
               select last_insert_id();
           </selectKey>
              insert into user (username,sex,birthday,address)values (#{username},#{sex},#{birthday},#{address});
          </insert>
      
      • 測試
        @Test
          public void testSave() throws Exception{
              User user = new User();
              user.setUsername("張三");
              user.setSex("男");
              user.setBirthday(new Date());
              user.setAddress("日本");
              System.out.println("插入之前:"+user);//打印出保存之前的user
              //5.使用代理對象執行方法
              final int row = userDao.save(user);
              System.out.println("插入之后:"+user);//打印出保存之后的user
      
          }
      

      mybatis中的參數深入---使用實體類的包裝對象作為查詢條件

      • 前面查詢條件的回顧


        當我的查詢條件有多個對象時,我們可以將多個對象包裝成一個domain對象作為查詢條件

      • 映射文件
      <!--使用實體類的包裝類作為查詢條件-->
          <select id="findByQueryVo" parameterType="com.athuima.domain.QueryVo">
               select * from user where username like #{user.username}
      
          </select>
      
      • 查詢條件包裝類--domain
      package com.athuima.domain;
      //查詢條件的包裝類
      public class QueryVo {
          private User user;
      
          public User getUser() {
              return user;
          }
      
          public void setUser(User user) {
              this.user = user;
          }
      }
      
      
      • dao接口
      /根據 QueryVo 中的條件模糊查詢用戶
        List<User> findByQueryVo(QueryVo vo);
      
      • 測試
      @Test
          public void testFindByQueryVo() throws Exception{
              QueryVo vo= new QueryVo();
              User user = new User();
              user.setUsername("王");
              vo.setUser(user);
              final List<User> users = userDao.findByUsername("王");
              for (User u : users) {
                  System.out.println(u);
              }
      
          }
      

      mybatis中返回值的深入----調整實體類的屬性解決增和改方法的報錯

      我們前面在查詢的時候要求我們的實體類和數據庫的列名一致,但是如果我們不一致會怎樣呢

      • 對于非查詢操作來說

        此時對于非查詢的報錯是可預料到的,我們將映射文件中的屬性值改成新的屬性值,就可以運行了
      • 但是在查詢中呢
        <!--查詢所有-->
          <select id="findAll" resultType="com.athuima.domain.User">
              select * from user;
          </select>
      
       @Test
          public void testSelect() throws Exception{
              //5.使用代理對象執行方法
              final List<User> list = userDao.findAll();
              //6.遍歷結果集
              for (User user : list) {
                  System.out.println(user);
              }
          }
      

      • 原因分析

      我們的屬性用戶名只是改變了大小寫其他的并沒有改變,而列名在window系統下不區分大小寫所有username可以封裝成功

      mybatis中返回值深入----解決實體類屬性和數據庫列名不對應的2種方式

      我們封裝不成功的原因就是屬性名和列名匹配不上,我們需要解決的就是讓他們匹配上就可以了

      • 1.第一種方法---起別名
        我可以可以在執行sql語句的時候起別名,讓查詢出來的列名和屬性名一致
      • 查詢所有的映射文件
       <!--查詢所有-->
          <select id="findAll" resultType="com.athuima.domain.User">
              select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as useraddRess from user;
          </select>
      
      • 查詢結果

      發現此時可以封裝成功了。這是從sql語句的層面上解決問題,執行的效率是最高的

      • 2.方式2:在映射文件中配置實體類屬性和數據庫列名的對應關系

      • 映射文件中的配置

         <!--配置查詢結果的列名和實體類中的屬性名的映射關系-->
          <resultMap id="usermap" type="com.athuima.domain.User">
      <!--主鍵字段的映射-->
              <id property="userId" column="id"></id>
              <!--非主鍵字段的對應-->
              <result property="userName" column="username"></result>
              <result property="userBirthDay" column="birthday"></result>
              <result property="userSex" column="sex"></result>
              <result property="useraddRess" column="address"></result>
          </resultMap>
      
      
      
      
          <!--查詢所有-->
          <select id="findAll" resultMap="usermap">
            <!--  select id as userId,username as userName,birthday as userBirthday,sex as userSex,address as useraddRess from user;-->
          select * from user;
      
          </select>
      

      注意此時我們需要將返回的結果resultType改成resultMap表示使用結果映射

      • 這2種方式的說明
        直接在sql語句中修改添加別名,這種效率是最高的,但是這種方法的開發效率比較低,每條查詢語句的都需要添加別名。方法2,我們添加結果映射,這將帶來多解析一段xml文件,執行效率比較低,但是開發效率比較高

      Mybatis 實現 DAO 的傳統開發方式(手動寫dao的實現類)

      mybatis編寫dao的實現類---查詢列表

      • dao接口
      package com.atheima.dao;
      
      import com.atheima.domain.User;
      
      import java.util.List;
      
      public interface UserDao {
          /*查詢所有*/
        List<User> findAll();
      }
      
      
      • dao實現類
      package com.atheima.dao.impl;
      
      import com.atheima.dao.UserDao;
      import com.atheima.domain.User;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      
      import java.util.List;
      //UserDao的實現類
      public class UserDaoImpl implements UserDao {
          //定義工廠用于創建sqlSession對象
          private SqlSessionFactory sqlSessionFactory;
          public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
              this.sqlSessionFactory = sqlSessionFactory;
          }
          @Override
          public List<User> findAll() {
              //工廠創建sqlSession對象
              final SqlSession sqlSession = sqlSessionFactory.openSession();
              final List<User> users = sqlSession.selectList("com.atheima.dao.UserDao.findAll");//參數是映射的key
              sqlSession.close();
              return users;
          }
      }
      
      
      • 映射文件
      <mapper namespace="com.atheima.dao.UserDao">
          <select id="findAll" resultType="com.atheima.domain.User">
              select * from user;
          </select>
      

      著配置文件是一樣的

      • 測試
      public class MyBatisTest {
          private InputStream in;
          private SqlSessionFactoryBuilder builder;
          @After
          public void  close() throws Exception{
              in.close();
          }
          @Before
          public void init() throws Exception{
              //加載配置文件
              in = Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.獲取SqlSessionFactory
             builder = new SqlSessionFactoryBuilder();
          }
          @Test
          public void testFindAll() throws Exception{
              //3.創建dao
              UserDao userDao = new UserDaoImpl(builder.build(in));
              final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
              }
          }
      }
      

      從這個例子我們可以看出,如果我們使用代理模式動態創建出代理(dao的實現類),這樣可以屏蔽很多細節。比如說完全屏蔽了使用sqlSession對象調用selectList方法,這些都是在動態代理中自動完成的。我們從實現類的結構可以看出我們的一個映射(mapper)其實就是一個實現類,所有說我們的動態代理完全可以依據映射關系被動態的創建出來

      mybatis編寫dao的實現類---保存操作

      • 映射文件
      <insert id="saveUser" parameterType="com.atheima.domain.User" >
              insert into user (id,username,birthday,sex,address)values (#{id},#{username},#{birthday},
                                                               #{sex},#{address});
      
          </insert>
      
      • dao實現類
        @Override
          public int saveUser(User user) {
              //1.創建session對象
              final SqlSession sqlSession = sqlSessionFactory.openSession();
              //2.執行sql
              final int row = sqlSession.insert("com.atheima.dao.UserDao.saveUser", user);
              //3.提交事務
              sqlSession.commit();
              //4.釋放資源
              sqlSession.close();
              return row;
          }
      
      • dao接口
        int saveUser(User user);

      • 測試類

       @Test
          public void testSaveUser() throws Exception{
              //3.創建dao
              UserDao userDao = new UserDaoImpl(builder.build(in));
              User user = new User();
             user.setUsername("啥問題");
             user.setAddress("曹縣");
             user.setBirthday(new Date());
             user.setSex("男");
             userDao.saveUser(user);
      
          }
      

      mybatis編寫dao的實現類---修改刪除等其他操作

      這些操作和前面的都差不了多少,可以查看IDEA中的代碼

      mybatis編寫dao的實現類的執行過程分析---查詢方法

      • 全套代碼分析流程看--截圖

      我們啟動debug模式對finfAll()方法的代碼去向溯源,我們可以發現mybatis只是對jdbc進行了一層一層封裝,sql語句最終的執行還是由jdbc的預處理對象preperedStatement.executer()方法完成的

      PreparedStatementHandler

      從執行流程可以看出來,不管是增刪改操作最后都匯聚到執行PreparedStatementHandler類中的update方法,并且由update方法中的preparedStatement中的execute方法具體執行

      mybatis中使用代理dao執行流程的分析


      • 使用動態代理dao執行流程的全部分析

      properties標簽的使用和細節(將連接信息放在外部屬性文件中,然后引入)

      • 外部配置文件
      jdbc.driver=com.mysql.jdbc.Driver
      jdbc.url=jdbc:mysql://localhost:3306/mybatis1?useUnicode=true&characterEncoding=UTF-8
      jdbc.username=root
      jdbc.password=888888
      
      • 著配置文件
      <?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">
      <!--mybatis著配置文件-->
      <configuration>
          <!--
          配置properties標簽
          可以在標簽內配置連接數據庫的信息。也可以通過屬性引用外部配置的屬性文件
          resource屬性:
          常用于指定配置文件的位置,按照類路徑的寫法來寫,且必須存在于類路徑下
          -->
          <!--r-->
          <properties  url="file:D:\ideaprojects\trationmybattis\src\main\resources/jdbcConfig.properties" >
                      <!--也可以使用使用類路徑  resource=jdbc.properties-->
              <!--配置連接的信息-->
              <!--我們可以在這里寫,然后再下面進行引用,但是寫在配置文件中然后引用更常見-->
              <!--<property name="driver" value="com.mysql.jdbc.Driver"/>
              <property name="url" value="jdbc:mysql://localhost:3306/mybatis1?useUnicode=true&amp;characterEncoding=UTF-8"/>
              <property name="username" value="root"/>
              <property name="password" value="888888"/>-->
          </properties>
          <!--mysql環境的配置-->
          <environments default="mysql">
              <environment id="mysql">
                  <transactionManager type="JDBC"></transactionManager>
                  <!--連接池的配置-->
                  <dataSource type="POOLED">
                      <!--配置連接的信息-->
                      <!--引入配置文件中的信息即可-->
                      <property name="driver" value="${jdbc.driver}"/>
                      <property name="url" value="${jdbc.url}"/>
                      <property name="username" value="${jdbc.username}"/>
                      <property name="password" value="${jdbc.password}"/>
      
                  </dataSource>
              </environment>
          </environments>
      
      <!--配置映射文件的位置-->
          <mappers>
              <!--使用xml配置文件-->
              <!--我們的mapper也可以使用url屬性定位映射文件的位置,前面的道理相同-->
             <mapper  resource="com/itheima/dao/userDao.xml"></mapper>
      
          </mappers>
      
      </configuration>
      

      typeAliases標簽和package標簽

      • 所以我們其實也可以給實體類起別名
      • 注意:是在主配置文件中指定的

      mybatis第三天

      第1章 Mybatis 連接池與事務深入

      內容介紹

      連接池介紹

      連接池就像一個容器,可以將我們的連接初始化放在一個容器里面,我們要用的時候只需要到容器中取就可以了


      當取出一個后剩下的將按照隊列一樣位置全部往前縮進一位

      mybatis連接池的介紹

      在傳統的JDBC中中我們獲取連接由DeiverManager接口負責,但是使用DeiverManager來獲取連接效率太低了。現在一般使用連接池來管理連接。java提供了DataSourse接口來管理連接池的連接

      mybatis中采用unpooled配置連接池的原理分析

      通過查看UNPOOLED模型的實現類UnPooledDataSource中關于獲取連接的方法,我們可以知道,每次獲取連接都需要注冊驅動,獲取連接,最后是否連接。沒有使用到連接池

      mybatis中采用pooled配置連接池的原理分析


      總體思路就是:見上圖

      mybatis中的事務原理和自動提交設置




      所以其實我們是可以自己手動設置是否自動提交的,如果不設置則默認是關閉自動提交

      • 在創建sqlSession對象的時候可以設置時候自動提交

      第二章mybatis映射文件的SQL深入

      這個一般是針對查詢語句的,當我們的查詢條件不同,將不同的查詢結果

      mybatis中的動態sql語句--if標簽

      只能使用 and不能使用&&

      • 映射文件
      • 測試
      //4.根據傳入的條件動態查詢
          @Test
          public void testFindByCondition() throws Exception{
              User user = new User();
              user.setUserName("老王");
      //        user.setUseraddRess("北京");//也可用于地址
              final List<User> users = userDao.findByCondition(user);
              for (User u : users) {
                  System.out.println(u);
              }
          }
      

      mybatis中的動態sql語句--where標簽的使用

      我們可以使用where標簽來替代where1=1這個條件

      mybatis中的動態sql語句--foreach和sql標簽


      我們需要解決的是如何將傳入的參數集合賦值給sql語句中in()這個集合中

      • 映射文件
      <select id="findUserInIds" parameterType="com.athuima.domain.QueryVo" resultType="com.athuima.domain.User">
      select  * from user
              <where>
          <if test="ids!=null and ids.size()>0">
                 <foreach collection="ids" open=" and id in(" close=")" item="uid" separator=",">
                      #{uid}
                 </foreach>
          </if>
              </where>
      
          </select>
      
      • 測試
       //根據queryVo中的id集合實現查詢用戶列表
          @Test
          public void findUserInIds() throws Exception{
              QueryVo vo= new QueryVo();
              List<Integer> ids = new ArrayList<>();
              ids.add(41);
              ids.add(42);
              ids.add(43);
              vo.setIds(ids);
              final List<User> users = userDao.findUserInIds(vo);
              for (User u : users) {
                  System.out.println(u);
              }
          }
      
      • sql標簽--抽取重復的ql語句

      第三章mysql多表關聯查詢

      mybatis的多表關聯查詢

      完成account表的建立及實現單表查詢


      建立用戶表和賬戶表

      
      DROP TABLE IF EXISTS `user`;
      
      CREATE TABLE `user` (
        `id` INT(11) NOT NULL AUTO_INCREMENT,
        `username` VARCHAR(32) NOT NULL COMMENT '用戶名稱',
        `birthday` DATETIME DEFAULT NULL COMMENT '生日',
        `sex` CHAR(1) DEFAULT NULL COMMENT '性別',
        `address` VARCHAR(256) DEFAULT NULL COMMENT '地址',
        PRIMARY KEY  (`id`)
      ) ENGINE=INNODB DEFAULT CHARSET=utf8;
      
      
      
      INSERT  INTO `user`(`id`,`username`,`birthday`,`sex`,`address`) VALUES (41,'老王','2018-02-27 17:47:08','男','北京'),(42,'小二王','2018-03-02 15:09:37','女','北京金燕龍'),(43,'小二王','2018-03-04 11:34:34','女','北京金燕龍'),(45,'傳智播客','2018-03-04 12:04:06','男','北京金燕龍'),(46,'老王','2018-03-07 17:37:26','男','北京'),(48,'小馬寶莉','2018-03-08 11:44:00','女','北京修正');
      
      
      
      
      
      DROP TABLE IF EXISTS `account`;
      
      CREATE TABLE `account` (
        `ID` INT(11) NOT NULL COMMENT '編號',
        `UID` INT(11) DEFAULT NULL COMMENT '用戶編號',
        `MONEY` DOUBLE DEFAULT NULL COMMENT '金額',
        PRIMARY KEY  (`ID`),
        KEY `FK_Reference_8` (`UID`),
        CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)-- 和用戶表的用戶編號綁定外鍵
      ) ENGINE=INNODB DEFAULT CHARSET=utf8;
      
      
      
      INSERT  INTO `account`(`ID`,`UID`,`MONEY`) VALUES (1,46,1000),(2,45,1000),(3,46,2000);
      
      
      

      完成查詢所有賬戶表

      • 主配置文件中指定映射文件的位置
        <mapper resource="com/athuima/dao/accountDao.xml"></mapper>
      • 映射配置文件
      <mapper namespace="com.athuima.dao.AccountDao">
      
          <!--1.查詢所有-->
          <select id="findAll" resultType="com.athuima.domain.Account">
          select * from account;
      
          </select>
      
      
      
      </mapper>
      
      • dao接口
      
          /**
           * 查詢所有賬戶
           * @return
           */
          List<Account>findAll();
      
      • 測試
        @Test
         public void testSelect(){
             final List<Account> accounts = accountDao.findAll();
             for (Account account : accounts) {
                 System.out.println(account);
             }
         }
      

      完成account一對一操作--通過寫account子類方式查詢

      但是現在我們的要求就是查詢所有賬戶,同時還要獲得當前賬戶所屬用戶的信息,其實就是實現多表查詢
      這個問題本質上是在進行多表查詢的時候,怎樣對查詢結果進行封裝的問題

      • 我們現在需要取出賬戶表的全部信息,已經每個賬戶對應的用戶的姓名和地址信息
        我們通過創建子類的方法開拓展實體類,使得其可以封裝多表查詢的結果,但是這種方法現在并不多見
      • 實體類(繼承了Account類)
      package com.athuima.domain;
      
      public class AccountUser extends Account{
          private String username;
          private String address;
      
          public AccountUser() {
          }
      
          public AccountUser(String username, String address) {
              this.username = username;
              this.address = address;
          }
      
          /**
           * 獲取
           * @return username
           */
          public String getUsername() {
              return username;
          }
      
          /**
           * 設置
           * @param username
           */
          public void setUsername(String username) {
              this.username = username;
          }
      
          /**
           * 獲取
           * @return address
           */
          public String getAddress() {
              return address;
          }
      
          /**
           * 設置
           * @param address
           */
          public void setAddress(String address) {
              this.address = address;
          }
      
          public String toString() {
              return super.toString()+ "AccountUser{username = " + username + ", address = " + address + "}";
          }
      }
      
      
      • 映射文件
      <!--查詢所有賬戶同時包含用戶名和地址信息-->
         <select id="findAllAccountUser" resultType="com.athuima.domain.AccountUser">
             select  a.*,u.username,u.address
                 from user u join account a on u.id=a.uid;
      
         </select>
      
      
      • 測試
        @Test
          public void findAllAccountUser(){
              final List<AccountUser> accounts = accountDao.findAllAccountUser();
              for (Account account : accounts) {
                  System.out.println(account);
              }
          }
      

      完成account一對一操作--建立實體類關系的方式

      我們的每個訂單它屬于一個用戶,在表中我們是根據在訂單表中設置外鍵來表示的。在實體類中我們可以在訂單表中放置用戶的引用來表示這一點
      我們的表和實體類會根據屬性和列進行自動封裝(我們要指定封裝的類型),但是當我們在account中添加user對象,這個對象就不能封裝可進行了。所以我們必須要為這個查詢專門設計resultMap

      • account類(關聯一個user對象,實現一對一關系)
      package com.athuima.domain;
      
      import java.io.Serializable;
      
      //賬戶表對應的實體類
      public class Account implements Serializable {
          private Integer id;//賬戶id
          private Integer uid;//用戶id
          private Double money;//賬戶余額
          private User user;//一個賬戶屬于一個用戶
      
          public Account() {
          }
      
          public Account(Integer id, Integer uid, Double money, User user) {
              this.id = id;
              this.uid = uid;
              this.money = money;
              this.user = user;
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return uid
           */
          public Integer getUid() {
              return uid;
          }
      
          /**
           * 設置
           * @param uid
           */
          public void setUid(Integer uid) {
              this.uid = uid;
          }
      
          /**
           * 獲取
           * @return money
           */
          public Double getMoney() {
              return money;
          }
      
          /**
           * 設置
           * @param money
           */
          public void setMoney(Double money) {
              this.money = money;
          }
      
          /**
           * 獲取
           * @return user
           */
          public User getUser() {
              return user;
          }
      
          /**
           * 設置
           * @param user
           */
          public void setUser(User user) {
              this.user = user;
          }
      
          public String toString() {
              return "Account{id = " + id + ", uid = " + uid + ", money = " + money + ", user = " + user + "}";
          }
      }
      
      
      • 映射文件
      <!--配置結果映射關系-->
          <resultMap id="accountmap" type="com.athuima.domain.Account">
              <!--主鍵-->
              <id property="id" column="id"></id>
              <result property="uid" column="uid"></result>
              <result property="money" column="money"></result>
              <!--用于指定表方關聯的引用實體屬性-->
            <association property="user" javaType="com.athuima.domain.User"><!--javaType用于指定關聯屬性的類型-->
            <id property="id" column="id"></id>
                <result column="username" property="username"/>
                <result column="sex" property="sex"/>
                <result column="birthday" property="birthday"/>
                <result column="address" property="address"/>
      
            </association>
          </resultMap>
      
          <!--查詢所有賬戶同時包含用戶名和地址信息-->
          <select id="findAllAccountUser" resultMap="accountmap" >
              select  a.*,u.username,u.address
                  from user u join account a on u.id=a.uid;
      
          </select>
      
      
      • 測試
       @Test
          public void findAllAccountUser(){
              final List<AccountUser> accounts = accountDao.findAllAccountUser();
              for (Account account : accounts) {
                  System.out.println(account);
              }
          }
      

      一對多查詢操作

      要求查詢出所有用戶和他們對應的賬戶信息。一個用戶可能對應一對多的關系,我們需要在實體類中實現這個關系

      • 映射文件
      <!--建立user表的結果映射-->
          <resultMap type="com.athuima.domain.User" id="userMap">
              <id column="id" property="id"></id>
              <result column="username" property="username"/>
              <result column="address" property="address"/>
              <result column="sex" property="sex"/>
              <result column="birthday" property="birthday"/>
              <!-- collection 是用于建立一對多中集合屬性的對應關系
              ofType 用于指定集合元素的數據類型
              -->
              <collection property="accounts" ofType="com.athuima.domain.Account">
                  <id column="aid" property="id"/>
                  <result column="uid" property="uid"/>
                  <result column="money" property="money"/>
      
              </collection>
          </resultMap>
      
      
      
          <!--1.查詢所有-->
          <select id="findAll" resultMap="userMap" >
              select u.*,a.id as aid ,a.uid,a.money from user u left outer join account
                  a on u.id =a.uid
      
          </select>
      

      說明:resultMap的格式(特別是屬性的位置還是按照上面的格式寫會比較號好),因為可能會出現無法將多個賬戶封裝到一個集合的情況

      • user(和賬戶關聯一對多的關系)
      package com.athuima.domain;
      
      import java.util.Date;
      import java.util.List;
      
      /**
       * @author SWT
       * @date 2023/12/09
       */
      public class User {
      private Integer id;
          private String username;
          private Date birthday;
          private String sex;
          private String address;
        //一個用戶可能對應多個賬戶
          private List<Account> accounts;
      
      
          public User() {
          }
      
          public User(Integer id, String username, Date birthday, String sex, String address, List<Account> accounts) {
              this.id = id;
              this.username = username;
              this.birthday = birthday;
              this.sex = sex;
              this.address = address;
              this.accounts = accounts;
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return username
           */
          public String getUsername() {
              return username;
          }
      
          /**
           * 設置
           * @param username
           */
          public void setUsername(String username) {
              this.username = username;
          }
      
          /**
           * 獲取
           * @return birthday
           */
          public Date getBirthday() {
              return birthday;
          }
      
          /**
           * 設置
           * @param birthday
           */
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          /**
           * 獲取
           * @return sex
           */
          public String getSex() {
              return sex;
          }
      
          /**
           * 設置
           * @param sex
           */
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          /**
           * 獲取
           * @return address
           */
          public String getAddress() {
              return address;
          }
      
          /**
           * 設置
           * @param address
           */
          public void setAddress(String address) {
              this.address = address;
          }
      
          /**
           * 獲取
           * @return accounts
           */
          public List<Account> getAccounts() {
              return accounts;
          }
      
          /**
           * 設置
           * @param accounts
           */
          public void setAccounts(List<Account> accounts) {
              this.accounts = accounts;
          }
      
          public String toString() {
              return "User{id = " + id + ", username = " + username + ", birthday = " + birthday + ", sex = " + sex + ", address = " + address + ", accounts = " + accounts + "}";
          }
      }
      
      
      • 測試
        @Test
         public void testSelect(){
             final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
              }
      
         }
      
      • 直接執行sql語句的情況

      分析mybatis的多對多的步驟并搭建環境

      • 角色即身份的意思

      多對多--準備角色表的實體類和映射配置

      • 添加role表并插入數據
      DROP TABLE IF EXISTS `role`;
      
      CREATE TABLE `role` (
        `ID` INT(11) NOT NULL COMMENT '編號',
        `ROLE_NAME` VARCHAR(30) DEFAULT NULL COMMENT '角色名稱',
        `ROLE_DESC` VARCHAR(60) DEFAULT NULL COMMENT '角色描述',
        PRIMARY KEY  (`ID`)
      ) ENGINE=INNODB DEFAULT CHARSET=utf8;
      
      
      
      INSERT  INTO `role`(`ID`,`ROLE_NAME`,`ROLE_DESC`) VALUES (1,'院長','管理整個學院'),(2,'總裁','管理整個公司'),(3,'校長','管理整個學校');
      
      
      
      
      
      • 插入中間表--- user--role
      DROP TABLE IF EXISTS `user_role`;
      
      CREATE TABLE `user_role` (
        `UID` INT(11) NOT NULL COMMENT '用戶編號',
        `RID` INT(11) NOT NULL COMMENT '角色編號',
        PRIMARY KEY  (`UID`,`RID`),
        KEY `FK_Reference_10` (`RID`),
        CONSTRAINT `FK_Reference_10` FOREIGN KEY (`RID`) REFERENCES `role` (`ID`),
        CONSTRAINT `FK_Reference_9` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
      ) ENGINE=INNODB DEFAULT CHARSET=utf8;
      
      INSERT  INTO `user_role`(`UID`,`RID`) VALUES (41,1),(45,1),(41,2);
      

      查詢角色獲取角色下屬用戶信息

      多對多是一種表的關系的體現,多對多可以看成是2個一對多,且中間表的列和其他2個表存在外鍵約束,

      因為要查詢出來所有用戶所以我們需要左外連

      • 映射文件
      <!--定義 role 表的 ResultMap-->
      <resultMap id="roleMap" type="com.athuima.domain.Role">
          <id property="roleId" column="id"></id>
          <result property="roleName" column="role_name"></result>
          <result property="roleDesc" column="role_desc"></result>
          <collection property="users" ofType="com.athuima.domain.User">
              <id column="uid" property="id"></id>
              <result column="username" property="username"></result>
              <result column="address" property="address"></result>
              <result column="sex" property="sex"></result>
              <result column="birthday" property="birthday"></result>
          </collection>
      </resultMap>
      
      <select id="findAll" resultMap="roleMap">
          SELECT
              r.*,u.id uid,
              u.username username,
              u.birthday birthday,
              u.sex sex,
              u.address address
          FROM
              ROLE r
                  INNER JOIN
              USER_ROLE ur
              ON ( r.id = ur.rid)
                  INNER JOIN
              USER u
              ON (ur.uid = u.id);
      </select>
      
      - role類
      ```java
      package com.athuima.domain;
      
      import java.io.Serializable;
      import java.util.List;
      
      //角色表對應的實體類
      public class Role implements Serializable {
          private  Integer roleId;//角色id
          private  String roleName;//角色名
          private String roleDesc;//角色描述
          //多對多關系
          private List<User> users;
      
          public List<User> getUsers() {
              return users;
          }
      
          public void setUsers(List<User> users) {
              this.users = users;
          }
      
          public Role() {
          }
      
          public Role(Integer roleId, String roleName, String roleDesc) {
              this.roleId = roleId;
              this.roleName = roleName;
              this.roleDesc = roleDesc;
          }
      
          /**
           * 獲取
           * @return roleId
           */
          public Integer getRoleId() {
              return roleId;
          }
      
          /**
           * 設置
           * @param roleId
           */
          public void setRoleId(Integer roleId) {
              this.roleId = roleId;
          }
      
          /**
           * 獲取
           * @return roleName
           */
          public String getRoleName() {
              return roleName;
          }
      
          /**
           * 設置
           * @param roleName
           */
          public void setRoleName(String roleName) {
              this.roleName = roleName;
          }
      
          /**
           * 獲取
           * @return roleDesc
           */
          public String getRoleDesc() {
              return roleDesc;
          }
      
          /**
           * 設置
           * @param roleDesc
           */
          public void setRoleDesc(String roleDesc) {
              this.roleDesc = roleDesc;
          }
      
          @Override
          public String toString() {
              return "Role{" +
                      "roleId=" + roleId +
                      ", roleName='" + roleName + '\'' +
                      ", roleDesc='" + roleDesc + '\'' +
                      ", users=" + users +
                      '}';
          }
      }
      
      
      • 測試
        public void testSelect() throws Exception{
              //5.使用代理對象執行方法
              final List<Role> roles = roleDao.findAll();
              //6.遍歷結果集
              for (Role role : roles) {
                  System.out.println(role);
              }
          }
      


      注意看結果體現了多對多的關系

      查詢用戶--獲取用戶所包含的角色信息

      我們的sql語句如果強調使用左右連接可能需要改,其他情況和前面相比,我們的sql都不用修改。我們只需要在user類中添加多對多關系

      • user類
      package com.athuima.domain;
      
      import java.util.Date;
      import java.util.List;
      
      /**
       * @author SWT
       * @date 2023/12/09
       */
      public class User {
      private Integer id;
          private String username;
          private Date birthday;
          private String sex;
          private String address;
        //多對多關系 :一個用戶有多個角色
      private List<Role> roles;
      
          public List<Role> getRoles() {
              return roles;
          }
      
          public void setRoles(List<Role> roles) {
              this.roles = roles;
          }
      
          public User() {
          }
      
          public User(Integer id, String username, Date birthday, String sex, String address) {
              this.id = id;
              this.username = username;
              this.birthday = birthday;
              this.sex = sex;
              this.address = address;
      
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return username
           */
          public String getUsername() {
              return username;
          }
      
          /**
           * 設置
           * @param username
           */
          public void setUsername(String username) {
              this.username = username;
          }
      
          /**
           * 獲取
           * @return birthday
           */
          public Date getBirthday() {
              return birthday;
          }
      
          /**
           * 設置
           * @param birthday
           */
          public void setBirthday(Date birthday) {
              this.birthday = birthday;
          }
      
          /**
           * 獲取
           * @return sex
           */
          public String getSex() {
              return sex;
          }
      
          /**
           * 設置
           * @param sex
           */
          public void setSex(String sex) {
              this.sex = sex;
          }
      
          /**
           * 獲取
           * @return address
           */
          public String getAddress() {
              return address;
          }
      
          /**
           * 設置
           * @param address
           */
          public void setAddress(String address) {
              this.address = address;
          }
      
          /**
           * 獲取
           * @return accounts
           */
          @Override
          public String toString() {
              return "User{" +
                      "id=" + id +
                      ", username='" + username + '\'' +
                      ", birthday=" + birthday +
                      ", sex='" + sex + '\'' +
                      ", address='" + address + '\'' +
                      ", roles=" + roles +
                      '}';
          }
      }
      
      
      • 映射文件
      <!--建立user表的結果映射-->
          <resultMap type="com.athuima.domain.User" id="userMap">
              <id column="uid" property="id"></id>
              <result column="username" property="username"/>
              <result column="address" property="address"/>
              <result column="sex" property="sex"/>
              <result column="birthday" property="birthday"/>
             <collection property="roles" ofType="com.athuima.domain.Role">
                 <id property="roleId" column="id"></id>
                 <result property="roleName" column="role_name"></result>
                 <result property="roleDesc" column="role_desc"></result>
             </collection>
          </resultMap>
      
      
      
          <!--1.查詢所有用戶,并且查出用戶所有的角色信息-->
          <select id="findAll" resultMap="userMap" >
              SELECT
                  r.*,u.id uid,
                  u.username username,
                  u.birthday birthday,
                  u.sex sex,
                  u.address address
              FROM
                  ROLE r
                      INNER JOIN
                  USER_ROLE ur
                  ON ( r.id = ur.rid)
                      INNER JOIN
                  USER u
                  ON (ur.uid = u.id);
      
          </select>
      

      補充內容--JNDI

      補充--JDNI的概述和原理

      • JNDI模仿windows的注冊表

      補充--JDNI搭建maven的war工程



      補充--測試JNDI數據源的使用以及以及使用細節

      原理還不是很懂,好像這個用的也不多

      第四天

      今日課程安排

      延遲加載和立即加載的概念


      我們已查詢用戶就會把該用戶100個賬戶都查詢出來,這對內存無疑是巨大的開銷

      應該需要的是當我們不需要使用賬戶的時候就應該把賬戶查詢出來,但是又帶來一個問題,那我們需要用的時候不就使用不了了嗎

      mybatis一對一實現延遲加載

      在實際開發中一對一和多對一應該是使用的延遲加載,這里只是舉一個例子

      • 查詢賬戶,實現延遲加載用戶

      延遲加載根據用到才會去加載,才會查詢數據庫獲取數據,如果沒有用到關聯的數據,不會去查詢數據庫

      • 主配置文件中:配置mybatis延遲加載
       <settings>
              <!--開啟mybatis延遲加載-->
              <setting name="lazyLoadingEnabled" value="true"/>
              <!--允許觸發方法進行立即加載 ,否則按需加載-->
              <setting name="aggressiveLazyLoading" value="false"/>
          </settings>
      
      • 映射配置文件
      <!--配置結果映射關系-->
          <resultMap id="accountmap" type="com.athuima.domain.Account">
              <!--主鍵-->
              <id property="id" column="id"></id>
              <result property="uid" column="uid"></result>
              <result property="money" column="money"></result>
              <!--用于指定表方關聯的引用實體屬性-->
              <!--select指定的內容:查詢用戶的唯一標識-->
              <!--column屬性指定的內容:用戶根據id查詢時,所需要參數的值-->
            <association property="user" column="uid" javaType="com.athuima.domain.User" select="com.athuima.dao.UserDao.findById"><!--javaType用于指定關聯屬性的類型-->
            <!--按照默認封裝-->
            </association>
          </resultMap>
      
      
      
      
          <!--1.查詢所有-->
          <select id="findAll" resultMap="accountmap">
              select * from account;
      
          </select>
      
      • 賬戶類
      package com.athuima.domain;
      
      import java.io.Serializable;
      
      //賬戶表對應的實體類
      public class Account implements Serializable {
          private Integer id;//賬戶id
          private Integer uid;//用戶id
          private Double money;//賬戶余額
          private User user;//一個賬戶屬于一個用戶
      
          public Account() {
          }
      
          public Account(Integer id, Integer uid, Double money, User user) {
              this.id = id;
              this.uid = uid;
              this.money = money;
              this.user = user;
          }
      
          /**
           * 獲取
           * @return id
           */
          public Integer getId() {
              return id;
          }
      
          /**
           * 設置
           * @param id
           */
          public void setId(Integer id) {
              this.id = id;
          }
      
          /**
           * 獲取
           * @return uid
           */
          public Integer getUid() {
              return uid;
          }
      
          /**
           * 設置
           * @param uid
           */
          public void setUid(Integer uid) {
              this.uid = uid;
          }
      
          /**
           * 獲取
           * @return money
           */
          public Double getMoney() {
              return money;
          }
      
          /**
           * 設置
           * @param money
           */
          public void setMoney(Double money) {
              this.money = money;
          }
      
          /**
           * 獲取
           * @return user
           */
          public User getUser() {
              return user;
          }
      
          /**
           * 設置
           * @param user
           */
          public void setUser(User user) {
              this.user = user;
          }
      
          public String toString() {
              return "Account{id = " + id + ", uid = " + uid + ", money = " + money ;
          }
      }
      
      
      • 測試類1





      mybatis一對多實現延遲加載

      思想是:在需要使用的時候去調用對方配置文件中的配置來實現查詢的功能

      • 配置文件
       <resultMap type="com.athuima.domain.User" id="userMap">
              <id column="id" property="id"></id>
              <result column="username" property="username"/>
              <result column="address" property="address"/>
              <result column="sex" property="sex"/>
              <result column="birthday" property="birthday"/>
              <!-- collection 是用于建立一對多中集合屬性的對應關系
              ofType 用于指定集合元素的數據類型
              -->
              <collection property="accounts" column="id" ofType="com.athuima.domain.Account" select="com.athuima.dao.AccountDao.findAccountsByUid">
              </collection>
          </resultMap>
      
      
      
          <!--1.查詢所有-->
          <select id="findAll" resultMap="userMap" >
            select * from user;
      
          </select>
      
      
      • 賬戶dao映射配置文件
      <!--1.根據用戶id查詢賬戶-->
          <select id="findAccountsByUid" resultType="com.athuima.domain.Account">
              select * from account where uid=#{id}
      
          </select>
      

      測試部分和前面的一樣

      緩存的概念

      適用于緩存的舉例:淘寶中商品的庫存數,可能真實的數據庫中名沒有商品了,但是緩存中顯示還有商品,但是造成的后果影響不大

      mybatis中的一級緩存


      當我們查詢的是同樣的結果,將直接在sqlSession的緩存中提取,而不會到數據庫中進行查詢


      說明我們第二次查詢并沒有到數據庫中查詢,而是到sqlSession的緩存中取出的結果,返回了相同的user對象


      觸發清空一級緩存的情況

      使用緩存,緩存和數據庫的數據同步是我們需要關注的一個問題

      • 我們在2個查詢相同內容的中間,使用update方法進行修改,第二次查詢的內容將會是怎樣的呢*



      • 只要是update insert delete操作都更新,不需要和查詢的內容相同

      mybates的二級緩存

      • 二級緩存原理圖



        二級緩存的配置







      在第二次查詢的時候,會創建一個新的user對象,會將二級緩存中的數據填充到新創建的對象里面去。雖然沒有發起查詢,但是卻重寫創建了一個對象。所有2個user地下并不相等

      mybatis注解開發

      手動搭建環境

      mybatis注解開發測試和使用注意事項

      • 注意事項

        但是此時同樣會報錯。也就是注解和使用xml文件,二者不能同時存在
        結論:只要你使用注解開發,但是在你的配置文件路徑下同時包含了映射配置文件,此時不管你用不用這個映射配置文件,他都會報錯(mybatis內部設置的)

      mybatis注解開發保存和更新功能

      • IUserDao接口
      package com.itheima.dao;
      
      import com.itheima.domain.User;
      import org.apache.ibatis.annotations.Insert;
      import org.apache.ibatis.annotations.Select;
      import org.apache.ibatis.annotations.Update;
      
      import java.util.List;
      
      public interface IUserDao {
          /**
           * 查詢所有
           * @return
           */
          @Select("select * from user" )
         List<User>findAll();
          /*保存操作*/
          @Insert("insert into user values(#{id},#{username},#{birthday},#{sex},#{address})")
          void save(User user);
          //更新操作
          @Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
          void update(User user);
      }
      
      
      • 著配置文件
      <?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>
      
          <!--引入外部配置文件-->
          <properties resource="jdbcConfig.properties"></properties>
          <!--將該包里面所有的類都注冊別名-->
          <typeAliases>
              <package name="com.itheima.domain"/>
          </typeAliases>
          <!--JDBC環境配置-->
          <environments default="mysql">
      
              <environment id="mysql">
                  <!--事務名稱-->
                  <transactionManager type="JDBC"></transactionManager>
      
                  <dataSource type="POOLED">
                      <property name="driver" value="${jdbc.driver}"/>
                      <property name="url" value="${jdbc.url}"/>
                      <property name="username" value="${jdbc.username}"/>
                      <property name="password" value="${jdbc.password}"/>
      
                  </dataSource>
              </environment>
          </environments>
      
       <mappers>
           <!--指定該包下面的所有dao接口的映射所在的位置-->
           <package name="com.itheima.dao"/>
       </mappers>
      
      
      
      </configuration>
      
      • 測試類
      package com.test;
      
      
      import com.itheima.dao.IUserDao;
      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.Date;
      import java.util.List;
      
      /*
       *Account表的測試
       * */
      public class AnnotationCRUDTest {
          private   InputStream in;
          private SqlSession sqlSession;
          private IUserDao userDao;
          //抽取關閉資源的方法
          @After//在測試方法之后執行
          public void close() throws Exception {
              //提交事務
      
              sqlSession.commit();
              sqlSession.close();
              in.close();
          }
          @Before//在測試方法之前執行
          //抽取初始化方法
          public void init() throws Exception{
              //1.讀取主配置文件數據
              in = Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.創建工廠
              SqlSessionFactory sqlSessionFactory= new SqlSessionFactoryBuilder().build(in);
              //3.利用工廠生成數據庫操作對象sqlSession
              sqlSession = sqlSessionFactory.openSession();
              //4.使用sqlSession生成代理對象
              userDao = sqlSession.getMapper(IUserDao.class);
          }
          @Test
          public void testSelect(){
              final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
              }
      
          }
      @Test
          public void testUpdate(){
              User user = new User();
              user.setId(577);
              user.setAddress("北京");
          user.setBirthday(new Date());
          user.setUsername("張三");
          user.setSex("女");
              userDao.update(user);
      }
          @Test
          public void testInsert(){
              User user = new User();
              user.setId(577);
              user.setAddress("湖北省十堰市");
              user.setBirthday(new Date());
              user.setUsername("黑馬程序員");
              user.setSex("男");
              userDao.save(user);
          }
      }
      
      

      mybatis注解開發CRUD的其他操作

      • dao
      package com.itheima.dao;
      
      import com.itheima.domain.User;
      import org.apache.ibatis.annotations.*;
      
      import java.util.List;
      
      public interface IUserDao {
          /**
           * 查詢所有
           * @return
           */
          @Select("select * from user" )
         List<User>findAll();
          /*保存操作*/
          @Insert("insert into user values(#{id},#{username},#{birthday},#{sex},#{address})")
          void save(User user);
          //更新操作
          @Update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}")
      
          void update(User user);
          //刪除
          @Delete("delete from user where id=#{id}")
          void deleteUser(Integer id);
          //查詢單個對象
          @Select("select * from user where id = #{id}")
          User selectOneUser(Integer id);
          //對用戶名進行模糊查詢
          @Select("select * from user where username like #{username}")
          List<User>selectByUsername(String username);
          //返回表中記錄條數
          @Select("select count(*) from user")
          int findTotal();
      }
      
      
      • 測試
      package com.test;
      
      
      import com.itheima.dao.IUserDao;
      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.Date;
      import java.util.List;
      
      /*
       *Account表的測試
       * */
      public class AnnotationCRUDTest {
          private InputStream in;
          private SqlSession sqlSession;
          private IUserDao userDao;
      
          //抽取關閉資源的方法
          @After//在測試方法之后執行
          public void close() throws Exception {
              //提交事務
      
              sqlSession.commit();
              sqlSession.close();
              in.close();
          }
      
          @Before//在測試方法之前執行
          //抽取初始化方法
          public void init() throws Exception {
              //1.讀取主配置文件數據
              in = Resources.getResourceAsStream("sqlMapConfig.xml");
              //2.創建工廠
              SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
              //3.利用工廠生成數據庫操作對象sqlSession
              sqlSession = sqlSessionFactory.openSession();
              //4.使用sqlSession生成代理對象
              userDao = sqlSession.getMapper(IUserDao.class);
          }
      
          @Test
          public void testSelect() {
              final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
              }
      
          }
      
          @Test
          public void testUpdate() {
              User user = new User();
              user.setId(577);
              user.setAddress("北京");
              user.setBirthday(new Date());
              user.setUsername("張三");
              user.setSex("女");
              userDao.update(user);
          }
      
          @Test
          public void testInsert() {
              User user = new User();
              user.setId(577);
              user.setAddress("湖北省十堰市");
              user.setBirthday(new Date());
              user.setUsername("黑馬程序員");
              user.setSex("男");
              userDao.save(user);
          }
      
          @Test
          public void testDelete() {
      
              userDao.deleteUser(577);
          }
      
          @Test
          public void testOneUser() {
      
              final User user = userDao.selectOneUser(48);
              System.out.println(user);
          }
          @Test
          public void testSelectByUsername() {
              final List<User> users = userDao.selectByUsername("%王%");
              for (User user : users) {
                  System.out.println(user);
              }
          }
      
          @Test
          public void testFindTotal() {
              final int total = userDao.findTotal();
              System.out.println(total);
          }
      }
      
      

      mybatis注解建立實體類屬性和數據庫表中列的對應關系

      • 配置resultMap結果映射(用于替代xml配置中resultMap標簽)
      • user類(屬性名稱和數據庫列名不一致)
      package com.itheima.domain;
      
      import java.io.Serializable;
      import java.util.Date;
      
      public class User implements Serializable {
          private Integer userId;
          private String userName;
          private Date userBirthday;
          private String userSex;
          private String userAddress;
      
          public User() {
          }
      
          public User(Integer userId, String userName, Date userBirthday, String userSex, String userAddress) {
              this.userId = userId;
              this.userName = userName;
              this.userBirthday = userBirthday;
              this.userSex = userSex;
              this.userAddress = userAddress;
          }
      
          /**
           * 獲取
           * @return userId
           */
          public Integer getUserId() {
              return userId;
          }
      
          /**
           * 設置
           * @param userId
           */
          public void setUserId(Integer userId) {
              this.userId = userId;
          }
      
          /**
           * 獲取
           * @return userName
           */
          public String getUserName() {
              return userName;
          }
      
          /**
           * 設置
           * @param userName
           */
          public void setUserName(String userName) {
              this.userName = userName;
          }
      
          /**
           * 獲取
           * @return userBirthday
           */
          public Date getUserBirthday() {
              return userBirthday;
          }
      
          /**
           * 設置
           * @param userBirthday
           */
          public void setUserBirthday(Date userBirthday) {
              this.userBirthday = userBirthday;
          }
      
          /**
           * 獲取
           * @return userSex
           */
          public String getUserSex() {
              return userSex;
          }
      
          /**
           * 設置
           * @param userSex
           */
          public void setUserSex(String userSex) {
              this.userSex = userSex;
          }
      
          /**
           * 獲取
           * @return userAddress
           */
          public String getUserAddress() {
              return userAddress;
          }
      
          /**
           * 設置
           * @param userAddress
           */
          public void setUserAddress(String userAddress) {
              this.userAddress = userAddress;
          }
      
          public String toString() {
              return "User{userId = " + userId + ", userName = " + userName + ", userBirthday = " + userBirthday + ", userSex = " + userSex + ", userAddress = " + userAddress + "}";
          }
      }
      
      

      package com.itheima.dao;
      
      import com.itheima.domain.User;
      import org.apache.ibatis.annotations.*;
      
      import java.util.List;
      
      public interface IUserDao {
          /**
           * 查詢所有
           * @return
           */
          @Select("select * from user" )
          @Results( id = "usermap",
               value = {@Result(id = true,property = "userId",column = "id"),//id用于標記是否為主鍵(默認為false)
                       @Result(property = "userName",column = "username"),
                       @Result(property = "userBirthday",column = "birthday"),
                       @Result(property = "userSex",column = "sex"),
                       @Result(property = "userAddress",column = "address")
               }
          )
      
         List<User>findAll();
      
          //查詢單個對象
          @Select("select * from user where id = #{id}")
          @ResultMap("usermap")//引用前面定義的結果映射
          User selectOneUser(Integer id);
          //對用戶名進行模糊查詢
          @Select("select * from user where username like #{username}")
          @ResultMap({"usermap","selectOneUser"})//引用前面定義的結果映射
          List<User>selectByUsername(String username);
      
      
      }
      
      

      這樣我們的結果集封裝就沒問題了

      mybatis注解開發一對一查詢配置

      • 在這個里面同時設置是否延遲加載
      • dao
      public interface IAccountDao {
          //查詢所有賬戶
          @Select("select * from account")
          @Results(id = "accountmap",value = {
                  //賬戶結果映射
                  @Result(id = true,property = "id",column = "id"),
                  @Result(property = "uid",column = "uid"),
                  @Result(property = "money",column = "money"),
                  
                @Result(property ="user",column = "uid",one=@One(select = "com.itheima.dao.IUserDao.findById",fetchType = FetchType.EAGER ))//指定不延遲加載
          }
          )
          List<Account> findAll();
      
      • 測試
        @Test
          public void testSelect() {
              final List<Account> accounts = accountDao.findAll();
              for (Account account : accounts) {
                  System.out.println(account);
                  System.out.println(account.getUser());
              }
      
          }
      
      


      他們的配置原理和xml文件中完全一致

      mybatis注解開發一對多查詢配置

      • dao
       @Select("select * from user" )
          @Results( id = "usermap",
               value = {@Result(id = true,property = "userId",column = "id"),//id用于標記是否為主鍵(默認為false)
                       @Result(property = "userName",column = "username"),
                       @Result(property = "userBirthday",column = "birthday"),
                       @Result(property = "userSex",column = "sex"),
                       @Result(property = "userAddress",column = "address"),
                       //根據用戶id查詢他的用戶
                       @Result(property = "accounts",column = "id",many = @Many(select = "com.itheima.dao.IAccountDao.findByUid",fetchType = FetchType.EAGER ))
               }
          )
      
         List<User>findAll();
      
      

      • 測試
         @Test
          public void testSelect() {
              final List<User> users = userDao.findAll();
              for (User user : users) {
                  System.out.println(user);
                  System.out.println("該用戶對應的賬戶是----------------------------------------------");
                  System.out.println(user.getAccounts());
                  System.out.println("-------------------------------------------------------------------------------");
              }
      
          }
      

      mybatis注解開發使用二級緩存

      一級緩存 自動開啟的





      posted @ 2023-12-17 18:40  一往而深,  閱讀(1023)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 成人AV无码一区二区三区| 欧美做受视频播放| 久久天天躁狠狠躁夜夜躁| 精品亚洲国产成人av制服| 亚洲一区二区三区在线观看精品中文| 丁香五月网久久综合| 国产精品三级中文字幕| 337p粉嫩大胆色噜噜噜| 久久精品国产熟女亚洲av| 国产精品成人午夜久久| 四虎永久地址www成人| 在国产线视频A在线视频| 秋霞电影院午夜无码免费视频| 亚洲一区二区乱码精品| 强奷白丝美女在线观看| 国产精品一区二区三区污| 蜜桃网址| 亚洲色成人一区二区三区人人澡人人妻人人爽人人蜜桃麻豆 | 久久亚洲国产精品五月天| 亚洲国产午夜精品福利| 午夜福利国产区在线观看| 亚洲一二三区精品与老人| 夜夜添无码一区二区三区| 亚洲一区成人av在线| 一本色道久久加勒比综合| 久久精品a亚洲国产v高清不卡| 99久re热视频这里只有精品6| 日本亚洲色大成网站www久久| 国产精品熟女孕妇一区二区| 久久亚洲国产精品久久| 国产精品麻豆成人av网| 一亚洲一区二区中文字幕| 精品国产成人一区二区| 四虎在线播放亚洲成人| 得荣县| 国产美女遭强高潮免费| 欧美另类图区清纯亚洲| 亚洲成人动漫av在线| 国产高清精品在线91| 亚洲欧美中文字幕5发布| 美女无遮挡免费视频网站|