Mybatis全面详解——下(学习总结)

1、Mybatis关联查询映射

这里采用一个案例来进行分析:(下面的案例都是采用Mapper接口编程的方式来实现)html

数据库准备:在数据库中建立一个Mybatis数据库,并在中建立user(用户)、orders(订单)、orderdetail(订单详情)、items(商品)表。java

各表的设计:mysql

user表:git


orders表:github

orderdetail表:sql

items表:数据库

表与表的关系:编程

user/orders表:mybatis

user——>orders:一个用户能够有多个订单;一对多oracle

orders——>user:一个订单只能由一个用户建立;一对一

orders/orderdetail表:

orders——>orderdetail:一个订单有多个订单详情,由于一个订单可能包含多个商品;一对多

orderdetail——>orders:一个订单详情只能包含在一个订单当中;一对一

orderdetail/items表:

orderdetail——>items:一个订单明细只能对应一个商品;一对一

items——>orderdetail:一个商品能够有多个订单明细;一对多。


为每一个表建立一个javaBean对象:

user表对应的User类:

public class User {
	private Integer id;
	private String username;
	private Date birthday;
	private String sex;
	private String address;
        //省略getter和setter方法
}

orders表对应的Orders类:

public class Orders {
	private Integer id;
	private Integer user_id;
	private String number;
	private Date createtime;
	private String note;
        //省略getter和setter方法
}

orderdetail表对应的Orderdetail类:

public class Orderdetail {
	private Integer id;
	private Integer ordersId;
	private Integer itemsId;
	private Integer itemsNum;
        //省略getter和setter方法
}

items表对应的Items类:

public class Items {
	private Integer id;
	private String name;
	private float price;
	private String text;
	private String pic;
	private Date createtime;
        //省略getter和setter方法
}
1.1.一对一查询

需求分析:

查询订单信息,关联查询用户信息。

sql语句:

肯定查询主表:订单表

肯定查询从表:用户表

SELECT
        orders.`id`,
        orders.`user_id` userId,
        orders.`number`,
        user.`username`,
        user.`sex`
        FROM
        orders,
        USER
        WHERE orders.`user_id` = user.`id`

方式一:采用resultType结果集映射:

因为resultType结果集映射时把查询出来的结果集中的每一列和javaBean对象中每一个属性进行一一对应。然而在咱们建立的javaBean中Orders表并不知足查询结果集的要求,所以这里就对Orders类进行扩展。

扩展javaBean:OrdersExt

public class OrdersExt extends Orders{
	private String username;
	private String sex;
        //省略getter和setter方法
}

编写Mapper接口:

public interface OrdersMapper {
	public List<OrdersExt> findOrdersAndUser();
}

编写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.lc.mybatis.mapper.OrdersMapper">

	<!-- 一对一resultType结果映射 -->
	<select id="findOrdersAndUser" resultType="ordersExt">
		SELECT
		orders.`id`,
		orders.`user_id` userId,
		orders.`number`,
		user.`username`,
		user.`sex`
		FROM
		orders,
		USER
		WHERE orders.`user_id` = user.`id`
	</select>
</mapper>

把OrdersMapper.xml映射文件加载到全局配置文件中SqlMapConfig.xml文件中:

我这里使用的是加载包下的全部映射文件的方式来加载映射文件;

<!-- 加载映射文件 -->
	<mappers>
		<!-- 注册指定包下的全部映射文件 -->
		<package name="com.lc.mybatis.mapper"/>
	</mappers>


测试类:

public class OrdersMapperTest {

private SqlSessionFactory sqlSessionFactory ;
	
	@Before
	public void setUp() throws IOException {
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public void testFindOerdersAndUser() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//获取UserMapper的代理类
		OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
		List<OrdersExt> lists = ordersMapper.findOrdersAndUser();
		System.out.println(lists);
		sqlSession.close();
	}
}

方式二:采用resultMap结果集映射

使用resultMap对结果集映射,须要先声明resultMap,由于resultMap是对查询出来的结果集中的每一列进行手动指定映射到javaBean对象中哪一个属性上。

修改OrdersExt类:

public class OrdersExt extends Orders{
	private User user;
        //省略getter和setter方法
}

修该OrdersMapper.xml映射文件:

其中映射文件中的:<association property="指定关联关系映射到OrdersExt的哪一个属性上" javaType="指定该属性的java类型">;该标签是一对一所使用的关联标签。

