(12)Spring框架——MyBatis的学习之关联映射

2023-11-08

目录

 

一、知识点

1、配置文件元素

二、概述

1、项目结构

2、描述

三、实例

1、mybatis-config.xml

2、db.properties

3、log4j.properties

4、mapper

(1)、IdCardMapper.xml

(2)、OrdersMapper.xml

(3)、PersonMapper.xml

(4)、ProductMapper.xml

(5)、UserMapper.xml

5、po

(1)、IdCard

(2)、Orders

(3)、Person

(4)、Product

(5)、User

6、test

(1)、MybatisAssociatedTest

7、utils

(1)、MybatisUtils


一、知识点

1、配置文件元素

<properties>

该元素通常用于将内部的配置外化,即通过外部的配置来动态地替换内部定义。

 
<settings> cacheEnabled, 该配置影响所有映射器中配置的缓存全局开关,true/false,默认false.
lazyLoadingEnabled, 延迟加载的全局开关,开启时,所有关联对象都会延迟加载,特定关联关系中可以通过设置fetchType属性来覆盖该项开关状态。默认false.
aggressiveLazyLoading, 关联对象属性的延迟加载开关,当启用时,任意延迟属性调用会使带有延迟加载属性的对象完整加载反之,每种属性都会按需加载。默认true.
multipleResultSetsEnabled 是否允许单一语句返回多结果集(需要兼容驱动)默认true.
useColumnLable 使用列标签代替列明。默认true.
useGeneratedKeys 允许jdbc支持自动生成主键,需要驱动兼容。默认false.
autoMappingBehavior 指定mybatis应如何自动映射列到字段或属性。NONE表示取消自动映射。PARTIAL只会自动映射没有定义嵌套结果集;FULL会自动映射任意复杂的结果集(无论是否嵌套)。
defaultExecutorType 配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新
defaultStatementTimeout 设置超时时间,它决定驱动等待数据库响应的秒数。当没有设置的时候,它取的就是驱动默认的时间。
mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camel case)映射
jdbcTypeForNull 当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如:NULL,VARCHAR,OTHER.默认OTHER
<typeAliases> 用于为配置文件中的JAVA类型设置一个简短的名字。即设置别名,别名的设置与XML配置相关,其使用意义在于减少全限定类名的冗余。 <typeAliases><typeAlias alias="user" type="com.po.User"></typeAliases>。默认小写。
<typeHandler> javaType与jdbcType的转换。 <typeHandler><typeHandler handler="com.type.CustomtypeHandler"></typeHandler>,注册一个类的类型处理器。
<objectFactory> 实例化目标类。默认构造方法实例化,有参构造方法实例化。
<plugins> 插件拦截
<enviroments> 配置数据源,数据库。
UNPOOLED driver JDBC驱动的JAVA类的完全限定名。
url URL地址
username 用户名
password 登录数据库的密码
defaultTransactionlationLevel 默认的连接事务隔离级别。
POOLED 此数据源利用“池”的概念将JDBC连接对象组织起来。  
poolMaximumActiveConnections 在任意时间可以存在的活动。连接数量。默认值:10
poolMaximumConnections 任意时间可能存在的空闲连接数
poolMaximumCheckoutTime 在被强制返回前,池中连接被检出时间默认值20秒。
poolTimeToWait 连接超时,重新尝试获取。默认时间20秒
poolPingQuery 用于检测连接是否在正常工作秩序。
poolPingEnabled 配置。侦测查询,必须使用一个可执行SQL语句设置poolPingQuery属性(最好是一个非常快的SQL )
poolPingConnectionsNotUsedFor poolPingQuery的使用调度,可以设置超时时间,避免不要的侦测,默认值:0。poolPingEnabled为true时适用。
JNDI 可以在EJB或应用服务器容器中使用,容器可以集中或在外部配置数据源。然后放置一个JDNI上下文引用。
<mappers> 用于指定MyBatis映射文件的位置,四种方式:<mappers><mapper resource="com.stx.UserMapper.xml"><mapper url="file:///D:/com/stx/UserMapper.xml"><mapper class="com.stx.UserMapper"><packge name="com.stx.mapper"></mappers>
<select> id 表示命名空间的唯一标识,常与命名空间组合起来使用。组合后如果不唯一,mybatis会抛出异常。
parameterType 该属性表示传入SQL语句的参数类的全限定名或者别名。它是一个可选属性,因为MyBatis可以通过TypeHandler推断出具体传入语句的参数,其默认值是unset(依赖于驱动)。
resultType 从SQL语句中返回的类型的类的全限定名或者别名,(从SQL返回类的别名),如果是集合类型,那么返回的是集合可以包含的类型,而不是集合本身。返回时可以使用resultTyperesultMap之一。
resultMap 表示外部的命名引用。返回时可以使用resultTyperesultMap之一。
flushCache 在调用SQL之后,是否需要MyBatis清空之前查询的本地缓存和二级缓存。其值为布尔,默认值false.调用就会被清空。
useCache 控制二级缓存的开启和关闭。布尔,默认true,查询结果存入二级缓存。
timeout 超时参数,超时抛出异常。
fetchSize 获取记录总条数,超时抛出异常。
statementType 用于设置MyBatis使用那个JDBC的Statement工作,其值STATEMENT,PREPARED,CALLABLE,分别对应JDBC中的statement,PreparedStatement和CallableStatement。
resultSetType 表示结果集的类型,其值可设置为FORWARD_ONLY,SCROLL_SENSITIVE或SCROLL_INSENSITIVE,他的默认值unset(依赖于驱动)
<insert> keyProperty (仅对insert和update有用)插入,更新,返回值赋值给PO类的某个属性。通常会设置主键对应的属性。联合主键,多个值逗号隔开。
keyColumn 用于设置第几列是主键,不是第一列就设置,多个就用逗号隔开。
useGeneratedKeys 此属性会使用MyBatis使用JDBC的getGeneratedKeys()方法来获取由数据库内部生产的主键,如MySql和SQL Server等自动递增字段,默认值false。
<update>和<delete>    
<sql>    
<resultMap> 表示结果集映射(这个很重要)  

