MyBatis 联合查询
MyBatis 创建的一个想法:数据库不用永远是你想要的或需要它们是什么样的。而我们最喜欢的数据库最好是第三范式或 BCNF 模式,但它们有时不是。如果可能有一个单独的数据库映射,所有应用程序都可以使用它,这是非常好的,但有时也不是。结果映射就是 MyBatis 提供处理这个问题的答案。
实体类代码
-
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 方法省略 }
-
修改 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 方法省略 }
-
添加 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(); }
-
添加 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>
关联查询的两种方式配置
-
一对多关联查询 -- 同时查出所有分类及其书籍
<!-- 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>
-
一对多关联查询 -- 先查询所有分类,再根据分类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>
-
多对一 或 一对一关联查询 -- 同时查出所有分类及其书籍
<!-- 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>
-
多对一 或 一对一关联查询 -- 二次查询
<!-- 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>
MyBatis 不提供多对多映射,如果是多对多关系需要转换成 一对多 和 多对一 关系
配置文件
mybatis-config.xml 别名设置
进行别名设置后,Mapper.xml映射操作文件中可以使用别名替代原名
-
通过 typeAlias 标签将类长名命名别名
<!-- 使用别名优化 MyBatis 配置 --> <typeAliases> <typeAlias type="com.neuedu.bookstore.bean.Book" alias="Book"/> <typeAlias type="com.neuedu.bookstore.bean.Category" alias="Category"/> </typeAliases>
-
通过 package 将包别名,填写类时不用添加包名,可直接写类名
<!-- 使用别名优化 MyBatis 配置 --> <typeAliases> <!-- 命名统一规范时,才可以使用package包名简化别名 --> <package name="com.neuedu.bookstore.bean"/> </typeAliases>
-
注意事项
mybatis-config.xml
配置全局文件时,需要按照以下先后顺序进行配置(properties?, settings?, typeAliases?, typeHandlers?, objectFactory?,
objectWrapperFactory?, reflectorFactory?, plugins?, environments?, databaseIdProvider?, mappers?)
mybatis-config.xml mapper 设置
- 使用 resource 配置
<mappers> <mapper resource="com/neuedu/bookstore/mapper/BookMapper.xml"/> --> </mappers>
-
使用 calss 配置
<!-- 用于配置接口映射文件 --> <mappers> <!-- 当Mapper映射接口 与配置文件名称一致时,可以使用接口进行映射--> <mapper class="com.neuedu.bookstore.mapper.CategorykMapper"/> </mappers>
-
使用 package 配置
<!-- 用于配置接口映射文件 --> <mappers> <!-- 使用package简化mapper映射配置 --> <package name="com.neuedu.bookstore.mapper"/> </mappers>
mybatis-config.xml 使用 Properties 优化数据库连接参数配置
- 在 src 目录下新建一个文件 db_config.properties
#这是一个属性配置文件,配置了数据连接的参数 driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/ssmdb username=javauser password=123456
- 修改 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>