<?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.lc.mybatis.mapper.OrdersMapper">	
	<!-- 一对一resultMap结果映射 -->
	<!-- 声明resultMap -->
	<resultMap type="ordersExt" id="findOrdersAndUserRstMap">
		<!-- 订单信息 -->
		<id column="id" property="id"/>
		<result column="userId" property="userId"/>
		<result column="number" property="number"/>
		<!-- 用户信息(一对一) -->
		<!--association标签:一对一映射  -->
		<!-- property属性:指定关联信息映射到OrdersExt的哪一个属性上 -->
		<!-- javaType属性:指定关联属性的java类型 -->
		<association property="user" javaType="user">
			<id column="userId" property="id"/>
			<result column="username" property="username"/>
			<result column="sex" property="sex"/>
		</association>
	</resultMap>
	<select id="findOrdersAndUserRstMap" resultMap="findOrdersAndUserRstMap">
		SELECT
		orders.`id`,
		orders.`user_id`userId,
		orders.`number`,
		user.`username`,
		user.`sex`
		FROM
		orders,
		USER
		WHERE orders.`user_id` = user.`id`
	</select>

</mapper>

修改Mapper接口:

public interface OrdersMapper {
	public List<OrdersExt> findOrdersAndUserRstMap();
}

测试类:

public class OrdersMapperTest {

private SqlSessionFactory sqlSessionFactory ;
	
	@Before
	public void setUp() throws IOException {
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public void testFindOrdersAndUserRstMap() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//获取UserMapper的代理类
		OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
		List<OrdersExt> lists = ordersMapper.findOrdersAndUserRstMap();
		sqlSession.close();
	}
}
1.2.一对多关联查询

需求分析:

查询订单信息及订单明细信息。

sql语句:

查询主表:订单表

查询从表:用户表和订单详情表

SELECT
        orders.`id`,
        orders.`user_id`,
        orders.`number`,
        user.`username`,
        user.`sex`,
        orderdetail.`id` detailId,
        orderdetail.`items_id`,
        orderdetail.`items_num`
        FROM
        orders,
        USER,
        orderdetail
        WHERE orders.`user_id` = user.`id`
        AND orders.`id` = orderdetail.`orders_id`

编写javaBean:

这里查询信息有订单详情和用户信息,所以,Orders类不能知足咱们查询是映射的需求,所以,这里一样采用对Orders类进行扩展:

public class OrdersExt extends Orders{
	private User user;
	private List<Orderdetail> orderdetailLists;
        //省略getter和setter方法
}

编写Mapper接口:

public interface OrdersMapper {
	public List<OrdersExt> findOrdersAndOrderdetail();
}

编写OrderMapper.xml映射文件:

在映射文件中使用了<collection property="指定关联关信息映射到OrdersExt的哪一个属性上" ofType="集合中元素的java类型"> 标签;该标签时一对多关联映射所使用的,把查询的结果集中有多个结果放在集合中去。

<?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.lc.mybatis.mapper.OrdersMapper">
	<!-- 声明resultMap -->
	<resultMap type="ordersExt" id="ordersAndOrderdetail">
		<!-- 订单信息 -->
		<id column="id" property="id"/>
		<result column="user_id" property="userId"/>
		<result column="number" property="number"/>
		<!-- 用户信息(一对一) -->
		<association property="user" javaType="user">
			<id column="user_id" property="id"/>
			<result column="username" property="username"/>
			<result column="sex" property="sex"/>
		</association>
		<!-- 订单详情信息(一对多) -->
		<!-- collection标签:因为一对多映射 -->
		<!-- property属性:指关联信息映射到OrdeersExt的哪一个属性上 -->
		<!-- ofType属性: 集合中java类型-->
		<collection property="orderdetailLists" ofType="com.lc.mybatis.po.Orderdetail">
			<id column="detailId" property="id"/>
			<result column="items_id" property="itemsId"/>
			<result column="items_num" property="itemsNum"/>
		</collection>
	</resultMap>
	
	<!-- 查询订单信息:主信息为订单信息,从信息为用户信息和订单详情 -->
	<select id="findOrdersAndOrderdetail" resultMap="ordersAndOrderdetail">
		SELECT
		orders.`id`,
		orders.`user_id`,
		orders.`number`,
		user.`username`,
		user.`sex`,
		orderdetail.`id` detailId,
		orderdetail.`items_id`,
		orderdetail.`items_num`
		FROM
		orders,
		USER,
		orderdetail
		WHERE orders.`user_id` = user.`id`
		AND orders.`id` = orderdetail.`orders_id`
	</select>

