mybatis的关联关系

mybatis的关联关系

mybatis的关联关系有三种
----->1.一对一
----->2.一对多
----->3.多对多

表现在pojo中是单个引用还是多个引用,从示例上看,朝代可以有多个皇上,朝代就是多的一方。皇帝只能有一个朝代,皇帝就是一的一方。

多的一方看

pojo king

import java.util.Date;

/**
 * 皇上的pojo
 * 
 * @author TeaBig
 */
public class ADemoKing
{
	private int id;
	private int dynastyId;
	private String name;
	private String content;
	private String miaoHao;
	private String nianHao;
	private byte age;
	private byte status;
	private Date createTime;
	private Date updateTime;
	private Date pubTime;
	
	/* 关联关系:自定义引用 */
	/* 只能有一个朝代,所以是单个引用 */
	private ADemoDynasty dynasty ; 

Set/get方法
	@Override
	public String toString()
	{
		return "ADemoKing [id=" + id + ", dynastyId=" + dynastyId + ", name=" + name + ", content=" + content
				+ ", miaoHao=" + miaoHao + ", nianHao=" + nianHao + ", age=" + age + ", status=" + status
				+ ", createTime=" + createTime + ", updateTime=" + updateTime + ", pubTime=" + pubTime + "]";
	}

mapper.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:相当于java里面的类
	namespace:相当于java里面的包名
 -->
<mapper namespace="king">
	<!-- ===========延迟加载===============
		延迟:懒惰,积极;
			积极一点:
			懒惰一点:
		延迟加载:
			查询a对象,期望使用到关联对象b的时候再查询b,而不是马上就查询b
	 -->
	
	<!-- 
		查询所有的朝代记录
		select标签可以发送select语句
		
		id:唯一标识,当前的mapper文件中,id不能重复
		resultType:结果类型;
			如果查询的是单条,那返回值的类型就是resultType; 
			如果查询的是多条,那么返回值的类型是List,List里面放的是resultType
	 -->
	<select id="selectList" resultType="com.jinghangzz.mybatis.data.pojo.ADemoKing">
		select * from a_demo_king  
	</select>
	
	<!-- resultMap -->
	<!-- 要发送两条sql语句,
		先查询皇上,
		拿着dynastyId(朝代Id要去朝代表查询朝代)
	 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoKing" id="resultMap">
		<!-- 如果配置了关联关系,那关联字段必须手动赋值 -->
		<result column="dynastyId" property="dynastyId"/>
		
		<!-- 联合:
			property:pojo的属性名
			column:数据库的列名;为dynasty赋值的时候,需要用到皇上表的哪列?
			javaType:dynasty到底是哪个类型(java里面的); 包名+类名
			select:拿着column执行哪个sql语句,应该可以查询到dynasty;执行sql语句的id;
				sql语句的id,应该是namespace+sql语句的id(如果sql语句的就在当前文件中,那namespace可以忽略)
		 	fetchType:抓取策略;lazy:延迟加载;eager:默认就是积极加载;
		 		如果全局开头木有打开,只能此标签才会起作用,其它的标签不起作用;
		 		建议:(延迟加载开关都打开)
		 			延迟加载只能在一个JVM里面生效;微服务编程:(dubbo,SPringCloud,延迟加载不起作用)
		 -->
		<association property="dynasty" column="dynastyId" javaType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty"
			select="dynasty.selectRelaOne" />
	</resultMap>
	
	<!-- 查询一条记录 
		resultType:指定的皇上,里面有一个朝代的引用,sql语句查询的结果木有存储,
			那应该拿着dynastyId再去朝代表里面查询一次(sql语句要写到一个地,并且要用resultmap来赋值)
	-->
	<select id="selectOne" resultMap="resultMap">
		select * from a_demo_king where id = #{id}
	</select>
	
	<!-- 拿着皇上表的dynastyId(朝代Id)查询朝代表的记录
		paramterType:它是被忽略的,自动的判断是哪个类型;根据值来判断;
		值就是association标签中的column(数据库的列)
		column是int,基本数据类型,#{可以随便写}
		
		这明明是皇上的Mapper文件,为啥要写朝代呢?
	 -->
	<!-- <select id="selectRelaOne" resultType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
		select * from a_demo_dynasty where id = #{asdfasfasf}
	</select> -->
	
