MyBatis 扩展结果、构造方法、鉴别器及延迟加载--4

扩展结果

1、意义:

1、扩展类:
扩展原有类的属性,并可以使其属性与其他相关的表的属性相关联
2、包装类:
用包装类传递参数,重要意义用于多表查询,将多个实体类对象作为某个包装类的属性,可以实现多表查询

2、具体示例

1、主体类和扩展类实体及其接口

//主实体类
class Test1 implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String id;
	private String name;
	private int age;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Test1 [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

//扩展类
class Test1K extends Test1 implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String kzAttribute;

	public String getKzAttribute() {
		return kzAttribute;
	}

	public void setKzAttribute(String kzAttribute) {
		this.kzAttribute = kzAttribute;
	}

}

//主体类接口
interface Test1Mapper{
	Test1 selectTest1(String id);
}

//扩展类接口
interface Test1KMapper{
	Test1K selectTest1K(String id);
}

2、主体类mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test1Mapper">
	<cache />
	<resultMap type="Test1" id="TestResultMap"></resultMap>
	
	<!-- 一对一查询 -->
	<select id="selectTest1" parameterType="string"  resultMap="TestResultMap">
		select*from test1 where id = #{id};
	</select>
	
</mapper>

3、扩展类mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test1KMapper">
	<resultMap type="Test1K" id="TestResultMap"></resultMap>
	
	<sql id="mysql">
			b.`id`, 
          	b.`name`,
            b.`age`,
          	<!-- 可将相关表中的属性扩展到此类中 -->
          	a.address as kzAttribute
	</sql>
	
	<select id="selectTest1K" parameterType="string" resultMap="TestResultMap">
		select
		<include refid="mysql"></include>
		from test1 b
		left join test2 a
		on b.id = a.tid
		where b.id = #{id}
	</select>
</mapper>

4、注意
扩展类没有实现toString(),因此无法打印所需字段,可直接get()获取
扩展类需要在mybatis-config.xml中进行别名等配置

构造方法

构造方法注入允许你在初始化时 为类设置属性的值,而不用暴露出公有方法。MyBatis 也支持私有属性和私有 JavaBeans 属 性来达到这个目的,但有一些人更青睐于构造方法注入。constructor 元素就是为此而生的。

1、加入构造方法的原因

因为mybatis框架会调用这个默认构造方法来构造实例对象。
即Class类的newInstance方法 这个方法就是通过调用默认构造方法来创建实例对象的 ,
另外再提醒一点,如果你没有提供任何构造方法,虚拟机会自动提供默认构造方法(无参构造器),但是如果你提供了其他有参数的构造方法的话,虚拟机就不再为你提供默认构造方法,这时必须手动把无参构造器写在代码里,否则new Xxxx()是会报错的,所以默认的构造方法不是必须的,只在有多个构造方法时才是必须的,这里“必须”指的是“必须手动写出来”。
当查询时,返回的实体类是一个对象实例,是mybatis动态通过反射生成的
反射的Class.forName(“className”).newInstance();需要对应的类提供一个无参构造函数

2、具体示例

1、实体及构造函数

class Test1 implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	//public Test1(){}
	
	public Test1(String id,String name,Integer age) {
		super();
		this.id = id;
		this.name = name;
		this.age = age;
		System.out.println("调用了构造方法。。。。");
	}
	
	private String id;
	private String name;
	private int age;
	
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@Override
	public String toString() {
		return "Test1 [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
	
}

2、xml文件配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test1Mapper">
	<cache />
	<resultMap type="Test1" id="TestResultMap">
		<constructor>
			<idArg column="id" javaType="string"/>
			<arg column="name" javaType="string"/>
			<arg column="age" javaType="int"/>
		</constructor>
	</resultMap>
	
	<!-- 一对一查询 -->
	<select id="selectTest1" parameterType="string"  resultMap="TestResultMap">
		select*from test1 where id = #{id};
	</select>
	
</mapper>

鉴别器

1、作用:
类型鉴别器,帮助实现创建多态的对象,用于多态映射。
鉴别器皿就是对实体有多种继承,根据实体中类别字段的不同来获取不同实体的过程。从而解决了,有多个细微差别的实体出现时,只用在原有实体对应的表中加入相应的区分字段及各自的属性,从而避免创建多个表。
2、具体示例:
实体类及子类

//主实体类
class Test1 implements Serializable{
	
	private static final long serialVersionUID = 1L;
	
	private String id;
	private String name;
	private int age;
	private String type;
	private String t11;
	private String t12;
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getType() {
		return type;
	}
	public void setType(String type) {
		this.type = type;
	}
	public String getT11() {
		return t11;
	}
	public void setT11(String t11) {
		this.t11 = t11;
	}
	public String getT12() {
		return t12;
	}
	public void setT12(String t12) {
		this.t12 = t12;
	}
}