</mapper>

加载OrderMapper.xml映射文件:

<!-- 加载映射文件 -->
	<mappers>
		<!-- 使用相对于类路径的资源 -->
		<!--  <mapper resource="com/lc/mybatis/mapper/UserMapper.xml"/>	-->
		<!-- 注册指定包下的全部映射文件 -->
		<package name="com.lc.mybatis.mapper"/>
	</mappers>

编写测试类:

private SqlSessionFactory sqlSessionFactory ;
	
	@Before
	public void setUp() throws IOException {
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public void testFindOrdersAndOrderdetail() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//获取UserMapper的代理类
		OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
		List<OrdersExt> lists = ordersMapper.findOrdersAndOrderdetail();
		sqlSession.close();
	}

}
1.3.多对多关联查询

其实多对多就是特殊的一对一的关联关系。

需求分析:

查询用户信息及用户购买的商品信息。

sql语句:

主表:user表

从表:orders、orderdetail、items

SELECT
        orders.`id`,
        orders.`user_id`,
        orders.`number`,
        user.`username`,
        user.`sex`,
        orderdetail.`id` detailId,
        orderdetail.`items_id`,
        orderdetail.`items_num`,
        items.`name`,
        items.`price`
        FROM
        orders,
        USER,
        orderdetail,
        items
        WHERE orders.`user_id` = user.`id`
        AND orders.`id` = orderdetail.`orders_id`
        AND orderdetail.`items_id` = items.`id`

修改user表对应的User类:

public class User {
	private Integer id;
	private String username;
	private Date birthday;
	private String sex;
	private String address;
	private List<Orders> ordersLists;

修改orders表对应的Orders类:

public class Orders {
	private Integer id;
	private Integer userId;
	private String number;
	private Date createtime;
	private String note;
	private List<Orderdetail> orderdetailList;

修改orderdetail表对应的Orderdetail类;

public class Orderdetail {
	private Integer id;
	private Integer ordersId;
	private Integer itemsId;
	private Integer itemsNum;
	private Items items;

修改items表对应的iItems类:

public class Items {
	private Integer id;
	private String name;
	private float price;
	private String text;
	private String pic;
	private Date createtime;

编写Mapper接口:

public interface UserMapper {
	public List<User> findUserAndItems();
}

编写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">
<mapper namespace="com.lc.mybatis.mapper.UserMapper">

	<!-- 多对多:查询用户购买商品的详细信息 -->
	<resultMap type="user" id="userAndItems">
		<!-- 用户信息 -->
		<id column="user_id" property="id"/>
		<result column="username" property="username"/>
		<result column="sex" property="sex"/>
		<!-- 订单信息(一对多) -->
		<collection property="ordersLists" ofType="orders">
			<id column="id" property="id"/>
			<result column="user_id" property="userId"/>
			<result column="number" property="number"/>
			<!-- 订单详情信息(一对多) -->
			<collection property="orderdetailList" ofType="orderdetail">
				<id column="detailId" property="id"/>
				<result column="items_id" property="itemsId"/>
				<result column="items_num" property="itemsNum"/>
				<!-- items信息:(一对多) -->
				<association property="items" javaType="items">
					<id column="items_id" property="id"/>
					<result column="name" property="name"/>
					<result column="price" property="price"/>
				</association>
			</collection>
		</collection>
	</resultMap>
	