	<!-- 使用联合查询,一次性把结果查询出来
		加上autoMapping=true
		我们使用的是自动映射;
		如果sql语句执行完以后,列名要是相同,会出现值一样的问题
		(如何解决重复,要把所有重复的字段起一个别名)
	 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoKing" id="resultMapJoin" autoMapping="true">
		<!-- 如果配置了关联关系,那关联字段必须手动赋值 -->
		<result column="dynastyId" property="dynastyId"/>
		<!-- 为朝代赋值 -->
		<association property="dynasty" column="dynastyId" autoMapping="true"
			javaType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
			<!-- 为重复的字段赋值
				column:sql语句执行的结果,要的是别名(因为重复)
			 -->
			<result column="dynaName" property="name"/>
		</association>
	</resultMap>
	
	<!-- 关联查询 -->
	<select id="selectJoin" resultMap="resultMapJoin">
		select ak.*,ad.*,ad.name as dynaName from a_demo_king ak, a_demo_dynasty ad where ak.dynastyId = ad.id and 
		ak.id = #{asdfasfa}
	</select>
	
	<!-- 查询多个引用(关联关系) -->
	<select id="selectRelaList" resultType="com.jinghangzz.mybatis.data.pojo.ADemoKing">
		select * from a_demo_king where dynastyId = #{dynastyId}
	</select>
</mapper>

测试代码

import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import com.jinghangzz.mybatis.data.pojo.ADemoDynasty;
import com.jinghangzz.mybatis.data.pojo.ADemoKing;
import com.jinghangzz.mybatis.data.test.BaseTest;

/**
 * 查询皇上操作
 * @author TeaBig
 */
public class ADemoKingTest extends BaseTest
{
	/**
	 * 查询一条记录
	 */
	@Test
	public void selectOne()
	{
		/* 获取链接 */
		SqlSession session = this.sqlSessionFactory.openSession(true);
		
		/**
		 * 查询一条记录
		 */
		ADemoKing demoKing = session.selectOne("king.selectOne",2);
		this.logger.info("皇上:id:{},朝代Id:{},name:{},miaoHao:{},createTime:{}",
					demoKing.getId(),demoKing.getDynastyId(),demoKing.getName(),demoKing.getMiaoHao(),demoKing.getCreateTime().toLocaleString());
		/* 需求:一个皇上有一个朝代
		 * 期望可以通过皇上把朝代查询出来;
		 * ~pojo
		 * ~
		 *  */
//		ADemoDynasty dynasty = demoKing.getDynasty() ; 
//		this.logger.info("朝代:id:{},name:{},首都:{},createTime:{}",
//				dynasty.getId(),dynasty.getName(),dynasty.getCapital(),dynasty.getCreateTime().toLocaleString());
		/* 关闭链接 */
		if(session != null)
		{
			session.close(); 
			session = null ; 
		}
	}
	
	/**
	 * 查询一条记录
	 */
	@Test
	public void selectJoin()
	{
		/* 获取链接 */
		SqlSession session = this.sqlSessionFactory.openSession(true);
		
		/**
		 * 查询一条记录
		 */
		ADemoKing demoKing = session.selectOne("king.selectJoin",2);
		this.logger.info("皇上:id:{},朝代Id:{},name:{},miaoHao:{},createTime:{}",
					demoKing.getId(),demoKing.getDynastyId(),demoKing.getName(),demoKing.getMiaoHao(),demoKing.getCreateTime().toLocaleString());
		/* 需求:一个皇上有一个朝代
		 * 期望可以通过皇上把朝代查询出来;
		 * ~pojo
		 * ~
		 *  */
		ADemoDynasty dynasty = demoKing.getDynasty() ; 
		this.logger.info("朝代:id:{},name:{},首都:{},createTime:{}",
				dynasty.getId(),dynasty.getName(),dynasty.getCapital(),dynasty.getCreateTime().toLocaleString());
		/* 关闭链接 */
		if(session != null)
		{
			session.close(); 
			session = null ; 
		}
	}
}
一的一方看

pojo dynasty


import java.util.Date;
import java.util.List;

/**
 * 朝代的POJO
 * 	pojo的类名和表名一样(把_去掉,注意驼峰标识)
 * 	pojo的属性名和表的类名一样
 * 	pojo的对象和表的记录一样;
 * @author TeaBig
 */
public class ADemoDynasty
{
	private int id;
	private String name;
	private String content;
	private int stYear;
	private int edYear;
	private int guoZuo;
	private String capital;
	private byte status;
	private Date createTime;
	private Date updateTime;
	private Date pubTime;
	
	/* 持有多个引用 */
	private List<ADemoKing> kingList;

读写器

