Java实训(5)-- MyBatis 之 联合查询 -- 2018-06-08

MyBatis 联合查询

MyBatis 创建的一个想法:数据库不用永远是你想要的或需要它们是什么样的。而我们最喜欢的数据库最好是第三范式或 BCNF 模式,但它们有时不是。如果可能有一个单独的数据库映射,所有应用程序都可以使用它,这是非常好的,但有时也不是。结果映射就是 MyBatis 提供处理这个问题的答案。

实体类代码

  1. bean 包下新增一个 Book.java

    package com.neuedu.bookstore.bean;
    
    import java.util.Date;
    
    public class Book {
        private String isbn;
        private String bookName;
        private double price;
        private Date publishDate;
        private String publisher;
        
        // MyBatis 时 orm 框架,设计实体类时需要把表关系转换成对象关系 - 本例是多对一关系
        private Category category;
    
        public Book() {
            super();
        }
    
        public Book(String isbn, String bookName, double price, Date publishDate, String publisher, Category category) {
            super();
            this.isbn = isbn;
            this.bookName = bookName;
            this.price = price;
            this.publishDate = publishDate;
            this.publisher = publisher;
            this.category = category;
        }
        
        @Override
        public String toString() {
            return "Book [isbn=" + isbn + ", bookName=" + bookName + ", price=" + price + ", publishDate=" + publishDate
                    + ", publisher=" + publisher + ", category=" + category + "]";
        } 
        
        // Getting 和 Setting 方法省略
    }
    
  2. 修改 Category.java 文件

    package com.neuedu.bookstore.bean;
    
    import java.util.List;
    
    public class Category {
        private int id;
        private String name;
        
        // 把数据关系转换成对象关系, 本例是一对多关系
        private List<Book> books;
        
        public Category() {
            super();
        }
        public Category(int id, String name) {
            super();
            this.id = id;
            this.name = name;
        }
        
        public Category(int id, String name, List<Book> books) {
            super();
            this.id = id;
            this.name = name;
            this.books = books;
        }
        public List<Book> getBooks() {
            return books;
        }
    
        @Override
        public String toString() {
            return "Category [id=" + id + ", name=" + name + ", books=" + books + "]";
        }
        // Getting 和 Setting 方法省略
    }
    
  3. 添加 Book 的数据映射接口 BookMapper.java

    package com.neuedu.bookstore.mapper;
    
    import java.util.List;
    
    import com.neuedu.bookstore.bean.Book;
    
    public interface BookMapper {
    
        public List<Book> findAll();
     
        public List<Book> findAllWithCategory();
    
    }
    
  4. 添加 Book 的数据操作映射文件 BookMapper.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">
    
    <!-- namespace 用于配置映射的数据操作接口,内容是接口的名称 -->
    <mapper namespace="com.neuedu.bookstore.mapper.BookMapper">
    </mapper>
    
    