二、概述

1、项目结构

2、描述

(1)映射就是把数据库的表映射到实体类上面,这是一对一的映射。但是随着业务的复杂度提高,关系的复杂性使得,一对一的映射关系不能满足。所以诞生了更多是关系。就出现一对多,多对多。

(2)直观:就是把mapper设置到mabatis核心配置。mapper里面的查询结果可能包括多个表,因此需要用到resultmap里面。

三、实例

1、mybatis-config.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>
	<!-- 引入数据库连接配置文件 -->
	<properties resource="db.properties" />
	
	<settings>
     <!-- 打开延迟加载的开关 -->  
    <setting name="lazyLoadingEnabled" value="true" />  
    <!-- 将积极加载改为消息加载,即按需加载 -->  
    <setting name="aggressiveLazyLoading" value="false"/>  
	</settings>
	
	<!--使用扫描包的形式定义别名 -->
	<typeAliases>
		<package name="com.itheima.po" />
	</typeAliases>
	<!--配置环境 ,默认的环境id为mysql -->
	<environments default="mysql">
		<!-- 配置id为mysql的数据库环境 -->
		<environment id="mysql">
			<!-- 使用JDBC的事务管理 -->
			<transactionManager type="JDBC" />
			<!--数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<!--配置Mapper的位置 -->
     <mappers>
         <mapper resource="com/itheima/mapper/IdCardMapper.xml" />
         <mapper resource="com/itheima/mapper/PersonMapper.xml" />
         <mapper resource="com/itheima/mapper/UserMapper.xml" />
         <mapper resource="com/itheima/mapper/OrdersMapper.xml" />
	 	 <mapper resource="com/itheima/mapper/ProductMapper.xml" />
     </mappers>
</configuration>

 

2、db.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456

3、log4j.properties

# Global logging configuration
log4j.rootLogger=ERROR, stdout
# MyBatis logging configuration...
log4j.logger.com.itheima=DEBUG
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4、mapper

(1)、IdCardMapper.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.itheima.mapper.IdCardMapper">
  <!-- 根据id查询证件信息 -->
  <select id="findCodeById" parameterType="Integer" resultType="IdCard">
	  SELECT * from tb_idcard where id=#{id}
  </select>
</mapper>