	<select id="findUserAndItems" resultMap="userAndItems">
		SELECT
		orders.`id`,
		orders.`user_id`,
		orders.`number`,
		user.`username`,
		user.`sex`,
		orderdetail.`id` detailId,
		orderdetail.`items_id`,
		orderdetail.`items_num`,
		items.`name`,
		items.`price`
		FROM
		orders,
		USER,
		orderdetail,
		items
		WHERE orders.`user_id` = user.`id`
		AND orders.`id` = orderdetail.`orders_id`
		AND orderdetail.`items_id` = items.`id`
	</select>

</mapper>

加载UserMapper.xml映射文件:

<!-- 加载映射文件 -->
	<mappers>
		<!-- 注册指定包下的全部映射文件 -->
		<package name="com.lc.mybatis.mapper"/>
	</mappers>

编写测试类:

public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory ;
	@Before
	public void setUp() throws IOException{
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	@Test
	public void testFindOrdersAndOrderdetail() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//获取UserMapper的代理类
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		List<User> lists = userMapper.findUserAndItems();
		sqlSession.close();
	}

}
1.4.对关联查询作出总结

关联查询,也就是多表查询,查询的结果集也不是一个表所对应的JavaBean对象所能进行直接映射的。所以,咱们在进行关联查询要进行合理的JavaBean对象处理和扩展,保证查询出来的结果集都有所对应的JavaBean属性和之对应。这样就能保证查询出来的结果正确无误。

在关联查询中咱们经常使用的标签有:association和collection标签。association标签是一对一关联映射所须要的标签。collection标签是一对多所须要的标签。在Mybatis中,能够理解为多对一也是特殊的一对一(如同:多个员工对应一个部门;可是也能够理解为一个员工对应一个部门,只不过有多个员工而已;能够理解为:在一个Employee对象中有一个department属性;同时又多个Employee对象,每一个对象中的department对应同一个部门);多对可能是特殊的一对多。

在结果集映射中,咱们用的结果集映射总共有两种,分别是:resultType和resultMap;那在关联映射的时候,咱们该如何选择使用哪一种结果映射方式呢?其实只须要理解两种映射的不一样和映射原理。resultType映射时把查询出来的结果集和对应的JavaBean属性进行一一对应。所以,在采用resultType映射,须要映射结果集的javaBean中的全部属性都是与查询结果集进行相互对应的(属性不能进行嵌套)。而使用resultMap结果集映射,则须要先声明resultMap,后使用。先声明resultMap就是制定查询出来的结果集中的列数和javaBean对象中的哪些属性进行关联映射(属性能够嵌套)。

2、Mybatis的延迟加载

在mybatis中只有resultMap标签的association标签和collection标签具备延迟加载的功能。

延迟加载的意思是在进行关联查询时,利用延迟加载,先加载主信息,须要关联信息时,再去按需加载关联信息。这样就会大大的提升数据库的性能,查询单表要比查询多表速度要快的多。

设置延迟加载(打开延迟加载):

Mybatis默认是不开启延迟加载的,须要咱们去配置打开延迟加载。须要在全局配置文件中SqlMapConfig.xml中设置lazyLoadingEnabled、aggressiveLazyLoading


开启延迟加载:

<!-- 设置延迟加载 -->
	<settings>
		<setting name="lazyLoadingEnabled" value="true"/>
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

上面已经在全局配置文件中打开了延迟加载,下面咱们就经过一个案例来测试是否已经可使用延迟加载了:

需求分析:

查询订单信息及关联的用户信息。

编码实现:

编写Javabean:

public class OrdersExt extends Orders{
	private User user;
        //省略getter和setter方法
}

编写Mapper接口:

public interface OrdersMapper {
	public List<OrdersExt> findOrdersAndUserLazyLoading();
}

编写OrdersMapper.xml配置文件:

为了使用懒加载,把刚才的需求分解成,首先查询订单信息,而后再按需根据id查询用户信息。

这样就须要配置两个select标签语句;在进行关联查询的时候,association标签找那个的select 是把按需查询用户信息的statement的id,column的做用就是把查询出来的orders信息集合的外键user_id做为findUserById的入参。

<?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.lc.mybatis.mapper.OrdersMapper">
	
	<!-- 需求:查询订单信息(主信息为订单,从信息为用户),而且对关联表进行懒加载 -->
	<!-- 声明resultMap -->
	<resultMap type="ordersExt" id="lazyloading">
		<!-- 订单信息 -->
		<id column="id" property="id"/>		
		<result column="user_id" property="user_id"/>
		<result column="number" property="number"/>
		<!-- 用户信息(一对一) -->
		<!-- select属性:指定关联查询statement(即查询用户statement的id),而后将查询的结果封装到property指定的属性中去 -->
		<!-- column属性:指定查询出来的列column属性的值,做为statement查询语句的入参 -->
		<association property="user" select="findUserById" column="user_id"></association>
	</resultMap>
	<select id="findOrdersAndUserLazyLoading" resultMap="lazyloading">
		SELECT * FROM ORDERS
	</select>
	<select id="findUserById" parameterType="user" resultType="user">
		SELECT * FROM USER WHERE id=#{id}
	</select>
	