	@Override
	public String toString()
	{
		return "ADemoDynasty [id=" + id + ", name=" + name + ", content=" + content + ", stYear=" + stYear + ", edYear="
				+ edYear + ", guoZuo=" + guoZuo + ", capital=" + capital + ", status=" + status + ", createTime="
				+ createTime + ", updateTime=" + updateTime + ", pubTime=" + pubTime + "]";
	}
}

mapper.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:相当于java里面的类
	namespace:相当于java里面的包名
 -->
<mapper namespace="dynasty">
	<!-- 
		查询所有的朝代记录
		select标签可以发送select语句
		
		id:唯一标识,当前的mapper文件中,id不能重复
		resultType:结果类型;
			如果查询的是单条,那返回值的类型就是resultType; 
			如果查询的是多条,那么返回值的类型是List,List里面放的是resultType
	 -->
	<select id="selectList" resultType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
		select * from a_demo_dynasty  
	</select>
	
	<!-- resultMap -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoDynasty" id="resultMap">
		<!-- 关联字段,需要重新赋值,此次的关联字段是id(主键) -->
		<id column="id" property="id"/>
		
		<!-- 为皇上集合赋值 
			在朝代表里面,根据哪个字段可以查询皇上集合
			select:根据关联字段,查询皇上的sql语句
				如果是当前mapper文件,namespace可以忽略,否则不能忽略
			在collection中要使用ofType(指的是包名+类名)
			association:要使用javaType(指的是包名+类名)
		-->
		<collection property="kingList" column="id" ofType="com.jinghangzz.mybatis.data.pojo.ADemoKing"
			select="king.selectRelaList"/>
	</resultMap>
	
	<select id="selectOne" parameterType="map" resultMap="resultMap">
		select * from a_demo_dynasty where id = #{id}
	</select>
	
	<!-- 为联合查询赋值 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoDynasty" id="resultMapJoin" autoMapping="true">
		<!-- 关联字段需要额外赋值 -->
		<id column="id" property="id"/>
		<result column="dynaName" property="name"/>
		<!-- 如果sql语句查询的列别名有重复的,需要起别名 -->
		
		<!-- 为皇上集合赋值 
			在朝代表里面,根据哪个字段可以查询皇上集合
			select:根据关联字段,查询皇上的sql语句
				如果是当前mapper文件,namespace可以忽略,否则不能忽略
			在collection中要使用ofType(指的是包名+类名)
			association:要使用javaType(指的是包名+类名)
		-->
		<collection property="kingList" column="id" ofType="com.jinghangzz.mybatis.data.pojo.ADemoKing" autoMapping="true">
			<id column="akId" property="id"/>
			<!-- 重复的列,要起别名 -->
			<result property="name" column="akName"/>
		</collection>
	</resultMap>
	
	<!-- 使用联合查询来实现 -->
	<select id="selectJoin" resultMap="resultMapJoin">
		select ad.*,ak.*,ad.name as dynaName,ak.name as akName,ak.id as akId from a_demo_king ak, a_demo_dynasty ad where ak.dynastyId = ad.id and 
		ad.id = #{id} ; 
	</select>
	
	<!-- 拿着皇上表的dynastyId(朝代Id)查询朝代表的记录
		paramterType:它是被忽略的,自动的判断是哪个类型;根据值来判断;
		值就是association标签中的column(数据库的列)
		column是int,基本数据类型,#{可以随便写}
		
		这明明是皇上的Mapper文件,为啥要写朝代呢?
	 -->
	<select id="selectRelaOne" resultType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
		select * from a_demo_dynasty where id = #{asdfasfasf}
	</select>
</mapper>

测试代码

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import com.jinghangzz.mybatis.data.pojo.ADemoDynasty;
import com.jinghangzz.mybatis.data.pojo.ADemoKing;
import com.jinghangzz.mybatis.data.test.BaseTest;

/**
 * 测试朝代的一方
 * @author TeaBig
 *
 */
public class ADemoDynastyTest extends BaseTest
{
	/**
	 * 查询一条记录
	 */
	@Test
	public void selectOne()
	{
		/* 获取链接 */
		SqlSession session = this.sqlSessionFactory.openSession(true);
		
		/**
		 * 查询一条记录
		 */
		ADemoDynasty dynasty = session.selectOne("dynasty.selectOne",10);
		this.logger.info("朝代:id:{},name:{},首都:{},createTime:{}",
				dynasty.getId(),dynasty.getName(),dynasty.getCapital(),dynasty.getCreateTime().toLocaleString());
		
		/* 需求:一个朝代有多个皇上
		 * 期望可以通过皇上把朝代查询出来;
		 * ~pojo
		 * ~
		 *  */
		List<ADemoKing> kingList = dynasty.getKingList() ; 
		kingList.forEach( demoKing -> 
		{
			this.logger.info("皇上:id:{},朝代Id:{},name:{},miaoHao:{},createTime:{}",
					demoKing.getId(),demoKing.getDynastyId(),demoKing.getName(),demoKing.getMiaoHao(),demoKing.getCreateTime().toLocaleString());
		});
		
		/* 关闭链接 */
		if(session != null)
		{
			session.close(); 
			session = null ; 
		}
	}
	
