MyBatis(五):mybatis關聯映射

Mybatis中表與表之間的關係分爲一下4類:java

1)一對一node

2)一對多mysql

3)多對一git

4)多對多spring

建立數據Demo表

數據庫表:

用戶表user:記錄了購買商品的用戶信息。 sql

訂單表orders:記錄了用戶所建立的訂單(購買商品的訂單)。 數據庫

訂單明細表orderdetail:記錄了訂單的詳細信息即購買商品的信息。 apache

商品表items:記錄商品信息。windows

數據模型:

數據表之間的關係:

先分析數據級別之間有關係的表之間的業務關係:api

  • usre和orders:

user —-> orders:一個用戶能夠建立多個訂單,一對多
orders —-> user:一個訂單隻由一個用戶建立,一對一

  • orders和orderdetail:

orders —-> orderdetail:一個訂單能夠包括 多個訂單明細,由於一個訂單能夠購買多個商品,每一個商品的購買信息在orderdetail記錄,一對多關係。
orderdetail —-> orders:一個訂單明細只能包括在一個訂單中,一對一

  • orderdetail和itesm:

orderdetail —-> itesms:一個訂單明細只對應一個商品信息,一對一
items —-> orderdetail:一個商品能夠包括在多個訂單明細 ,一對多

建立Demo表

/*
Navicat MySQL Data Transfer

Source Server         : mysql1
Source Server Version : 50712
Source Host           : localhost:3306
Source Database       : relation

Target Server Type    : MYSQL
Target Server Version : 50712
File Encoding         : 65001

Date: 2019-03-24 15:57:05
*/

SET FOREIGN_KEY_CHECKS=0;