关联查询的两种方式配置

  1. 一对多关联查询 -- 同时查出所有分类及其书籍

    <!-- filename : CategoryMapper.xml -->
    <!-- 关联查询1 -->
    <select id="findAll" resultMap="categoryMap">
        select * from category c left join book b on c.id = b.category_id
    </select>
    
    <!-- 对于复杂数据关系,mybatis可以支持自定义数据的关系映射 -->
    <resultMap type="com.neuedu.bookstore.bean.Category" id="categoryMap">
        <!-- 在自定义的关系映射中,可以通过配置指定每个查询结果与java对象的映射关系 -->
        
        <!-- id标签一般用于配置主键列或唯一键列 -->
        <id column="id" property="id" />
        <result column="name" property="name" />
        
        <!-- 一对多关系可以使用collection进行配置 -->
        <collection property="books" ofType="com.neuedu.bookstore.bean.Book">
            <result column="isbn" property="isbn"/>
            <result column="book_name" property="bookName"/>
            <result column="price" property="price"/>
            <result column="publish_date" property="publishDate"/>
            <result column="publisher" property="publisher"/>
            <result column="category_id" property="category.id"/>
        </collection>
    </resultMap>
    
    
  2. 一对多关联查询 -- 先查询所有分类,再根据分类id进行二次查询获取分类书籍

    <!-- filename : CategoryMapper.xml -->
    <!-- 关联查询2 -->
    <select id="findAll" resultMap="categoryMap2">
        select id,name from category
    </select>
    
    <resultMap id="categoryMap2" type="com.neuedu.bookstore.bean.Category">
        <!-- 
             jdbcType配置列的数据类型,类型名在 org.apache.ibatis.type.JdbcType 中查询 
             javaType属性的Java类型,mybatis提供了一系列的java类型,在官方手册中可查(大小写不敏感)  
        -->
        <id  column="id" jdbcType="INTEGER" javaType="int" property="id"></id>
        <result column="name" property="name"/>
        
        <!-- 集合数据第一次没有查询出来,需要执行二次查询 (使用 select 进行配置)-->
        <collection property="books" select="selectBookByCategory" column="id" ofType="com.neuedu.bookstore.bean.Book">
        </collection>
    </resultMap>
    
    <select id="selectBookByCategory" parameterType="int" resultMap="bookMap">
        select * from book where category_id = #{id}
    </select>
        
    <resultMap type="com.neuedu.bookstore.bean.Book" id="bookMap">
        <result column="isbn" property="isbn"/>
        <result column="book_name" property="bookName"/>
        <result column="price" property="price"/>
        <result column="publish_date" property="publishDate"/>
        <result column="publisher" property="publisher"/>
        <result column="category_id" property="category.id"/>  
    </resultMap>
    
  3. 多对一 或 一对一关联查询 -- 同时查出所有分类及其书籍

    <!-- filename : BookMapper.xml -->
    <select id="findAllWithCategory" resultMap="bookMap">
        select * from book b,category c where b.category_id = c.id
    </select>
    
    <resultMap type="com.neuedu.bookstore.bean.Book" id="resultMap2">
            <result column="isbn" property="isbn"/>
            <result column="book_name" property="bookName"/>
            <result column="price" property="price"/>
            <result column="publish_date" property="publishDate"/>
            <result column="publisher" property="publisher"/>
            <!-- 多对一 或 一对一关联查询 -->
            <association  property="category" column="category_id" javaType="com.neuedu.bookstore.bean.Category">           
                <id column="id" property="id" />
                <result column="name" property="name"/>
            </association>        
    </resultMap>
    
  4. 多对一 或 一对一关联查询 -- 二次查询

    <!-- filename : BookMapper.xml -->
    <resultMap type="com.neuedu.bookstore.bean.Book" id="bookMap">
            <result column="isbn" property="isbn"/>
            <result column="book_name" property="bookName"/>
            <result column="price" property="price"/>
            <result column="publish_date" property="publishDate"/>
            <result column="publisher" property="publisher"/>
            <!-- 多对一 或 一对一关联查询 -->
            <association  property="category" column="category_id" select="selectCategory">
            </association>
    </resultMap>
    
    <select id="findAll" resultMap="bookMap">
        select * from book
    </select>
    
    <select id="selectCategory" parameterType="int" resultType="com.neuedu.bookstore.bean.Category">
        select id,name from category where id = #{category_id}
    </select>    
    
  5. MyBatis 不提供多对多映射,如果是多对多关系需要转换成 一对多 和 多对一 关系


配置文件

mybatis-config.xml 别名设置

进行别名设置后,Mapper.xml映射操作文件中可以使用别名替代原名

  1. 通过 typeAlias 标签将类长名命名别名

    <!-- 使用别名优化 MyBatis 配置 -->
    <typeAliases>
      <typeAlias type="com.neuedu.bookstore.bean.Book" alias="Book"/>
      <typeAlias type="com.neuedu.bookstore.bean.Category" alias="Category"/> 
    </typeAliases>
    
  2. 通过 package 将包别名,填写类时不用添加包名,可直接写类名

    <!-- 使用别名优化 MyBatis 配置 -->
    <typeAliases>
      <!-- 命名统一规范时,才可以使用package包名简化别名 -->
      <package name="com.neuedu.bookstore.bean"/>
    </typeAliases>
    
  3. 注意事项

    mybatis-config.xml
    配置全局文件时,需要按照以下先后顺序进行配置

    (properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,
    objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)

mybatis-config.xml mapper 设置

  1. 使用 resource 配置
    <mappers>
      <mapper resource="com/neuedu/bookstore/mapper/BookMapper.xml"/> -->
    </mappers>
    
  1. 使用 calss 配置

    <!-- 用于配置接口映射文件 --> 
    <mappers>
      <!-- 当Mapper映射接口 与配置文件名称一致时,可以使用接口进行映射-->
      <mapper class="com.neuedu.bookstore.mapper.CategorykMapper"/>
    </mappers>
    
  2. 使用 package 配置

    <!-- 用于配置接口映射文件 --> 
    <mappers>
      <!-- 使用package简化mapper映射配置 -->
      <package name="com.neuedu.bookstore.mapper"/>
    </mappers>
    

mybatis-config.xml 使用 Properties 优化数据库连接参数配置

  1. 在 src 目录下新建一个文件 db_config.properties
    #这是一个属性配置文件,配置了数据连接的参数
    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/ssmdb
    username=javauser
    password=123456
    
  2. 修改 mybatis-config.xml 文件
    <!-- 对于系统的某些配置信息,可使用 Priperties 便签进行统一配置 -->  
    <properties resource="db_config.properties">
    </properties>
    
    <typeAliases>
      <package name="com.neuedu.bookstore.bean"/>
    </typeAliases>
    
    <environments default="development">
      <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
          <property name="driver" value="${driver}"/>
          <property name="url" value="${url}"/>
          <property name="username" value="${username}"/>
          <property name="password" value="${password}"/>
        </dataSource>
      </environment>
    </environments>
    
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,732评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,496评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,264评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,807评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,806评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,675评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,029评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,683评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,704评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,666评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,773评论 1 332
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,413评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,016评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,978评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,204评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,083评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,503评论 2 343

推荐阅读更多精彩内容