(2)、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.itheima.mapper.OrdersMapper">
	<!-- 多对多嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
	<select id="findOrdersWithPorduct" parameterType="Integer" 
              resultMap="OrdersWithProductResult">
		select * from tb_orders WHERE id=#{id}	
	</select>
	<resultMap type="Orders" id="OrdersWithProductResult">
		<id property="id" column="id" />
		<result property="number" column="number" />
		<collection property="productList" column="id" ofType="Product" 
		     select="com.itheima.mapper.ProductMapper.findProductById">
		</collection>
	</resultMap>
	
	<!-- 多对多嵌套结果查询:查询某订单及其关联的商品详情 -->
	<select id="findOrdersWithPorduct2" parameterType="Integer" 
	         resultMap="OrdersWithPorductResult2">
	    select o.*,p.id as pid,p.name,p.price
	    from tb_orders o,tb_product p,tb_ordersitem  oi
	    WHERE oi.orders_id=o.id 
	    and oi.product_id=p.id 
	    and o.id=#{id}
	</select>
	<!-- 自定义手动映射类型 -->
	<resultMap type="Orders" id="OrdersWithPorductResult2">
	    <id property="id" column="id" />
	    <result property="number" column="number" />
	    <!-- 多对多关联映射:collection -->
	    <collection property="productList" ofType="Product">
	        <id property="id" column="pid" />
	        <result property="name" column="name" />
	        <result property="price" column="price" />
	    </collection>
	</resultMap>
	
</mapper>

(3)、PersonMapper.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.itheima.mapper.PersonMapper">
	<!-- 嵌套查询:通过执行另外一条SQL映射语句来返回预期的特殊类型 -->
	<select id="findPersonById" parameterType="Integer" 
                                      resultMap="IdCardWithPersonResult">
		SELECT * from tb_person where id=#{id}
	</select>
	<resultMap type="Person" id="IdCardWithPersonResult">
		<id property="id" column="id" />
		<result property="name" column="name" />
		<result property="age" column="age" />
		<result property="sex" column="sex" />
		<!-- 一对一:association使用select属性引入另外一条SQL语句 -->
		<association property="card" column="card_id" javaType="IdCard"
			select="com.itheima.mapper.IdCardMapper.findCodeById" />
	</resultMap>
	
	<!-- 嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集 -->
	<select id="findPersonById2" parameterType="Integer" 
	                                   resultMap="IdCardWithPersonResult2">
	    SELECT p.*,idcard.code
	    from tb_person p,tb_idcard idcard
	    where p.card_id=idcard.id 
	    and p.id= #{id}
	</select>
	<resultMap type="Person" id="IdCardWithPersonResult2">
	    <id property="id" column="id" />
	    <result property="name" column="name" />
	    <result property="age" column="age" />
	    <result property="sex" column="sex" />
	    <association property="card" javaType="IdCard">
	        <id property="id" column="card_id" />
	        <result property="code" column="code" />
	    </association>
	</resultMap>
	
</mapper>

(4)、ProductMapper.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.itheima.mapper.ProductMapper">
	<select id="findProductById" parameterType="Integer" 
                                       resultType="Product">
		SELECT * from tb_product where id IN(
		   SELECT product_id FROM tb_ordersitem  WHERE orders_id = #{id}
		)
	</select>
</mapper>

(5)、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">
<!-- namespace表示命名空间 -->
<mapper namespace="com.itheima.mapper.UserMapper">
	<!-- 一对多:查看某一用户及其关联的订单信息 
	      注意:当关联查询出的列名相同,则需要使用别名区分 -->
	<select id="findUserWithOrders" parameterType="Integer" 
						   resultMap="UserWithOrdersResult">
		SELECT u.*,o.id as orders_id,o.number 
		from tb_user u,tb_orders o 
		WHERE u.id=o.user_id 
         and u.id=#{id}
	</select>
	<resultMap type="User" id="UserWithOrdersResult">
		<id property="id" column="id"/>
		<result property="username" column="username"/>
		<result property="address" column="address"/>
		<!-- 一对多关联映射:collection 
			ofType表示属性集合中元素的类型,List<Orders>属性即Orders类 -->
		<collection property="ordersList" ofType="Orders">
			<id property="id" column="orders_id"/>
			<result property="number" column="number"/>
		</collection>
	</resultMap>
</mapper>

5、po

(1)、IdCard

package com.itheima.po;
/**
 * 证件持久化类
 */
public class IdCard {
	private Integer id;
	private String code;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	@Override
	public String toString() {
		return "IdCard [id=" + id + ", code=" + code + "]";
	}
}

(2)、Orders

package com.itheima.po;
/**
 * 证件持久化类
 */
public class IdCard {
	private Integer id;
	private String code;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getCode() {
		return code;
	}
	public void setCode(String code) {
		this.code = code;
	}
	@Override
	public String toString() {
		return "IdCard [id=" + id + ", code=" + code + "]";
	}
}

(3)、Person

package com.itheima.po;
/**
 * 个人持久化类
 */
