实例解析:MyBatis中复杂resultMap结果映射
来源:互联网 发布:彩票预测算法 编辑:程序博客网 时间:2024/05/16 11:02
resultMap是MyBatis里面最复杂的元素,它的作用是定义映射规则、级联的更新、定制类型转化器等。
在实际的应用中,数据库中的实体存在三种基本的级联关系:
1、一对一关系
2、一对多关系
3、多对多关系
多对多关系在转化成物理表结构之后,可以分解为两个一对多的关系。那么在使用MyBatis时,如何处理“一对一关系”,“多对多关系”?
在MyBatis中,官方文档描述如下:
resultMap:
- constructor - 类在实例化时,用来注入结果到构造方法中
idArg - ID 参数;标记结果作为 ID 可以帮助提高整体效能
arg - 注入到构造方法的一个普通结果 - id – 一个 ID 结果;标记结果作为 ID 可以帮助提高整体效能
- result – 注入到字段或 JavaBean 属性的普通结果
- association – 一个复杂的类型关联;许多结果将包成这种类型
嵌入结果映射 – 结果映射自身的关联,或者参考一个 - collection – 复杂类型的集
嵌入结果映射 – 结果映射自身的集,或者参考一个 - discriminator – 使用结果值来决定使用哪个结果映射
case – 基于某些值的结果映射
◾嵌入结果映射 – 这种情形结果也映射它本身,因此可以包含很多相 同的元素,或者它可以参照一个外部的结果映射。
代码片段……,一个resultMap的例子:
<resultMap id="productsResultMap" type="com.keymen.domain.Products"> <id column="productid" property="productid" jdbcType="VARCHAR" /> <result column="productname" property="productname" jdbcType="VARCHAR" /> <result column="productmemo" property="productmemo" jdbcType="VARCHAR" /> <result column="createtime" property="createtime" jdbcType="TIMESTAMP" /> <result column="updatetime" property="updatetime" jdbcType="TIMESTAMP" /> <result column="deletetime" property="deletetime" jdbcType="TIMESTAMP" /> <!-- 定义产品类型与产品的对应关系 ,一个产品类型对应多个产品,这是一对多的关系 --> <association property="prodtype" resultMap="productsTypeResult" /> </resultMap>
关联
关联元素处理“有一个”类型的关系。比如,在我们的示例中,一个博客有一个用户。 关联映射就工作于这种结果之上。你指定了目标属性,来获取值的列,属性的 java 类型(很多情况下 MyBatis 可以自己算出来) ,如果需要的话还有 jdbc 类型,如果你想覆盖或获取的结果值还需要类型控制器。
关联中不同的是你需要告诉 MyBatis 如何加载关联。MyBatis 在这方面会有两种不同的 方式:
- 嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型。
- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集。首先,然让我们来查看这个元素的属性。所有的你都会看到,它和普通的只由select 和resultMap 属性的结果映射不同。
下面通过实例在说明resultMap结果映射的关系(一对一)
需要提前准备的内容:
在MySQL数据库中,创建一个testdb数据库。再创建两张数据表:
- 产品类型表(tb_products_type)
- 产品表(tb_products)
其中包含的实体关系:每一个产品都有唯一的产品类型;而一类产品类型,包含多个产品。
创建数据表的SQL语句如下:
create table tb_products_type(prodtypeid integer not null primary key,prodtypename varchar(40) not null,prodparentid integer,createtime time,updatetime time,deletetime time);create table tb_products(productid varchar(40) not null primary key,prodtypeid integer not null,productname varchar(80) not null,productunit varchar(40),productmemo varchar(100),createtime time,updatetime time,deletetime time);
需要注意的是,要在产品表(tb_products表)中的prodtypeid列上建外键(Foreign Key)。
向表中插入测试数据:
insert into tb_products_type values(1001,'Clothes',null,now(),null,null);insert into tb_products_type values(4210,'Man Suit',1001,now(),null,null);insert into tb_products values('TC180001',4210,'Dock Man Suit','unit','Made in China',now(),null,null);commit;
查询表中的数据。
这样数据库表就准备好了。
下面在创建JAVA Project类实现复杂的resultMap结果映射。
1. 规划工程的包结构和配置文件结构
src
- com.keymen.application
- com.keymen.dao
- com.keymen.domain
- com.keymen.sqlMappers
- com.keymen.test
- Configurations.xml
-jdbc.properties
-mybatis.xml
再在工程中加入包:
mybatis-3.2.6.jar和mysql-connector-java-5.1.13-bin.jar。
2. 编写POJO类
2.1 编写产品类型POJO类:ProductsType
package com.keymen.domain;import java.util.Date;public class ProductsType { private int producttypeid; private String prodtypename; private int prodparentid; private Date createtime; private Date updatetime; private Date deletetime; public ProductsType() { super(); } public ProductsType(int producttypeid, String prodtypename, int prodparentid, Date createtime, Date updatetime, Date deletetime) { super(); this.producttypeid = producttypeid; this.prodtypename = prodtypename; this.prodparentid = prodparentid; this.createtime = createtime; this.updatetime = updatetime; this.deletetime = deletetime; } public int getProducttypeid() { return producttypeid; } public void setProducttypeid(int producttypeid) { this.producttypeid = producttypeid; } public String getProdtypename() { return prodtypename; } public void setProdtypename(String prodtypename) { this.prodtypename = prodtypename; } public int getProdparentid() { return prodparentid; } public void setProdparentid(int prodparentid) { this.prodparentid = prodparentid; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public Date getUpdatetime() { return updatetime; } public void setUpdatetime(Date updatetime) { this.updatetime = updatetime; } public Date getDeletetime() { return deletetime; } public void setDeletetime(Date deletetime) { this.deletetime = deletetime; }}
2.2 编写产品POJO类:Products
package com.keymen.domain;import java.util.Date;public class Products { private String productid; //注意这个属性:产品类型对象 private ProductsType prodtype; private String productname; private String productunit; private String productmemo; private Date createtime; private Date updatetime; private Date deletetime; public Products() { super(); } public Products(String productid, ProductsType prodtype, String productname, String productunit, String productmemo, Date createtime, Date updatetime, Date deletetime) { super(); this.productid = productid; this.prodtype = prodtype; this.productname = productname; this.productunit = productunit; this.productmemo = productmemo; this.createtime = createtime; this.updatetime = updatetime; this.deletetime = deletetime; } public String getProductid() { return productid; } public void setProductid(String productid) { this.productid = productid; } public ProductsType getProdtype() { return prodtype; } public void setProdtype(ProductsType prodtype) { this.prodtype = prodtype; } public String getProductname() { return productname; } public void setProductname(String productname) { this.productname = productname; } public String getProductunit() { return productunit; } public void setProductunit(String productunit) { this.productunit = productunit; } public String getProductmemo() { return productmemo; } public void setProductmemo(String productmemo) { this.productmemo = productmemo; } public Date getCreatetime() { return createtime; } public void setCreatetime(Date createtime) { this.createtime = createtime; } public Date getUpdatetime() { return updatetime; } public void setUpdatetime(Date updatetime) { this.updatetime = updatetime; } public Date getDeletetime() { return deletetime; } public void setDeletetime(Date deletetime) { this.deletetime = deletetime; }}
3. 编写MyBatis配置文件:Configurations.xml
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> <properties resource="jdbc.properties"></properties> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driverClassName}" /> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/keymen/sqlMappers/products.xml" /> </mappers></configuration>
编写 jdbc.properties数据库连接配置文件
jdbc.driverClassName=com.mysql.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/testdbjdbc.username=rootjdbc.password=baggio800jdbc.initialSize=0jdbc.maxActive=20jdbc.maxIdle=20jdbc.minIdle=1jdbc.maxWait=60000
4. 编写XML映射文件
mybatis.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> <mappers> <mapper resource="com/keymen/sqlMappers/products.xml" /> </mappers></configuration>
编写products.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.keymen.dao.ProductsDAO"> <resultMap id="productsResultMap" type="com.keymen.domain.Products"> <id column="productid" property="productid" jdbcType="VARCHAR" /> <result column="productname" property="productname" jdbcType="VARCHAR" /> <result column="productmemo" property="productmemo" jdbcType="VARCHAR" /> <result column="createtime" property="createtime" jdbcType="TIMESTAMP" /> <result column="updatetime" property="updatetime" jdbcType="TIMESTAMP" /> <result column="deletetime" property="deletetime" jdbcType="TIMESTAMP" /> <!-- 定义产品类型与产品的对应关系 ,一个产品类型对应多个产品,这是一对多的关系 --> <association property="prodtype" resultMap="productsTypeResult" /> </resultMap> <resultMap id="productsTypeResult" type="com.keymen.domain.ProductsType"> <!-- 注意此处,在Domain类中的属性和在数据库表中对应的字段名称不一致,下面的property和column的对应关系 --> <id property="producttypeid" column="prodtypeid" /> <result property="prodtypename" column="prodtypename" /> <result property="prodparentid" column="prodparentid" /> <result property="createtime" column="createtime" /> <result property="updatetime" column="updatetime" /> <result property="deletetime" column="deletetime" /> </resultMap> <select id="getProductsByID" resultMap="productsResultMap"> select p.productid,p.productname,p.prodtypeid,pt.prodtypename from tb_products p join tb_products_type pt on p.prodtypeid=pt.prodtypeid and p.productid = #{id} </select></mapper>
5. 编写DAO接口
package com.keymen.dao;import com.keymen.domain.Products;public interface ProductsDAO { public Products getProductsByID(String productid);}
6. 编写测试类
package com.keymen.test;import java.io.IOException;import java.io.Reader;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 com.keymen.dao.ProductsDAO;import com.keymen.domain.Products;public class TestSelectProducts { public static void main(String[] args) { // TODO Auto-generated method stub String resource = "Configurations.xml"; // 通过Mybatis包中的Resources对象很轻松的获取到配置文件 Reader reader = null; try { reader = Resources.getResourceAsReader(resource); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } // 通过SqlSessionFactoryBuilder创建 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); // 获得session实例 SqlSession session = sqlSessionFactory.openSession(); if (session != null) { System.out.println("Already got session ...."); ProductsDAO productDAO = session.getMapper(ProductsDAO.class); Products product = productDAO.getProductsByID("TC180001"); System.out.println("executing searching...."); System.out.println(product.getProductname() + "\n" + product.getProdtype().getProducttypeid() + "\n" + product.getProdtype().getProdtypename() + "\n"); } else { System.out.println("session is null...."); } session.commit(); session.close(); System.out.println(sqlSessionFactory); }}
7. 总结
运行结果:
Already got session ….
executing searching….
Dock Man Suit (数据来自产品表)
4210 (数据来自产品类型表)
Man Suit (数据来自产品类型表)
从运行结果来看:
程序创建了session,然后执行查询,从产品表和产品类型表中进行了连接查询,获取了相应的数据。
完毕。
- 实例解析:MyBatis中复杂resultMap结果映射
- MyBatis结果集映射(ResultMap)
- [mybatis]ResultMap输出结果映射
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- Mybatis 高级结果映射 ResultMap Association Collection
- 设计模式--[4]建造者模式和AlertDialog源码解析
- 第二单元作业
- Android 耳机插拔流程源码跟踪浅析
- 【NOI】7084 迷宫问题
- RecycleView 动画实现
- 实例解析:MyBatis中复杂resultMap结果映射
- 排序:插入排序
- SecureCRT配色推荐和永久设置
- 1.自然语言处理(NLP)与Python
- Struts2示例
- LINUX系统资源监控工具nmon的使用
- java开发系统内核:实现进程自动切换,再现Linus当年辉煌一刻
- String类及String类常用的方法
- RecyclerView 的点击事件!