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>
    
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容