	/**
	 * 查询一条记录
	 */
	@Test
	public void selectJoin()
	{
		/* 获取链接 */
		SqlSession session = this.sqlSessionFactory.openSession(true);
		
		List<ADemoDynasty> dynastyList = session.selectList("dynasty.selectJoin",10);
		dynastyList.forEach( dynasty -> {
			this.logger.info("朝代:id:{},name:{},首都:{},createTime:{}",
					dynasty.getId(),dynasty.getName(),dynasty.getCapital(),dynasty.getCreateTime().toLocaleString());
			
			/* 需求:一个朝代有多个皇上
			 * 期望可以通过皇上把朝代查询出来;
			 * ~pojo
			 * ~
			 *  */
			List<ADemoKing> kingList = dynasty.getKingList() ; 
			kingList.forEach( demoKing -> 
			{
				this.logger.info("皇上:id:{},朝代Id:{},name:{},miaoHao:{},createTime:{}",
						demoKing.getId(),demoKing.getDynastyId(),demoKing.getName(),demoKing.getMiaoHao(),demoKing.getCreateTime().toLocaleString());
			});
		});
		
		
		/* 关闭链接 */
		if(session != null)
		{
			session.close(); 
			session = null ; 
		}
	}
}

mybatis.cfg.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>
	<!-- 全局的开关,设置的意思 -->
	<settings>
		<!-- 打开延迟加载 -->
		<setting name="lazyLoadingEnabled" value="true"/>
		<!-- 都关闭,按需要加载;不管是哪处版本,都是false,3,4,1以前,默认值为true,之后是false -->
		<setting name="aggressiveLazyLoading" value="false"/>
	</settings>

	<!-- 配置了一堆环境;jdbc的环境
		default:默认的环境,配置environment的id
	 -->
	<environments default="my">
		<!-- 配置一个单数 -->
		<environment id="my">
			<!-- 事务管理器:专门用来管理事务的 -->
			<transactionManager type="JDBC"/>
			<!-- 数据源
				pooled:连接池;放的是一个一个的Connection;
				数据源包含了java连接数据库的各种信息
			 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?serverTimezone=UTC"/>
				<property name="username" value="root"/>
				<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
	
	<!-- 一定一定一定要把映射文件包含起来 -->
	<mappers>
		<!-- 映射文件的路径,classpath -->
		<mapper resource="com/jinghangzz/mybatis/data/pojo/ADemoDynastyMapper.xml"/>
		<mapper resource="com/jinghangzz/mybatis/data/pojo/ADemoKingMapper.xml"/>
	</mappers>
</configuration>
总结:查询多张表(此例2张表)要考虑是使用联合查询(一条sql语句),还是通过关联字段(多条sql语句)进行查询,两种方法都需要一个resultMap


一的一方

通过关联字段进行查询
	<!-- resultMap -->
	<!-- 通过关联字段进行查询 -->
	<!-- 要发送两条sql语句,
		先查询皇上,
		拿着dynastyId(朝代Id要去朝代表查询朝代)
	 -->

	<!-- 查询一条记录 
		resultType:指定的皇上,里面有一个朝代的引用,sql语句查询的结果木有存储,
			那应该拿着dynastyId再去朝代表里面查询一次(sql语句要写到一个地,并且要用resultmap来赋值)
	-->
	<!-- 1、通过id查找皇上 -->
	<select id="selectOne" resultMap="resultMap">
		select * from a_demo_king where id = #{id}
	</select>
	<!-- 2、关联字段赋值 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoKing" id="resultMap">
		<!-- 如果配置了关联关系,那关联字段必须手动赋值 -->
		<result column="dynastyId" property="dynastyId"/>
		
		<!-- 联合:
			property:pojo的属性名
			column:数据库的列名;为dynasty赋值的时候,需要用到皇上表的哪列?
			javaType:dynasty到底是哪个类型(java里面的); 包名+类名
			select:拿着column执行哪个sql语句,应该可以查询到dynasty;执行sql语句的id;
				sql语句的id,应该是namespace+sql语句的id(如果sql语句的就在当前文件中,那namespace可以忽略)
		 	fetchType:抓取策略;lazy:延迟加载;eager:默认就是积极加载;
		 		如果全局开头木有打开,只能此标签才会起作用,其它的标签不起作用;
		 		建议:(延迟加载开关都打开)
		 			延迟加载只能在一个JVM里面生效;微服务编程:(dubbo,SPringCloud,延迟加载不起作用)
		 -->
		<association property="dynasty" column="dynastyId" javaType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty"
			select="dynasty.selectRelaOne" />
	</resultMap>