-- ----------------------------
-- Table structure for items
-- ----------------------------
DROP TABLE IF EXISTS `items`;
CREATE TABLE `items` (
  `items_id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(64) DEFAULT NULL,
  `price` double(10,2) DEFAULT NULL,
  `detail` varchar(255) DEFAULT NULL,
  `pic` varchar(255) DEFAULT NULL,
  `createtime` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of items
-- ----------------------------
INSERT INTO `items` VALUES ('1', '巧克力', '28.00', '黑巧克力', 'pic url', '2019-01-01');
INSERT INTO `items` VALUES ('2', '運動襪', '35.00', '運動襪', 'pic url', '2019-01-01');
INSERT INTO `items` VALUES ('3', '高跟鞋', '890.00', '高跟鞋', 'pic url', '2019-01-01');

-- ----------------------------
-- Table structure for orders
-- ----------------------------
DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `user_id` int(11) DEFAULT NULL,
  `number` int(11) DEFAULT NULL,
  `createtime` date DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of orders
-- ----------------------------
INSERT INTO `orders` VALUES ('1', '1', '2', '2019-03-24');
INSERT INTO `orders` VALUES ('2', '2', '1', '2019-03-22');
INSERT INTO `orders` VALUES ('3', '2', '2', '2019-03-24');

-- ----------------------------
-- Table structure for ordersdetail
-- ----------------------------
DROP TABLE IF EXISTS `ordersdetail`;
CREATE TABLE `ordersdetail` (
  `ordersdetail_id` int(11) NOT NULL AUTO_INCREMENT,
  `items_id` int(11) DEFAULT NULL,
  `items_num` int(11) DEFAULT NULL,
  `orders_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of ordersdetail
-- ----------------------------
INSERT INTO `ordersdetail` VALUES ('1', '1', '1', '1');
INSERT INTO `ordersdetail` VALUES ('2', '2', '1', '1');
INSERT INTO `ordersdetail` VALUES ('3', '1', '1', '2');
INSERT INTO `ordersdetail` VALUES ('4', '2', '1', '3');
INSERT INTO `ordersdetail` VALUES ('5', '3', '1', '3');

-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `username` varchar(32) DEFAULT NULL,
  `birthday` date DEFAULT NULL,
  `address` varchar(255) DEFAULT NULL,
  `gender` varchar(4) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES ('1', 'zhangsan', '1999-10-01', '北京市海淀區海淀黃莊', '');
INSERT INTO `user` VALUES ('2', 'lili', '1989-02-02', '北京市朝陽區大運村', '');

配置mybatis-generator插件,生成mapper、mapper.xml、model代碼:

第一步:建立demo maven項目:

填寫Group Id、Artifact Id、Packaging選擇爲pom:

此時項目值包含mybatie-study

而後,建立maven module-------選中mybatie-study maven項目,而後右鍵-》彈出菜單,菜單中選擇New->選擇Other...

在彈出New窗口中選擇Maven->Maven Module

填寫Maven Module名稱

 

點擊finish完成Maven Module建立。

第二步:在Maven Module項目mybatis-relation下/src/main/resources目錄下,建立generatorConfig.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd" >
<generatorConfiguration>
    <!-- jdbc鏈接庫jar包路徑 -->
    <classPathEntry location="D:\IDE\maven\repository\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar" />
    <!-- eclipse tool配置 Location = E:\Java\apache-maven-3.2.3\bin\mvn.bat Working 
        Direction = ${workspace_loc:/linetoy-common} Arguments = mybatis-generator:generate -->
    <context id="DB2Tables" targetRuntime="MyBatis3">
        <!-- 去掉註釋,通常都會去掉,那個註釋真的不敢讓人恭維 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true" />
        </commentGenerator>
        <!-- jdbc鏈接配置 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/relation?characterEncoding=UTF-8" userId="root"
            password="root">
        </jdbcConnection>
        <!-- 數字字段是否強制使用BigDecimal類 -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>
        <!-- entity建立後放在那個項目的哪一個包路徑上 -->
        
        <javaModelGenerator targetPackage="com.dx.mybatis01.model"
            targetProject="D:\git\springboot_learn01\mybatie-study\mybatis-relation\src\main\java">
            <property name="enableSubPackages" value="true" />
            <property name="trimStrings" value="true" />
        </javaModelGenerator> 
        
        <!-- dao建立後放在那個項目的哪一個包路徑上 -->
        <sqlMapGenerator targetPackage="com.dx.mybatis01.dao"
            targetProject="D:\git\springboot_learn01\mybatie-study\mybatis-relation\src\main\java">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>
        <!-- dao的.xml描述sql文件建立後放在那個項目的哪一個包路徑上 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="com.dx.mybatis01.dao"
            targetProject="D:\git\springboot_learn01\mybatie-study\mybatis-relation\src\main\java">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>
        <!-- 要生成的表配置,能夠多個 tableName:表名 domainObjectName:指定類名 -->
        <table tableName="orders" domainObjectName="Orders"
            enableCountByExample="false" enableUpdateByExample="false"
            enableDeleteByExample="false" enableSelectByExample="false"
            selectByExampleQueryId="false">
              <generatedKey column="id" sqlStatement="Mysql" identity="true" />
        </table>
    </context>
</generatorConfiguration>

該配置文件用來配置生成mybatis代碼規則,以及代碼生成目錄,將要生成代碼的table配置。

第三步:在Maven Module項目mybatis-relation中pom.xml中引入依賴包:

<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>
    <parent>
        <groupId>com.dx.mybatis01</groupId>
        <artifactId>mybatie-study</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.dx.mybatis01.relation</groupId>
    <artifactId>mybatis-relation</artifactId>

    <dependencies>
        <!-- 配置mybatis的開發包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.1</version>
        </dependency>
        <!-- 配置mysql支持包 -->
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>          
        <!-- 日誌 slf4j是規範/接口 日誌實現:log4j,logback,common-logging 這裏使用:slf4j + log4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.2</version>
        </dependency>
        
        <!-- https://mvnrepository.com/artifact/org.mybatis.generator/mybatis-generator-core -->
        <dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
            <version>1.3.5</version>
        </dependency>
                
    </dependencies>
    <build>
        <defaultGoal>compile</defaultGoal>
        <finalName>mybatis-plugin</finalName>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>2.1</version>
                <configuration>
                    <skip>true</skip>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.5</version>
                <configuration>   
                    <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

第四步:選中Maven Module項目右鍵運行生成mybatis代碼:

在Maven build.....彈出窗口中,Global參數中填寫「mybatis-generator:generate」,並運行

執行日誌:

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: D:\Java_Study\apache-maven-3.3.9
Java version: 1.8.0_161, vendor: Oracle Corporation
Java home: C:\Program Files\Java\jdk1.8.0_161\jre
Default locale: zh_CN, platform encoding: GBK
OS name: "windows 7", version: "6.1", arch: "amd64", family: "dos"
[DEBUG] Created new class realm maven.api
[DEBUG] Importing foreign packages into class realm maven.api
。。。。。。
[DEBUG] Populating class realm maven.api
[INFO] Error stacktraces are turned on.
[DEBUG] Reading global settings from D:\Java_Study\apache-maven-3.3.9\conf\settings.xml
[DEBUG] Reading user settings from D:\Java_Study\apache-maven-3.3.9\conf\settings.xml
[DEBUG] Reading global toolchains from D:\Java_Study\apache-maven-3.3.9\conf\toolchains.xml
[DEBUG] Reading user toolchains from C:\Users\Administrator\.m2\toolchains.xml
[DEBUG] Using local repository at D:\IDE\maven\repository
[DEBUG] Using manager EnhancedLocalRepositoryManager with priority 10.0 for D:\IDE\maven\repository
[INFO] Scanning for projects...
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for central (https://repo.maven.apache.org/maven2).
[DEBUG] Extension realms for project com.dx.mybatis01.relation:mybatis-relation:jar:0.0.1-SNAPSHOT: (none)
[DEBUG] Looking up lifecyle mappings for packaging jar from ClassRealm[plexus.core, parent: null]
[DEBUG] Extension realms for project com.dx.mybatis01:mybatie-study:pom:0.0.1-SNAPSHOT: (none)
[DEBUG] Looking up lifecyle mappings for packaging pom from ClassRealm[plexus.core, parent: null]
[DEBUG] Resolving plugin prefix mybatis-generator from [org.apache.maven.plugins, org.codehaus.mojo]
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for snapshots (http://snapshots.maven.codehaus.org/maven2).
[DEBUG] Resolved plugin prefix mybatis-generator to org.mybatis.generator:mybatis-generator-maven-plugin from POM com.dx.mybatis01.relation:mybatis-relation:jar:0.0.1-SNAPSHOT
[DEBUG] === REACTOR BUILD PLAN ================================================
[DEBUG] Project: com.dx.mybatis01.relation:mybatis-relation:jar:0.0.1-SNAPSHOT
[DEBUG] Tasks:   [mybatis-generator:generate]
[DEBUG] Style:   Regular
[DEBUG] =======================================================================
[INFO]                                                                         
[INFO] ------------------------------------------------------------------------
[INFO] Building mybatis-relation 0.0.1-SNAPSHOT
[INFO] ------------------------------------------------------------------------
[DEBUG] Resolving plugin prefix mybatis-generator from [org.apache.maven.plugins, org.codehaus.mojo]
[DEBUG] Resolved plugin prefix mybatis-generator to org.mybatis.generator:mybatis-generator-maven-plugin from POM com.dx.mybatis01.relation:mybatis-relation:jar:0.0.1-SNAPSHOT
[DEBUG] Lifecycle default -> [validate, initialize, generate-sources, process-sources, generate-resources, process-resources, compile, process-classes, generate-test-sources, process-test-sources, generate-test-resources, process-test-resources, test-compile, process-test-classes, test, prepare-package, package, pre-integration-test, integration-test, post-integration-test, verify, install, deploy]
[DEBUG] Lifecycle clean -> [pre-clean, clean, post-clean]
[DEBUG] Lifecycle site -> [pre-site, site, post-site, site-deploy]
[DEBUG] === PROJECT BUILD PLAN ================================================
[DEBUG] Project:       com.dx.mybatis01.relation:mybatis-relation:0.0.1-SNAPSHOT
[DEBUG] Dependencies (collect): []
[DEBUG] Dependencies (resolve): []
[DEBUG] Repositories (dependencies): [nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public, default, releases)]
[DEBUG] Repositories (plugins)     : [nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public, default, releases)]
[DEBUG] -----------------------------------------------------------------------
[DEBUG] Goal:          org.mybatis.generator:mybatis-generator-maven-plugin:1.3.5:generate (default-cli)
[DEBUG] Style:         Regular
[DEBUG] Configuration: <?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <configurationFile default-value="${project.basedir}/src/main/resources/generatorConfig.xml">D:\git\springboot_learn01\mybatie-study\mybatis-relation/src/main/resources/generatorConfig.xml</configurationFile>
  <contexts>${mybatis.generator.contexts}</contexts>
  <jdbcDriver>${mybatis.generator.jdbcDriver}</jdbcDriver>
  <jdbcPassword>${mybatis.generator.jdbcPassword}</jdbcPassword>
  <jdbcURL>${mybatis.generator.jdbcURL}</jdbcURL>
  <jdbcUserId>${mybatis.generator.jdbcUserId}</jdbcUserId>
  <outputDirectory default-value="${project.build.directory}/generated-sources/mybatis-generator">${mybatis.generator.outputDirectory}</outputDirectory>
  <overwrite default-value="false">true</overwrite>
  <project>${project}</project>
  <skip default-value="false">${mybatis.generator.skip}</skip>
  <sqlScript>${mybatis.generator.sqlScript}</sqlScript>
  <tableNames>${mybatis.generator.tableNames}</tableNames>
  <verbose default-value="false">true</verbose>
</configuration>
[DEBUG] =======================================================================
[INFO] 
[INFO] --- mybatis-generator-maven-plugin:1.3.5:generate (default-cli) @ mybatis-relation ---
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for apache.snapshots (http://repository.apache.org/snapshots).
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for sonatype-nexus-snapshots (https://oss.sonatype.org/content/repositories/snapshots).
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for repository.jboss.org (http://repository.jboss.org/maven2).
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for snapshots.jboss.org (http://snapshots.jboss.org/maven2).
[DEBUG] Using mirror nexus-aliyun (http://maven.aliyun.com/nexus/content/groups/public) for oss.sonatype.org/jboss-snapshots (http://oss.sonatype.org/content/repositories/jboss-snapshots).
[DEBUG] Dependency collection stats: {ConflictMarker.analyzeTime=1, ConflictMarker.markTime=0, ConflictMarker.nodeCount=17, ConflictIdSorter.graphTime=0, ConflictIdSorter.topsortTime=1, ConflictIdSorter.conflictIdCount=14, ConflictIdSorter.conflictIdCycleCount=0, ConflictResolver.totalTime=2, ConflictResolver.conflictItemCount=17, DefaultDependencyCollector.collectTime=739, DefaultDependencyCollector.transformTime=5}
[DEBUG] org.mybatis.generator:mybatis-generator-maven-plugin:jar:1.3.5:
。。。。。。
[DEBUG] Configuring mojo org.mybatis.generator:mybatis-generator-maven-plugin:1.3.5:generate from plugin realm ClassRealm[plugin>org.mybatis.generator:mybatis-generator-maven-plugin:1.3.5, parent: sun.misc.Launcher$AppClassLoader@33909752]
[DEBUG] Configuring mojo 'org.mybatis.generator:mybatis-generator-maven-plugin:1.3.5:generate' with basic configurator -->
[DEBUG]   (f) configurationFile = D:\git\springboot_learn01\mybatie-study\mybatis-relation\src\main\resources\generatorConfig.xml
[DEBUG]   (f) outputDirectory = D:\git\springboot_learn01\mybatie-study\mybatis-relation\target\generated-sources\mybatis-generator
[DEBUG]   (f) overwrite = true
[DEBUG]   (f) project = MavenProject: com.dx.mybatis01.relation:mybatis-relation:0.0.1-SNAPSHOT @ D:\git\springboot_learn01\mybatie-study\mybatis-relation\pom.xml
[DEBUG]   (f) skip = false
[DEBUG]   (f) verbose = true
[DEBUG] -- end configuration --
[INFO] Connecting to the Database
Sun Mar 24 14:42:43 CST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
[INFO] Introspecting table orders
[DEBUG] Retrieving column information for table "orders"
[DEBUG] Found column "id", data type 4, in table "relation..orders"
[DEBUG] Found column "user_id", data type 4, in table "relation..orders"
[DEBUG] Found column "number", data type 4, in table "relation..orders"
[DEBUG] Found column "createtime", data type 91, in table "relation..orders"
[INFO] Generating Record class for table orders
[INFO] Generating Mapper Interface for table orders
[INFO] Generating SQL Map for table orders
[INFO] Saving file OrdersMapper.xml
[INFO] Saving file Orders.java
[INFO] Saving file OrdersMapper.java
[WARNING] Existing file D:\git\springboot_learn01\mybatie-study\mybatis-relation\src\main\java\com\dx\mybatis01\model\Orders.java was overwritten
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1.499 s
[INFO] Finished at: 2019-03-24T14:42:44+08:00
[INFO] Final Memory: 19M/491M
[INFO] ------------------------------------------------------------------------

刷新項目,此時能夠發現項目中已經包含了新的代碼生成:

一對一查詢

實例:查詢訂單信息,關聯查詢建立訂單的用戶信息。

SELECT 
orders.*,user.username,user.gender,user.address 
FROM orders,USER 
WHERE orders.user_id = user.id

主查詢表:orders
關聯查詢表:user
聯結查詢:內聯結

利用ResultType

一、SQL語句的書寫要領:先肯定查詢的主表,在肯定查詢的關聯表,關聯查詢是使用內聯結仍是外聯結。
二、POVO擴展類建立。(這是因爲關聯查詢出來的信息是多張表的綜合字段,因此咱們能夠根據POJO建立咱們的擴展類)
三、Mapper.xml和Mapper.java的代理編寫
四、進行測試

在Maven Module項目mybatis-relation下src/main/resources下建立mybatis.cfg.xml

<?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>
    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>
    <typeAliases>
        <!-- <typeAlias type="com.demo.module.News" alias="News"/> -->
    </typeAliases>
    <environments default="development"> 
        <!-- 配置數據源的相關信息 -->
        <environment id="development">
            <transactionManager type="jdbc" /> <!-- 使用JDBC方式管理 -->
            <dataSource type="POOLED"> <!-- 設置數據源類型,此時爲POOLED -->
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/relation" />
                <!-- 設置數據庫鏈接的用戶名和密碼 -->
                <property name="username" value="root" />
                <property name="password" value="root" /> 
            </dataSource> 
        </environment>
    </environments>
    <mappers>
          <mapper resource="com/dx/mybatis01/dao/OrdersExtendsMapper.xml"></mapper>
    </mappers>
</configuration>

在com.dx.mybatis01.module下建立module:

Order.java

package com.dx.mybatis01.model;

import java.util.Date;
import java.util.List;

public class Orders {
    private Integer id;

    private Integer userId;

    private Integer number;

    private Date createtime;  
    // 用戶信息
    private User user;       
    //商品信息存放集合
    private List<OrdersDetail> orderdetails;   

    public User getUser() {
        return user;
    }

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

    public List<OrdersDetail> getOrderdetails() {
        return orderdetails;
    }

    public void setOrderdetails(List<OrdersDetail> orderdetails) {
        this.orderdetails = orderdetails;
    }

    public Integer getId() {
        return id;
    }

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

    public Integer getUserId() {
        return userId;
    }

    public void setUserId(Integer userId) {
        this.userId = userId;
    }

    public Integer getNumber() {
        return number;
    }

    public void setNumber(Integer number) {
        this.number = number;
    }

    public Date getCreatetime() {
        return createtime;
    }

    public void setCreatetime(Date createtime) {
        this.createtime = createtime;
    }
}
View Code

OrdersExtends.java

package com.dx.mybatis01.model;

public class OrdersExtends extends Orders{
    private String username;
    private String gender;
    private String address;
    ......
}

在com.dx.mybatis01.dao下建立mapper和mapper.xml:

OrdersExtendsMapper.java

package com.dx.mybatis01.dao;

import java.util.List;

import com.dx.mybatis01.model.OrdersExtends;

public interface OrdersExtendsMapper {
     List<OrdersExtends>  findOrderAndUser();
}

OrdersExtendsMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dx.mybatis01.dao.OrdersExtendsMapper">
  <select id="findOrderAndUser" resultType="com.dx.mybatis01.model.OrdersExtends">
      SELECT 
          orders.*,user.username,user.gender,user.address 
      FROM orders,USER 
      WHERE orders.user_id = user.id
  </select>
</mapper>

測試類:

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.dx.mybatis01.dao.OrdersExtendsMapper;
import com.dx.mybatis01.model.OrdersExtends;

public class OrdersExtendsTest {
    private SqlSessionFactory sqlSessionFactory = null;
    private SqlSession session = null;

    @Before
    public void Init() throws IOException {
        // 加載總配置文件,轉化爲流
        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 建立sqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
    }

    @After
    public void destory() {
        this.session.close();
    }

    @Test
    public void test() {
        OrdersExtendsMapper ordersExtendsMapper = session.getMapper(OrdersExtendsMapper.class);
        List<OrdersExtends> list = ordersExtendsMapper.findOrderAndUser();
        for (OrdersExtends o : list) {
            // getUserid沒有和數據庫對應,因此沒法獲取默認爲null
            System.out.println(o.getId() + ":" + o.getUserId() + ":" + o.getUsername() + ":" + o.getAddress());
        }
    }
}

輸出:

1:null:zhangsan:北京市海淀區海淀黃莊
2:null:lili:北京市朝陽區大運村
3:null:lili:北京市朝陽區大運村

注意:上述測試代碼中,因爲userid沒有和數據庫中的字段進行對應(user_id),因此會形成數據映射不成功而默認爲null。

項目代碼結構以下:

利用ResultMap

思路:利用 ResultMap 有點相似於Hibernate中POJO類中的設置。將咱們對應的屬性關聯到類中。
一、使用resultMap將查詢結果中的訂單信息映射到Orders對象中,
二、在orders類中添加User屬性,將關聯查詢出來的用戶信息映射到orders對象中的user屬性中。
Order.java

public class Orders {
    private Integer id;

    private Integer userId;

    private Integer number;

    private Date createtime;  
    // 用戶信息
    private User user;       
    ......
}

OrderMapper和Mapper xml以下:

OrderMapper.java

package com.dx.mybatis01.dao;

import java.util.List;

import com.dx.mybatis01.model.Orders;

public interface OrdersMapper {    
    List<Orders> findOrderAndUserResultMap();
}

OrdersMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dx.mybatis01.dao.OrdersMapper">
  <!-- 訂單查詢關聯用戶的查詢 -->
  <resultMap type="com.dx.mybatis01.model.Orders" id="OrderUserResultMap">
    <!-- 配置映射的訂單信息 -->
    <id column="id" property="id"/>
     <result column="user_id" property="userId"/>      
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/>

    <!-- 配置關聯的用戶信息
        association:用來映射關聯查詢單個對象的信息
        property :將關聯信息映射到Order的哪一個屬性中去
        javaType 映射到那個java類中
      -->
    <association property="user" javaType="com.dx.mybatis01.model.User">
    <!-- id  關聯查詢用戶的惟一標識 ,外鍵 column 指定惟一標識用戶信息的字段,property表示類中屬性 -->
        <id column="id" property="id"/>             
        <result column="username" property="username"/>
        <result column="gender" property="gender"/>
        <result column="address" property="address"/>
    </association>
  </resultMap>

  <select id="findOrderAndUserResultMap" resultMap="OrderUserResultMap">
      SELECT orders.*,user.username,user.gender,user.address 
      FROM orders,USER 
      WHERE orders.user_id = user.id
  </select>
</mapper>

測試類:

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.dx.mybatis01.dao.OrdersMapper;
import com.dx.mybatis01.model.Orders;

public class OrdersMapperTest {
    private SqlSessionFactory sqlSessionFactory = null;
    private SqlSession session = null;

    @Before
    public void Init() throws IOException {
        // 加載總配置文件,轉化爲流
        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 建立sqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
    }

    @After
    public void destory() {
        this.session.close();
    }

    @Test
    public void test() {
        OrdersMapper ordersExtendsMapper = session.getMapper(OrdersMapper.class);
        List<Orders> list = ordersExtendsMapper.findOrderAndUserResultMap();
        for (Orders o : list) {
            System.out.println(o.getId() + ":" + o.getUserId() + ":" + o.getUser().getUsername() + ":" + o.getUser().getAddress());
        }
    }
}

測試打印信息:

1:1:zhangsan:北京市海淀區海淀黃莊
2:2:lili:北京市朝陽區大運村
3:2:lili:北京市朝陽區大運村

說明:
利用 ResultMap,咱們能夠利用其中的association 屬性將外鍵關聯的相關類進行映射。這也是使用ResultMap 的便利之一。

ResultType和ResultMap實現一對一查詢比較
一、resultType:使用resultType實現較爲簡單,若是pojo中沒有包括查詢出來的列名,須要增長列名對應的屬性,便可完成映射。若是沒有查詢結果的特殊要求建議使用resultType。
二、resultMap:須要單獨定義resultMap,實現有點麻煩,若是對查詢結果有特殊的要求,使用resultMap能夠完成將關聯查詢映射pojo的屬性中。
三、resultMap能夠實現延遲加載,resultType沒法實現延遲加載。

一對多查詢

實例:查詢訂單及訂單明細的信息。

        SELECT
            t10.id,t10.user_id,t10.number,t10.createtime,
            t11.username,t11.gender,t11.address,
            t12.ordersdetail_id,t12.items_id,t12.items_num,t12.orders_id
        FROM orders t10
        inner join USER t11 on t10.user_id=t11.id
        left outer join ordersdetail t12 on t10.id=t12.orders_id

主查詢表:orders
肯定關聯查詢表:orderdetail
聯結查詢:內聯結

利用resultType將上邊的 查詢結果映射到pojo中,訂單信息的就是重複。而咱們對於對orders映射不能出現重複記錄。因此咱們這裏只能利用ResultMap。

利用ResultMap

POJO類

// POJO類
    public class User {
        private int id;
        private String username;
        private Date birthday;
        private String address;
        private String gender;
    }



    public class Orders {

        private User user;

        private int id;
        private int userId;
        private String number;
        private Date createtime;
        private String note;

        private List<OrdersDetail> orderdetails;  //  一對多關係設置

    }

    public class OrdersDetail {
        private int id;
        private int ordersId;
        private int itemsId;
        private int itemsNum;

    }

OrdersMapper.java

package com.dx.mybatis01.dao;

import java.util.List;

import com.dx.mybatis01.model.Orders;

public interface OrdersMapper {
    // 查詢訂單(關聯用戶)訂單明細
    public List<Orders> findOrderAndDetailResultMap();
}

OrdersMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dx.mybatis01.dao.OrdersMapper">
    <resultMap type="com.dx.mybatis01.model.Orders" id="OrderAndDetailResultMap">
        <!-- 配置映射的訂單信息 -->
        <id column="id" property="id" />
        <result column="user_id" property="userId" />
        <result column="number" property="number" />
        <result column="createtime" property="createtime" />

        <!-- 配置關聯的用戶信息 association:用來映射關聯查詢單個對象的信息 一對多的逆向使用 property :將關聯信息映射到Order的哪一個屬性中去 
            javaType 映射到那個java類中 -->
        <association property="user" javaType="com.dx.mybatis01.model.User">
            <!--  id 關聯查詢用戶的惟一標識 ,外鍵 column 指定惟一標識用戶信息的列  -->
            <id column="id" property="id" />
            <result column="username" property="username" />
            <result column="gender" property="gender" />
            <result column="address" property="address" />
        </association>

        <!-- 訂單明細信息 一個訂單包含多條明細,要使用collection進行映射 一對多使用 配置在一的一方添加屬性 collection:對關聯查詢的多條記錄映射到集合對象中去 
            property: 將關聯查詢出來的多條記錄映射到類中的那個屬性中 list ofType : 指定映射到集合屬性中的pojo類,list的泛型 -->
        <collection property="orderdetails" ofType="com.dx.mybatis01.model.OrdersDetail">
            <!-- id 訂單明細惟一標識 -->
            <id column="ordersdetail_id" property="id" />
            <result column="items_id" property="itemsId" />
            <result column="items_num" property="itemsNum" />
            <result column="orders_id" property="ordersId" />
        </collection>
    </resultMap>

    <select id="findOrderAndDetailResultMap" resultMap="OrderAndDetailResultMap">
        SELECT
            t10.id,t10.user_id,t10.number,t10.createtime,
            t11.username,t11.gender,t11.address,
            t12.ordersdetail_id,t12.items_id,t12.items_num,t12.orders_id
        FROM orders  t10
        inner join USER t11 on t10.user_id=t11.id
        left outer join ordersdetail t12 on t10.id=t12.orders_id
    </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.dx.mybatis01.dao.OrdersMapper">
    <resultMap id="BaseResultMap" type="com.dx.mybatis01.model.Orders">
        <id column="id" jdbcType="INTEGER" property="id" />
        <result column="user_id" jdbcType="INTEGER" property="userId" />
        <result column="number" jdbcType="INTEGER" property="number" />
        <result column="createtime" jdbcType="DATE" property="createtime" />
    </resultMap>
    <sql id="Base_Column_List">
        id, user_id, number, createtime
    </sql>
    <!-- 訂單查詢關聯用戶的查詢 -->
    <resultMap type="com.dx.mybatis01.model.Orders" id="OrderUserResultMap"
        extends="BaseResultMap">
        <!-- 配置關聯的用戶信息 association:用來映射關聯查詢單個對象的信息 property :將關聯信息映射到Order的哪一個屬性中去 
            javaType 映射到那個java類中 -->
        <association property="user" javaType="com.dx.mybatis01.model.User">
            <!-- id 關聯查詢用戶的惟一標識 ,外鍵 column 指定惟一標識用戶信息的字段,property表示類中屬性 -->
            <id column="id" property="id" />
            <result column="username" property="username" />
            <result column="gender" property="gender" />
            <result column="address" property="address" />
        </association>
    </resultMap>

    <resultMap type="com.dx.mybatis01.model.Orders" id="OrderAndDetailResultMap"
        extends="OrderUserResultMap">
        <!-- 訂單明細信息 一個訂單包含多條明細,要使用collection進行映射 一對多使用 配置在一的一方添加屬性 collection:對關聯查詢的多條記錄映射到集合對象中去 
            property: 將關聯查詢出來的多條記錄映射到類中的那個屬性中 list ofType : 指定映射到集合屬性中的pojo類,list的泛型 -->
        <collection property="orderdetails" ofType="com.dx.mybatis01.model.OrdersDetail">
            <!-- id 訂單明細惟一標識 -->
            <id column="ordersdetail_id" property="id" />
            <result column="items_id" property="itemsId" />
            <result column="items_num" property="itemsNum" />
            <result column="orders_id" property="ordersId" />
        </collection>
    </resultMap>

    <select id="findOrderAndDetailResultMap" resultMap="OrderAndDetailResultMap">
        SELECT
            t10.id,t10.user_id,t10.number,t10.createtime,
            t11.username,t11.gender,t11.address,
            t12.ordersdetail_id,t12.items_id,t12.items_num,t12.orders_id
        FROM orders t10
        inner join USER t11 on t10.user_id=t11.id
        left outer join ordersdetail t12 on t10.id=t12.orders_id
    </select>
</mapper>

測試代碼:

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.dx.mybatis01.dao.OrdersMapper;
import com.dx.mybatis01.model.Orders;
import com.dx.mybatis01.model.OrdersDetail;

public class OrdersMapperTest {
    private SqlSessionFactory sqlSessionFactory = null;
    private SqlSession session = null;

    @Before
    public void Init() throws IOException {
        // 加載總配置文件,轉化爲流
        String resource = "mybatis.cfg.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 建立sqlSessionFactory
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        session = sqlSessionFactory.openSession();
    }

    @After
    public void destory() {
        this.session.close();
    }

    @Test
    public void test() {
        OrdersMapper ordersExtendsMapper = session.getMapper(OrdersMapper.class);
        List<Orders> list = ordersExtendsMapper.findOrderAndDetailResultMap();
        for (Orders o : list) {
            System.out.println(o.getId() + ":" + o.getUserId() + ":" + o.getUser().getUsername() + ":"
                    + o.getUser().getAddress() + ":o.getOrderdetails().size()=" + o.getOrderdetails().size());
            for (OrdersDetail od : o.getOrderdetails()) {
                System.out.println("------" + od.getId() + ":" + od.getItemsId() + ":" + od.getItemsNum()
                        + ":" + od.getOrdersId());
            }
        }
    }
}

添加log4j.properties配置,設置打印執行sql,在Maven Module項目mybatis-relation中src/main/resources下添加log4j.properties

log4j.rootLogger=debug,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout

log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.Java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

打印執行結果:

log4j:ERROR Could not find value for key log4j.appender.logfile
log4j:ERROR Could not instantiate appender named "logfile".
DEBUG - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - PooledDataSource forcefully closed/removed all connections.
DEBUG - Opening JDBC Connection
Sun Mar 24 17:10:10 CST 2019 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
DEBUG - Created connection 1295083508.
DEBUG - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4d3167f4]
DEBUG - ==>  Preparing: 

SELECT
  t10.id,t10.user_id,t10.number,t10.createtime, t11.username,t11.gender,t11.address, t12.ordersdetail_id,t12.items_id,t12.items_num,t12.orders_id
FROM orders t10 inner
join USER t11 on t10.user_id=t11.id
left outer join ordersdetail t12 on t10.id=t12.orders_id
DEBUG
- ==> Parameters: DEBUG - <== Total: 5 1:1:zhangsan:北京市海淀區海淀黃莊:o.getOrderdetails().size()=2 ------1:1:1:1 ------2:2:1:1 2:2:lili:北京市朝陽區大運村:o.getOrderdetails().size()=1 ------3:1:1:2 3:2:lili:北京市朝陽區大運村:o.getOrderdetails().size()=2 ------4:2:1:3 ------5:3:1:3 DEBUG - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4d3167f4] DEBUG - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@4d3167f4] DEBUG - Returned connection 1295083508 to pool.

注意:

對於一對多或者多對一的查詢,建議使用ResultMap映射進行代碼編寫,
mybatis使用resultMap的collection對關聯查詢的多條記錄映射到一個list集合屬性中。

使用resultType實現:
將訂單明細映射到orders中的orderdetails中,須要本身處理,使用雙重循環遍歷,去掉重複記錄,將訂單明細放在orderdetails中。
特別注意:

若是上邊ordersdetail的惟一鍵數據庫列名字爲id,則會致使order關聯出來ordersdetail記錄只爲一條記錄。

多對多查詢

實例:查詢用戶及用戶購買商品信息。 
查詢主表是:user 
關聯表:因爲用戶和商品沒有直接關聯,經過訂單和訂單明細進行關聯,因此關聯表: 
orders、orderdetail、items 
聯結查詢:內聯結

利用ResultMap

POJO類

    public class User {
        private int id;
        private String username;
        private Date birthday;
        private String address;
        private String sex;
        private List<Orders> orderslist;    //一對多
    }

    public class Orders {
        private User user;      // 用戶信息
        private int id;
        private int userId;
        private String number;
        private Date createtime;
        private String note;
        private List<OrdersDetail> orderdetails;    //商品信息存放集合
    }

    public class OrdersDetail {
        private int id;
        private int ordersId;
        private int itemsId;
        private int itemsNum;
        private Items items;    //商品信息
    }

    public class Items {
        private int id;
        private String name;
        private double price;
        private String detail;
        private String pic;
        private Date createtime;
    }

 UserMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.dx.mybatis01.dao.UserMapper">   
    <!-- 用戶及用戶購買的商品明細 -->
    <resultMap type="com.dx.mybatis01.model.User" id="UserAndItemResultMap">
        <!-- 映射用戶信息 -->
        <id column="user_id" property="id" />
        <result column="username" property="username" />
        <result column="gender" property="gender" />
        <result column="address" property="address" />

        <!-- 訂單信息 一個用戶建立多個訂單 使用collection -->
        <collection property="orderslist" ofType="com.dx.mybatis01.model.Orders">
            <id column="id" property="id" />
            <result column="user_id" property="userId" />
            <result column="number" property="number" />
            <result column="createtime" property="createtime" />

            <!-- 訂單明細 一個訂單包含多個訂單明細 因此寫在訂單信息裏面 -->

            <collection property="orderdetails" ofType="com.wf.model.OrdersDetail">
                <!-- id 訂單明細惟一標識 -->
                <id column="orderdetail_id" property="id" />
                <result column="items_id" property="itemsId" />
                <result column="items_num" property="itemsNum" />
                <result column="orders_id" property="ordersId" />

                <!-- 商品信息 一個訂單明細對應一個商品 -->
                <association property="items" javaType="com.wf.model.Items">
                    <id column="items_id" property="id" />
                    <result column="items_name" property="name" />
                    <result column="item_price" property="price" />
                    <result column="item_datail" property="detail" />
                </association>
            </collection>
        </collection>
    </resultMap>
    <select id="findUserAndItemResultMap" resultMap="UserAndItemResultMap">
        select
         t10.*,t11.*,t12.*,t13.*
        from user t10
        left outer join orders t11 on t10.user_id=t11.id
        left outer join ordersdetail t12 on t11.id=t12.order_id
        left outer join items t13 on t12.items_id=t13.items_id
        where id = #{id,jdbcType=INTEGER}
    </select>
</mapper>

 注意:

這裏是把user的id修改成了user_id,不然也會形成上邊提到的錯誤,致使關聯出來訂單不是多條只能是一條。

參考:

https://blog.csdn.net/sinat_28978689/article/details/74999738

相關文章
相關標籤/搜索