扩展结果
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());
}
测试结果