	<!-- 3、通过关联字段查找朝代 -->
	<select id="selectRelaOne" resultType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
		select * from a_demo_dynasty where id = #{asdfasfasf}
	</select>
通过联合查询进行查询
	<!-- 2、使用联合查询,一次性把结果查询出来
		加上autoMapping=true
		我们使用的是自动映射;
		如果sql语句执行完以后,列名要是相同,会出现值一样的问题
		(如何解决重复,要把所有重复的字段起一个别名,或者在数据库中创建表单时就硬性要求,表单的字段不能重复)
	 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoKing" id="resultMapJoin" autoMapping="true">
		<!-- 如果配置了关联关系,那关联字段必须手动赋值 -->
		<result column="dynastyId" property="dynastyId"/>
		<!-- 为朝代赋值 -->
		<association property="dynasty" column="dynastyId" autoMapping="true"
			javaType="com.jinghangzz.mybatis.data.pojo.ADemoDynasty">
			<!-- 为重复的字段赋值
				column:sql语句执行的结果,要的是别名(因为重复)
			 -->
			<result column="dynaName" property="name"/>
		</association>
	</resultMap>
	
	<!-- 1、关联查询 -->
	<select id="selectJoin" resultMap="resultMapJoin">
		select ak.*,ad.*,ad.name as dynaName from a_demo_king ak, a_demo_dynasty ad where ak.dynastyId = ad.id and 
		ak.id = #{asdfasfa}
	</select>


多的一方

通过关联字段进行查询
	<!-- 1、查询朝代 -->
	<select id="selectOne" parameterType="map" resultMap="resultMap">
		select * from a_demo_dynasty where id = #{id}
	</select>
	
	<!-- 2、关联字段赋值 时集合的话使用collection -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoDynasty" id="resultMap">
		<!-- 关联字段,需要重新赋值,此次的关联字段是id(主键) -->
		<id column="id" property="id"/>
		
		<!-- 为皇上集合赋值 
			在朝代表里面,根据哪个字段可以查询皇上集合
			select:根据关联字段,查询皇上的sql语句
				如果是当前mapper文件,namespace可以忽略,否则不能忽略
			在collection中要使用ofType(指的是包名+类名)
			association:要使用javaType(指的是包名+类名)
		-->
		<collection property="kingList" column="id" ofType="com.jinghangzz.mybatis.data.pojo.ADemoKing"
			select="king.selectRelaList"/>
	</resultMap>
	<!-- 3、通过关联字段进行查询 -->
	<!-- 查询多个引用(关联关系) -->
	<select id="selectRelaList" resultType="com.jinghangzz.mybatis.data.pojo.ADemoKing">
		select * from a_demo_king where dynastyId = #{dynastyId}
	</select>
通过联合查询进行查询
	
	<!-- 1、使用联合查询来实现 -->
	<select id="selectJoin" resultMap="resultMapJoin">
		select ad.*,ak.*,ad.name as dynaName,ak.name as akName,ak.id as akId from a_demo_king ak, a_demo_dynasty ad where ak.dynastyId = ad.id and 
		ad.id = #{id} ; 
	</select>
	
	<!-- 2、为联合查询赋值 -->
	<resultMap type="com.jinghangzz.mybatis.data.pojo.ADemoDynasty" id="resultMapJoin" autoMapping="true">
		<!-- 关联字段需要额外赋值 -->
		<id column="id" property="id"/>
		<result column="dynaName" property="name"/>
		<!-- 如果sql语句查询的列别名有重复的,需要起别名 -->
		
		<!-- 为皇上集合赋值 
			在朝代表里面,根据哪个字段可以查询皇上集合
			select:根据关联字段,查询皇上的sql语句
				如果是当前mapper文件,namespace可以忽略,否则不能忽略
			在collection中要使用ofType(指的是包名+类名)
			association:要使用javaType(指的是包名+类名)
		-->
		<collection property="kingList" column="id" ofType="com.jinghangzz.mybatis.data.pojo.ADemoKing" autoMapping="true">
			<id column="akId" property="id"/>
			<!-- 重复的列,要起别名 -->
			<result property="name" column="akName"/>
		</collection>
	</resultMap>
实际操作中,联合查询必须将重复的字段起别名,很不方便,使用关联字段进行查询,搭配延迟加载和策略抓取,可以有效的节约系统资源和空间。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值