	<!-- 在mybatis中,resultMap标签 的association标签和collection标签具备延迟加载的功能。resultType结果映射就没有延迟加载 -->

</mapper>

编写测试类:

经过断点方式来测试是否使用了懒加载。在测试语句中获得lists处打断点,经过查询lists中的元素中的user属性是否为空,当执行到获取user对象后,再看lists中元素的user属性是否为空。

public class OrdersMapperTest {

private SqlSessionFactory sqlSessionFactory ;
	
	@Before
	public void setUp() throws IOException {
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public void testFindOrdersAndUserLazyLoading() {
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//获取UserMapper的代理类
		OrdersMapper ordersMapper = sqlSession.getMapper(OrdersMapper.class);
		List<OrdersExt> lists = ordersMapper.findOrdersAndUserLazyLoading();
		lists.get(0).getUser();
		sqlSession.close();
	}
	

}

显然经过测试:在第一次获取lists集合,集合中的元素中user属性为空,当获取user后,lists集合中元素的user属性就不为空。

3、Mybatis的逆向工程(会用)

什么是逆向工程:

简单解释:就是经过数据库中的表,自动生成java代码;

下载逆向工程:

逆向工程的下载地址:

https://github.com/mybatis/generator/releases/tag/mybatis-generator-1.3.2


使用逆向工程:

建立项目导入jar包:


建立generator配置文件:

该配置文件放在classpath下:

该配置文件说明看注释;该配置文件能够在下载下来的逆向工程中docs中index.html中找到;

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
	<context id="testTables" targetRuntime="MyBatis3">
		<commentGenerator>
			<!-- 是否去除自动生成的注释 true:是 : false:否 -->
			<property name="suppressAllComments" value="true" />
		</commentGenerator>
		<!--数据库链接的信息:驱动类、链接地址、用户名、密码 -->
		<jdbcConnection driverClass="com.mysql.jdbc.Driver"
			connectionURL="jdbc:mysql://localhost:3306/mybatis" userId="root"
			password="mysql">
		</jdbcConnection>
		<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
			connectionURL="jdbc:oracle:thin:@127.0.0.1:1521:yycg" 
			userId="yycg"
			password="yycg">
		</jdbcConnection> -->

		<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和 
			NUMERIC 类型解析为java.math.BigDecimal -->
		<javaTypeResolver>
			<property name="forceBigDecimals" value="false" />
		</javaTypeResolver>

		<!-- targetProject:生成PO类的位置 -->
		<javaModelGenerator targetPackage="cn.itcast.ssm.po"
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema做为包的后缀 -->
			<property name="enableSubPackages" value="false" />
			<!-- 从数据库返回的值被清理先后的空格 -->
			<property name="trimStrings" value="true" />
		</javaModelGenerator>
        <!-- targetProject:mapper映射文件生成的位置 -->
		<sqlMapGenerator targetPackage="cn.itcast.ssm.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema做为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</sqlMapGenerator>
		<!-- targetPackage:mapper接口生成的位置 -->
		<javaClientGenerator type="XMLMAPPER"
			targetPackage="cn.itcast.ssm.mapper" 
			targetProject=".\src">
			<!-- enableSubPackages:是否让schema做为包的后缀 -->
			<property name="enableSubPackages" value="false" />
		</javaClientGenerator>
		<!-- 指定数据库表 -->
		<table tableName="items"></table>
		<table tableName="orders"></table>
		<table tableName="orderdetail"></table>
		<table tableName="user"></table>

		
	</context>
</generatorConfiguration>

建立生成表对应类的java类:

public class Generator {
	public static void main(String[] args) throws Exception{
		List<String> warnings = new ArrayList<String>();
		boolean overwrite = true;
		File configFile = new File("config/generatorConfig.xml");
		ConfigurationParser cp = new ConfigurationParser(warnings);
		Configuration config = cp.parseConfiguration(configFile);
		DefaultShellCallback callback = new DefaultShellCallback(overwrite);
		MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
		myBatisGenerator.generate(null);
	}
}

执行该类中的方法就生成了咱们所须要的类: