Spring整合Mybatis之DAO层、Service层开发

3. Spring整合Mybatis编程DAO层开发

1. 项目引入相关依赖

	spring   mybatis   mysql   mybatis-spring   druid

2. 编写spring.xml
	
	整合:spring 接管 mybatis 中 SqlSessionFactory对象的创建
	
    <!--创建DataSource-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--创建sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--依赖数据源-->
        <property name="dataSource" ref="dataSource"/>
    </bean>
    
3. 建表

4. 实体类
	
5. DAO接口
	public interface UserDAO {
    List<User> findAll();
	}
	
6. 开发Mapper
	<mapper namespace="com.baizhi.dao.UserDAO">

    <select id="findAdd" resultType="com.baizhi.eneity.User">
        select id, name, age, bir from t_user
    </select>
	</mapper>

	注意:开发完mapper文件后一定要在spring.xml中注册
	<!--创建sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--依赖数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--注册mapper配置文件-->
        <property name="mapperLocations">
            <array>
                <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
            </array>
        </property>
    </bean>
    
7. 启动工厂获取SqlSessionFactory

    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    SqlSessionFactory sqlSessionFactory = (SqlSessionFactory) context.getBean("sqlSessionFactory");
    SqlSession sqlSession = sqlSessionFactory.openSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    userDAO.findAll().forEach(user -> {System.out.println(user);});
    
    再进一步可以直接在工厂中注册SqlSessionFactory、注册DAO组件类,
    并且在DAO组件里面注入SqlSessionFactory和DAO接口的类型,这样就可以使用spring工厂直接获取UserDAO组件类了
    不用再获取SqlSessionFactory了
    
    ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");
    UserDAO userDAO = (UserDAO) context.getBean("userDAO");

接下来我们来整合mybatis和spring并一步一步的开发DAO层:

首先,我们新建一个模块,使用标准的包结构

 

之后我们要在pom.xml文件中引入依赖

spring mybatis mysql mybatis-spring druid

 

<!--spring核心及相关依赖-->
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-core</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-beans</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-web</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-expression</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aop</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-context-support</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-jdbc</artifactId>
  <version>4.3.2.RELEASE</version>
</dependency>

<!--mysql-->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.38</version>
</dependency>

<!--mybatis-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.5.4</version>
</dependency>

<!--mybatis-spring-->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis-spring</artifactId>
  <version>2.0.4</version>
</dependency>

<!--druid-->
<dependency>
  <groupId>com.alibaba</groupId>
  <artifactId>druid</artifactId>
  <version>1.1.19</version>
</dependency>

在数据库中建表

 

创建实体类

public class User {

    private String id;
    private String name;
    private Integer age;
    private Date bir;

    public User() {
    }

    public User(String id, String name, Integer age, Date bir) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.bir = bir;
    }

    // 成员变量的set、get方法以及类的to_String方法在博客中没有,是为了避免占用太多篇幅,但是这里其实是有的
    // 大家写的时候一定要写上
}

创建DAO接口 

public interface UserDAO {
    List<User> findAll();
}

 

 写Mapper配置文件

<?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.baizhi.dao.UserDAO">
    
    <!--查询表中所有记录-->
    <select id="findAll" resultType="com.baizhi.eneity.User">
        select id, name, age, bir from t_user
    </select>
    
    
</mapper>

 

编写spring.xml文件进行整合 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--创建DataSource-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--创建sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
    <!--因为使用了mybatis官方的创建SqlSessionFactory对象的工具类,所以不能使用mybatis的主配置文件了,
     主配置文件最重要的是数据源+mapper,所以我们要在这里写上数据源和mapper配置-->
    <!--依赖数据源-->
    <property name="dataSource" ref="dataSource"/>
    <!--注册mapper配置文件-->
    <property name="mapperLocations">
        <array>
            <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
        </array>
    </property>
    </bean>


</beans>

 

测试和结果 

 

最后我们来说一个优化 

对于我们来说,我们不关心SqlSessionFactory如何获取SqlSession的,也不关心SqlSession如何获取获取DAO接口的,我们关心能否一步就获得想要的DAO接口呢,这是可以的,我们先在工厂中注册SqlSessionFactory对象,因为SqlSessionFactory可以获取SqlSession对象,然后传入DAO接口类型就获得了DAO接口对象;然后我们可以在工厂中创建一个DAO组件类,注入SqlSessionFactory对象和DAO接口类型就可以直接获得DAO对象了,这个类就是mybatis-spring包中的MapperFactoryBean类

配置文件

<!--创建DataSource-->
<bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
    <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
    <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
    <property name="username" value="root"/>
    <property name="password" value="root"/>
</bean>

<!--创建sqlSessionFactory-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
    <!--因为使用了mybatis官方的创建SqlSessionFactory对象的工具类,所以不能使用mybatis的主配置文件了,
     主配置文件最重要的是数据源+mapper,所以我们要在这里写上数据源和mapper配置-->
    <!--依赖数据源-->
    <property name="dataSource" ref="dataSource"/>
    <!--注册mapper配置文件-->
    <property name="mapperLocations">
        <array>
            <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
        </array>
    </property>
</bean>

<!--创建DAO组件类-->
<bean class="org.mybatis.spring.mapper.MapperFactoryBean" name="userDAO">
    <!--注入SqlSessionFactory-->
    <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    <!--注入创建的DAO接口的类型  注入接口的全限定名  包.接口名-->
    <property name="mapperInterface" value="com.baizhi.dao.UserDAO"/>
</bean>

  • 测试和结果
public class TestUserDAO {
    public static void main(String[] args) {
        ApplicationContext context = new ClassPathXmlApplicationContext("spring.xml");

        UserDAO userDAO = (UserDAO) context.getBean("userDAO");

        userDAO.findAll().forEach(user -> System.out.println("user = " + user));
    }
}

 

 

总结:

 

 4. Spring整合Mybatis编程Service层开发

# spring、mybatis整合Service层开发时如何加入事务控制

1. Mybatis框架中事务控制

	SqlSession		提交:sqlSession.commit();		回滚:sqlSession.rollback()
	
	// 无论用的是哪个简化数据库的框架,它的底层一定是jdbc,sqlSession底层调的也是Connection的commit()、rollback()
	Mybatis 是对 原始jdbc技术的封装  ===> Connection(数据库其实只认java.sql.Connection commit() | rollback())
	
	项目中真正负责数据库事务控制的对象:Connection 对象
	
2. 用来实现事务控制的核心对象是

	Connection 连接对象的 commit() rollback()
	
3. 如何在现有的项目中获取Connection对象
	
	注意:在现有项目中DruidDataSource是一个连接池  在连接池里面装的就是一个一个的Connection连接
	Connection conn = DruidDataSource.getConnection();
	
4. 给现有业务层加入事务
	UserServiceImpl
	
	private DataSource dataSource; // 提供公开的set方法
	save(){
		try{
         // 控制事务
         druidDataSource.getConnection().setAutoCommit(false)	// 将事务提交方式改为手动
         // 处理业务
         // 调用DAO
         druidDataSource.getConnection().commit();
        }catch(...){
         druidDataSource.getConnection().rollback();
        }
	}
	
	连接控制事务得保证是同一个连接对象,在业务层拿到的连接对象得和DAO真正执行时打开的数据库连接对象保持一致
	DAO真正执行是由框架内部的jar包创建出来的,不受控制,与业务层拿到的连接不是同一个,所以利用上面的代码控制
	事务是不行的
	
4. 在Spring和Mybatis框架中提供了一个类

	DataSourceTransactionManager	数据源事务管理器
	
	作用
	
		1. 在全局创建一个事务管理器,用来统一调度 业务层当前线程使用的连接对象和DAO层使用的连接对象一致
           由它来决定哪个线程在执行业务层时用的是这个连接,在执行DAO时同样用这个连接
	
	创建
     <!--数据源管理器-->
     <!--它是用来控制数据源的线程安全问题,它不生产数据源,所以要告诉它控制哪个数据源的线程安全问题,所以要注入数据源-->
     <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
         <!--注入数据源对象-->
         <property name="dataSource" ref="dataSource"/>
     </bean>		
	
5. 给现有的业务层加入事务控制

public class UserServiceImpl implements UserService{

    private UserDAO userDAO;
    private PlatformTransactionManager transactionManager; //setTransactionManager方法

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public void save(User user) {
        try{
        // 创建事务配置对象
        // 接口,后面new的用实现类
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        // 获取事务状态
                                                                    //传入事务配置
        TransactionStatus status = platformTransactionManager.getTransaction(transactionDefinition);
        //
        try {
            // 控制事务
            // 处理业务
            userDAO.save(user);
            int i = 1 / 0;
            // 需要传入事务状态
            platformTransactionManager.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            platformTransactionManager.rollback(status);
        }
    }
}	

在具体讲解Spring整合Mybatis编程Service层开发之前,我们先来补充一个小的知识点 

<!--一次性创建项目中所有DAO对象 MapperScannerConfigurer
    MapperScannerConfigurer:
        默认创建对象在工厂中唯一标识:接口的首字母小写的名字
        UserDAO=====> userDAO   Userdao====> userdao
        OrderDAO====> orderDAO  Orderdao====> orderdao
        EmpDAO====> empDAO
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!--注入SqlSessionFactory-->
    <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
    <!--扫描DAO接口所在的包-->
    <property name="basePackage" value="com.baizhi.dao"/>
</bean>

 

  • 使用MapperScannerConfigurer,一次性创建包中所有的接口
<!--创建sqlSessionFactory-->
<bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
    <!--因为使用了mybatis官方的创建SqlSessionFactory对象的工具类,所以不能使用mybatis的主配置文件了,
     主配置文件最重要的是数据源+mapper,所以我们要在这里写上数据源和mapper配置-->
    <!--依赖数据源-->
    <property name="dataSource" ref="dataSource"/>
    <!--注册mapper配置文件-->
    <property name="mapperLocations">
        <array>
            <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
        </array>
    </property>
    <!--注入别名相关配置 typeAliasesPackage:用来给指定包中所有类起别名 默认的别名:类名|类名首字母小写-->
    <property name="typeAliasesPackage" value="com.baizhi.eneity"/>
</bean>

 

  • typeAliasesPackage:用来给指定包中所有类起别名 默认的别名:类名|类名首字母小写

 

之后我们正式进入Spring整合Mybatis编程Service层开发

因为在前面开发DAO层时已经在pom.xml中导入依赖了,所以在开发Service时就不需要再导入依赖了,我们直接开发Service接口

 

public interface UserService {
    List<User> findAll();

    void save(User user);
}

 

 这里我们先不管事务操作,创建UserService接口的实现类,UserService的实现类里面有一个userDAO接口对象

package com.baizhi.service;

import com.baizhi.dao.UserDAO;
import com.baizhi.eneity.User;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import java.util.List;
import java.util.UUID;

public class UserServiceImpl implements UserService{

    private UserDAO userDAO;


    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public List<User> findAll() {
        // 查询操作不需要事务控制
        // 调用userDAO的方法
        return userDAO.findAll();
    }

    @Override
    public void save(User user) {
        // 控制事务
        // 处理业务
        // 调用DAO
        // userDAO 方法上有一个小事务,仅限于DAO的方法,DAO的方法结束后会做一个提交,这个小事务仅是为了方便测试DAO
        // 当外部(Service方法内)存在事务时,小事务(仅限于DAO的方法中的事务)自动消失(小事务不生效)
        // // 调用userDAO的方法
        userDAO.save(user);
        //int i = 1 / 0;
    }
}

 编写spring.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--创建DataSource-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--创建sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--因为使用了mybatis官方的创建SqlSessionFactory对象的工具类,所以不能使用mybatis的主配置文件了,
         主配置文件最重要的是数据源+mapper,所以我们要在这里写上数据源和mapper配置-->
        <!--依赖数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--注册mapper配置文件-->
        <property name="mapperLocations">
            <array>
                <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
            </array>
        </property>
        <!--注入别名相关配置 typeAliasesPackage:用来给指定包中所有类起别名 默认的别名:类名|类名首字母小写-->
        <property name="typeAliasesPackage" value="com.baizhi.eneity"/>
    </bean>

    <!--一次性创建项目中所有DAO对象 MapperScannerConfigurer
        MapperScannerConfigurer:
            默认创建对象在工厂中唯一标识:接口的首字母小写的名字
            UserDAO=====> userDAO   Userdao====> userdao
            OrderDAO====> orderDAO  Orderdao====> orderdao
            EmpDAO====> empDAO
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入SqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描DAO接口所在的包-->
        <property name="basePackage" value="com.baizhi.dao"/>
    </bean>

    <!--管理Service组件-->
    <bean class="com.baizhi.service.UserServiceImpl" name="userService">
        <property name="userDAO" ref="userDAO"/>
    </bean>

</beans>

 

测试和结果 

 测试之前t_user表中记录:

运行代码:

 

运行之后t_user表中记录:

 

上面表记录说明执行成功了。

接下来我们尝试使用事务进行管理

我们先看一下是否有事务自动提交

 

 

为什么有异常却仍然插入了数据呢,这时因为userDAO 方法上有一个小事务,仅限于DAO的方法,DAO的方法结束后会做一个提交,这个小事务仅是为了方便测试DAO, 当外部(Service方法内)存在事务时,小事务(仅限于DAO的方法中的事务)自动消失(小事务不生效)。所以我们就需要手动进行管理了,我们知道,无论什么框架与数据库打交道时,底层都是Connection对象与数据库打交道,所以我们尝试用Connection进行事务管理,但是这确实不行的,因为Connection管理事务的前提是相同的Connection对象,当调用userDAO管理事务的Connection对象和userService管理事务的Connection对象不是同一个,那怎么办呢?官方提供了事务管理器类platformTransactionManager,它是用来控制数据源的线程安全问题,它不生产数据源,我们把它声明为成员变量,并声明公开的set方法,让spring工厂管理,所以UserServiceImpl实现类代码如下:

UserServiceImpl实现类

 

public class UserServiceImpl implements UserService{