//子类1
class Test11 extends Test1{
	
	private static final long serialVersionUID = 1L;
	
	private String t11;

	public String getT11() {
		return t11;
	}

	public void setT11(String t11) {
		this.t11 = t11;
	}

	@Override
	public String toString() {
		return "Test11 [t11=" + t11 + "]";
	}
	
}

//子类2
class Test12 extends Test1{
	
	private static final long serialVersionUID = 1L;
	
	private String t12;

	public String getT12() {
		return t12;
	}

	public void setT12(String t12) {
		this.t12 = t12;
	}

	@Override
	public String toString() {
		return "Test12 [t12=" + t12 + "]";
	}
}

实体类mapper.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test1Mapper">
	<cache />
	<resultMap type="Test1" id="TestResultMap">
		<discriminator javaType="string" column="type">
		<!-- 配置子类及对应的表中字段 -->
			<case value="1" resultType="Test11">
				<result property="t11" column="t11" />
			</case>
			<case value="2" resultType="Test12">
				<result property="t12" column="t12" />
			</case>
		</discriminator>
	</resultMap>
	
	<!-- 一对一查询 -->
	<select id="selectTest1" parameterType="string"  resultMap="TestResultMap">
		select*from test1 where id = #{id};
	</select>
	
</mapper>

延迟加载

延迟加载是指当表与表之间关联时,若不用到相关联属性,则不进行关联表的查询,若使用相关属性,再进行查询,从而提高查询速度及效率,避免资源的浪费。

1、非延迟加载

没有配置任何选项:无论是否查询Test1的任意属性,都会执行Test2数据的查询。Test1与Test2为一对一关联
Test1Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test1Mapper">
	<cache />
	<resultMap type="Test1" id="TestResultMap">
		<id column="id" property="id" jdbcType="VARCHAR"/>
		<association property="test2" column="id" select="com.my.test.Test2Mapper.selectTest2">
		</association>
	</resultMap>
	
	<!-- 一对一查询 -->
	<select id="selectTest1" parameterType="string"  resultMap="TestResultMap">
		select * from test1 where id = #{id};
	</select>
	
</mapper>

Test2Mapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"  
"http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">
<mapper namespace="com.my.test.Test2Mapper">
	<cache />
	<resultMap type="Test2" id="TestResultMap">
		 <id column="id" property="id"/>
	</resultMap>
	
	<select id="selectTest2" parameterType="string" resultMap="TestResultMap">
          select*from test2 where id = #{id};
	</select> 
</mapper>

查询结果
在这里插入图片描述

2、延迟加载

配置延迟加载步骤:
1、导入依赖

	<dependency>
		<groupId>cglib</groupId>
		<artifactId>cglib-nodep</artifactId>
		<version>2.1_3</version>
	</dependency>
	<dependency>
		<groupId>asm</groupId>
		<artifactId>asm</artifactId>
		<version>1.5.3</version>
	</dependency>
	<dependency>
		<groupId>asm</groupId>
		<artifactId>asm-attrs</artifactId>
		<version>1.5.3</version>
    </dependency>

2、在mybatis-config.xml中进行配置(settings必须在properties后和typeAliases前

	<settings>
		<setting name="lazyLoadingEnabled" value="true"></setting>
		 <setting name="aggressiveLazyLoading" value="false"></setting>
	</settings>

3、执行同样的查询–结果如下

在这里插入图片描述

3、积极的延迟加载

配置同2,执行方法时使用Test1与Test2相关联的字段
测试方法

public static void main(String[] args) {
		SqlSession session =MyBatisUtil.getSqlSession();
		Test1Mapper test1Mapper = session.getMapper(Test1Mapper.class);
		Test1 tk = test1Mapper.selectTest1("4");
		session.close();
		System.out.println(tk.toString());
	}

测试结果–使用时才会去查询
在这里插入图片描述

4、非积极的延迟加载

配置

	<settings>
		<setting name="lazyLoadingEnabled" value="true"></setting>
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

第一种:查询非mydata属性
测试方法

public static void main(String[] args) {
		SqlSession session =MyBatisUtil.getSqlSession();
		Test1Mapper test1Mapper = session.getMapper(Test1Mapper.class);
		Test1 tk = test1Mapper.selectTest1("4");
		session.close();
		System.out.println(tk.getName());
	}

测试结果
在这里插入图片描述

第二种:查询mydata属性
测试方法

public static void main(String[] args) {
		SqlSession session =MyBatisUtil.getSqlSession();
		Test1Mapper test1Mapper = session.getMapper(Test1Mapper.class);
		Test1 tk = test1Mapper.selectTest1("4");
		session.close();
		System.out.println(tk.getTest2());
	}

测试结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值