public class Person {
	private Integer id;
	private String name;
	private Integer age;
	private String sex;
	private IdCard card;  //个人关联的证件
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public IdCard getCard() {
		return card;
	}
	public void setCard(IdCard card) {
		this.card = card;
	}
	@Override
	public String toString() {
		return "Person [id=" + id + ", name=" + name + ", "
				+ "age=" + age + ", sex=" + sex + ", card=" + card + "]";
	}
}

(4)、Product

package com.itheima.po;
import java.util.List;
/**
 * 商品持久化类
 */
public class Product {
	private Integer id;  //商品id
	private String name; //商品名称
	private Double price;//商品单价
	private List<Orders> orders; //与订单的关联属性
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Double getPrice() {
		return price;
	}
	public void setPrice(Double price) {
		this.price = price;
	}
	public List<Orders> getOrders() {
		return orders;
	}
	public void setOrders(List<Orders> orders) {
		this.orders = orders;
	}
	@Override
	public String toString() {
		return "Product [id=" + id + ", name=" + name 
				           + ", price=" + price + "]";
	}
}

(5)、User

package com.itheima.po;
import java.util.List;
/**
 * 用户持久化类
 */
public class User {
	private Integer id;                 // 用户编号
	private String username;           // 用户姓名
	private String address;            // 用户地址
	private List<Orders> ordersList; //用户关联的订单
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public List<Orders> getOrdersList() {
		return ordersList;
	}
	public void setOrdersList(List<Orders> ordersList) {
		this.ordersList = ordersList;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", username=" + username + ", address="
				+ address + ", ordersList=" + ordersList + "]";
	}
}

6、test

(1)、MybatisAssociatedTest

package com.itheima.test;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.itheima.po.Orders;
import com.itheima.po.Person;
import com.itheima.po.User;
import com.itheima.utils.MybatisUtils;
/**
 * Mybatis关联查询映射测试类
 */
public class MybatisAssociatedTest {
    /**
     * 嵌套查询
     */
    @Test
    public void findPersonByIdTest() {
        // 1、通过工具类生成SqlSession对象
        SqlSession session = MybatisUtils.getSession();
        // 2.使用MyBatis嵌套查询的方式查询id为1的人的信息
        Person person = session.selectOne("com.itheima.mapper." 
                                   + "PersonMapper.findPersonById", 1);
        // 3、输出查询结果信息
        System.out.println(person);
        // 4、关闭SqlSession
        session.close();
    }
    
    /**
     * 嵌套结果
     */
    @Test
    public void findPersonByIdTest2() {
        // 1、通过工具类生成SqlSession对象
        SqlSession session = MybatisUtils.getSession();
        // 2.使用MyBatis嵌套结果的方法查询id为1的人的信息
        Person person = session.selectOne("com.itheima.mapper." 
                                   + "PersonMapper.findPersonById2", 1);
        // 3、输出查询结果信息
        System.out.println(person);
        // 4、关闭SqlSession
        session.close();
    }
    
    /**
     * 一对多	
     */
    @Test
    public void findUserTest() {
        // 1、通过工具类生成SqlSession对象
        SqlSession session = MybatisUtils.getSession();
        // 2、查询id为1的用户信息
        User user = session.selectOne("com.itheima.mapper."
                                + "UserMapper.findUserWithOrders", 1);
        // 3、输出查询结果信息
        System.out.println(user);
        // 4、关闭SqlSession
        session.close();
    }

    /**
     * 多对多
     */
    @Test
    public void findOrdersTest(){
        // 1、通过工具类生成SqlSession对象
        SqlSession session = MybatisUtils.getSession();
        // 2、查询id为1的订单中的商品信息
        Orders orders = session.selectOne("com.itheima.mapper."
                               + "OrdersMapper.findOrdersWithPorduct", 1);
        // 3、输出查询结果信息
        System.out.println(orders);
        // 4、关闭SqlSession
        session.close();
    }


}

7、utils

(1)、MybatisUtils

package com.itheima.utils;
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;
/**
 * 工具类
 */
public class MybatisUtils {	
    public static SqlSessionFactory sqlSessionFactory = null;
    // 初始化SqlSessionFactory对象
    static{
        try {
            //使用MyBatis提供的Resources类加载mybatis的配置文件
            Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
            //构建sqlSession的工厂
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 获取SqlSession对象的静态方法
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession();
    }
}

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

(12)Spring框架——MyBatis的学习之关联映射 的相关文章

随机推荐