    private UserDAO userDAO;
    // 声明事务管理器
    // PlatformTransactionManager是一个接口
    // DataSourceTransactionManager是PlatformTransactionManage的子类
    private PlatformTransactionManager platformTransactionManager;

    public void setPlatformTransactionManager(PlatformTransactionManager platformTransactionManager) {
        this.platformTransactionManager = platformTransactionManager;
    }

    public void setUserDAO(UserDAO userDAO) {
        this.userDAO = userDAO;
    }

    @Override
    public List<User> findAll() {
        // 查询操作不需要事务控制
        return userDAO.findAll();
    }

    @Override
    public void save(User user) {
        // 创建事务配置对象
        // 接口,后面new的用实现类
        TransactionDefinition transactionDefinition = new DefaultTransactionDefinition();
        // 获取事务状态
                                                                    //创建事务配置
        TransactionStatus status = platformTransactionManager.getTransaction(transactionDefinition);
        //
        try {
            // 控制事务
            // 处理业务
            // 调用DAO
            // userDAO 方法上有一个小事务,仅限于DAO的方法,DAO的方法结束后会做一个提交,这个小事务仅是为了方便测试DAO
            // 当外部(Service方法内)存在事务时,小事务(仅限于DAO的方法中的事务)自动消失(小事务不生效)
            userDAO.save(user);
            int i = 1 / 0;
            // 需要传入事务状态
            platformTransactionManager.commit(status);
        } catch (Exception e) {
            e.printStackTrace();
            platformTransactionManager.rollback(status);
        }
    }
}

mapper配置文件 

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">


    <!--创建DataSource-->
    <bean class="com.alibaba.druid.pool.DruidDataSource" id="dataSource">
        <property name="driverClassName" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/lb"/>
        <property name="username" value="root"/>
        <property name="password" value="root"/>
    </bean>

    <!--创建sqlSessionFactory-->
    <bean class="org.mybatis.spring.SqlSessionFactoryBean" id="sqlSessionFactory">
        <!--因为使用了mybatis官方的创建SqlSessionFactory对象的工具类,所以不能使用mybatis的主配置文件了,
         主配置文件最重要的是数据源+mapper,所以我们要在这里写上数据源和mapper配置-->
        <!--依赖数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--注册mapper配置文件-->
        <property name="mapperLocations">
            <array>
                <value>classpath:com/baizhi/mapper/UserDAOMapper.xml</value>
            </array>
        </property>
        <!--注入别名相关配置 typeAliasesPackage:用来给指定包中所有类起别名 默认的别名:类名|类名首字母小写-->
        <property name="typeAliasesPackage" value="com.baizhi.eneity"/>
    </bean>

    <!--一次性创建项目中所有DAO对象 MapperScannerConfigurer
        MapperScannerConfigurer:
            默认创建对象在工厂中唯一标识:接口的首字母小写的名字
            UserDAO=====> userDAO   Userdao====> userdao
            OrderDAO====> orderDAO  Orderdao====> orderdao
            EmpDAO====> empDAO
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!--注入SqlSessionFactory-->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!--扫描DAO接口所在的包-->
        <property name="basePackage" value="com.baizhi.dao"/>
    </bean>

    <!--管理Service组件-->
    <bean class="com.baizhi.service.UserServiceImpl" name="userService">
        <property name="userDAO" ref="userDAO"/>
        <property name="platformTransactionManager" ref="transactionManager"/>
    </bean>

    <!--数据源管理器-->
    <!--它是用来控制数据源的线程安全问题,它不生产数据源,所以要告诉它控制哪个数据源的线程安全问题,所以要注入数据源-->
    <bean class="org.springframework.jdbc.datasource.DataSourceTransactionManager" id="transactionManager">
        <!--注入数据源对象-->
        <property name="dataSource" ref="dataSource"/>

    </bean>

</beans>

 

测试和结果 

测试之前的表 

 

测试: 

 

测试之后的表: 

 

上述结果说明我们成功的使用事务管理了Service层。

总结:

 

 

————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.csdn.net/qq_50313418/article/details/123301769

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ok060

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值