第三十四天:Mybatis框架基础+快速入门配置文件

0. 相关概念

0.1 框架和工具类

  • 工具类
    • 对程序中一小段代码的封装。项目中大多数代码还是需要我们写。
  • 框架
    • 通俗理解框架
    • 可以看做一个半成品的软件/项目。使用框架开发项目,项目中半数以上代码就不需要 我们编写了。
    • 我们一般需要配置(大多数框架都是重配置轻编码的)+少量编码,就可完成项目中的需求。
    • 框架的目的 就是为了简化编码eg:Mybatis
      我们在学习完Mybatis之后,dao层会更简单。你只需要写一个dao接口,然后写一个SQL语句,dao层就已经写完了。
  • 学习步骤
    • 这个框架能干什么?
    • 导包+配置
    • 框架少量的API,少量编码

0.2 ORM

  • Object Relational Mapping 对象关系映射的思想

  • 对象 - Java中的对象 关系-关系型数据库中表的记录 映射 - 一对一关联起来

  • java项目中的每一个实体类,对应数据库中的一个
    java类中的属性,对应数据库表中的字段
    java类中的一个实体对象,对应一个数据表中的一条记录

  • 全自动ORM框架:hibernate

    通过操作实体对象,就可以完成对数据库表中记录的操作。复杂业务性能低下,不可定制,学习成本高。

  • 半自动的ORM框架:Mybatis,ibatis

    基于ORM,但是SQL语句需要我们自己编写。自己优化SQL,可定制性强,效率高。

0.3 Mybatis&原生JDBC

  • 原生jdbc

    • 注册驱动,设置连接参数
    • 获取连接
    • 获取执行对象
    • 设置SQL参数并执行SQL语句
    • 封装结果集并封装成实体对象
    • 释放资源

    相同的内容已经抽取到工具类中(上述删除线标识的步骤)

    模板化(步骤不变,部分步骤相同,上述加粗的内容)的操作,也是可以抽取封装的。

    但是相同的步骤中又有不同的地方,不同的地方如果也要实现解耦,需要通过配置来实现

  • Mybatis解决方案

    • 连接复用:使用数据库连接池初始化并管理连接
    • 解耦:将SQL语句和设置到SQL中的参数抽取到xml配置文件中
    • 自动封装:通过反射内省等技术,实现查询结果集字段实体属性自动映射并赋值
  • Mybatis框架抽取后的样子

    1596759720800

  • Mybatis简介

    • 是一个数据持久层(DAO)框架,封装共性内容让使用者只关注SQL本身。结合了ORM思想,是一个ORM半自动的框架。
    • 使用Mybatis之后,我们只需要定义一个Dao层接口+存储SQL的配置文件(Mybatis映射配置文件),就可以完成Dao层内容。

1. Mybatis快速入门

1.1 Mybatis快速入门步骤

  • 导入Jar包

    • mybatis-3.5.3.jar
    • mysql-connector-java-5.1.37-bin.jar
    • junit-4.12.jar
  • 编写Mybatis核心配置文件:mybatis-config.xml

    • 连接数据库四要素
    • <mapper>标签中映射文件路径不是./ 建议复制,不要手敲
  • 编写POJO类和Dao层接口,初始化数据库表及数据

  • 编写映射文件:StudentDao.xml,在映射文件中编写SQL语句

  • 测试

  • 小经验

    • 直接生成mybatis的两类xml文件

    • Mybatis映射配置文件和接口之间相互跳转

核心配置文件

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <!-- 连接数据库四要素 -->
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///web17_mybatis01"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>


    <!-- 加载映射配置文件 -->
    <mappers>
        <mapper resource="dao/StudentDao.xml"/>
    </mappers>
</configuration>

映射配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!--
    xml文档第一行是文档声明,必须在首行
    接下来是:命名空间。作用如下:
        1. 引入dtd文件
        2. 对文档中标签及其属性进行约束
 -->
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<!-- 把当前这个xml配置文件当做对应接口的实现类
        通过namespace属性指向要被实现的接口,接口代理的方式必须这样写

 -->
<mapper namespace=".dao.StudentDao">
    <!--
        标签名:select  表示查询
            id属性   id唯一标识,要配置被实现的接口中的方法
            resultType属性    方法的结果(集合中泛型)的类型,全限定类名,不能省略
            parameterType属性,方法发参数的类型,全限定类名,可以省略
            标签体中书写SQL语句
		整个标签被称之为:statement

     -->
        <select id="findById" resultType="domain.Student">
            select * from student where  id = 1;
        </select>
</mapper>

接口StudentDao.java

public interface StudentDao {
    Student findById();
}

测试类MybatisTest.ava

public class MybatisTest {

    @Test
    public void test01() throws IOException {
        // 配置文件位置
        String resource = "mybatis-config.xml";
        // 加载配置文件
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 通过构建的方式创建了SqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // 获取session对象
        // SqlSession session = sqlSessionFactory.openSession();

        // JDK7 新特性  try-with-resources
        /**
         * try(创建各种连接对象){
         *  使用连接
         * }
         * 不需要自己关闭连接,这个结构会在执行完代码之后自动帮你关闭
         */
        // 获取session对象
        try (SqlSession session = sqlSessionFactory.openSession()) {
            // 通过连接对象,获取dao层实现类对象
            StudentDao studentDao = session.getMapper(StudentDao.class);

            // 调用dao层实现类对象中的方法
            Student student = studentDao.findById();
            System.out.println("student = " + student);

            // 提示让删除,因为已经关闭过了
            // session.close();
        }
    }
}

2. API

2.1 Resources

读取配置的文件的工具类,底层使用的是classLoad对象.getResourceAsStream

InputStream getResourceAsStream(“配置文件相对于类路径的相对路径”);

2.2 SqlSessionFactoryBuilder

获取SqlSessionFactory工厂对象的功能类。

// 通过构建的方式构建了一个SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

//xxxBuilder.build()

2.3 SqlSessionFactory

org.apache.ibatis.session.SqlSessionFactory:获取 SqlSession 对象的工厂接口。

SqlSession openSession() 获取SqlSession对象,并开启事务,需要手动提交事务

SqlSession openSession(boolean autoCommit) 获取SqlSession对象,true表示自动提交

2.4SqlSession

org.apache.ibatis.session.SqlSession:sql会话对象接口。用于执行SQL管理事务接口代理

voidcommit()提交事务
voidrollback()回滚事务
TgetMapper(Class cls)获取指定接口的代理实现类对象
voidclose()释放资源

3. 映射配置文件

3.1 基本讲解

<?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">
<!-- 上面的xml的命名空间的作用
    1. 引入dtd约束文件,限制文档中标签名称和属性
    2. 提示功能(配合插件使用)
 -->
<!--
    mapper mybatis映射配置文件的根标签
        属性namespace 指向对应的接口全类名
        就相当于  当前这个映射配置文件可以看做是一个实现类,通过namespace指定被实现的接口
-->
<mapper namespace="dao.StudentDao">
    <!-- 映射配置文件,现在可以看做是接口的实现类,要求如下:
        1. 文件名和对应的接口名一致
        2. 放在和接口相同的包下
        3. 该配置文件的namespace的值为,接口的全限定类名
     -->
    <!-- 实现接口中的抽象方法,mapper下每一个字标签都可以被称之为一个statement,可以是insert/update/delete/select
        select标签标示要查询
            id属性要和对应的方法名一致
            resultType 返回值类型,与方法的返回值 类型要一致
            parameterType  参数类型,现在没有,就省略不写
        标签体中编写SQL语句
     -->
    <select id="findById"  resultType="domain.Student">
        select  * from student where  id = 2
    </select>

</mapper>

参数相关

编码完成如下需求:

// 需求1:查询id为1的学生(强制要求)
// 需求2:创建一个Student对象并保存到数据库(参数和成员变量名保持一致)(成功了吗?)
// 需求3:根据学生姓名和年龄查询用户,传两个参数(多个参数怎么办?)
// 需求4:完成需求3,传一个参数。

映射配置文件StudentDao.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="dao.StudentDao">

    <!--// 需求1:查询id为1的学生(强制要求)
        当接口的参数只有一个,且类型为普通类型(基本数据类型 + String)
        在SQL中个,可以使用任意字符接收传递的参数  格式  #{任意字符}
        可以在接口形参上添加注解@Param("标识"),在SQL语句中,只能使用该标识或者param[n]来接收

        限制接收参数的名称之后,乱写造成的异常
        BindingException: Parameter 'xxxx' not found. Available parameters are [idx, param1]
    -->
<!--    <select id="findById" parameterType="integer" resultType="domain.Student">
        select * from student where  id = #{idx}
    </select>-->
    <!--<select id="findById" parameterType="integer" resultType="domain.Student">
        select id, first_name firstName, age from student where id = #{idx}
    </select>-->

    <!--
        // 需求2:创建一个Student对象并保存到数据库(参数和成员变量名保持一致)(成功了吗?)
        // 需求3:根据学生姓名和年龄查询用户,传两个参数(多个参数怎么办?)
    -->

    <!-- // 需求2:创建一个Student对象并保存到数据库

        当接口中参数只有一个,且为JavaBean类型时,
        在SQL语句中,使用属性名直接接收即可。格式 #{属性名}

        增删改 修改操作直接执行不会持久化到数据库中,因为mybatis默认开始起了事务,但是没有自动提交
        解决方式1:
            1. 手动提交。使用SQLSession对象的commit方法提交
            2. 自动提交。获取SQLSession的时候指定自动提交。openSession(true)

        关于日志:
            mybatis的日志实现之一是log4j,我们需要导包 + 创建配置文件(log4j.properties)才能生效。
			核心配置文件中的配置可以不配,他会自己搜索日志的实现。
     -->
    <!--<insert id="save" parameterType="domain.Student">-->
    <insert id="save">
        insert  into student values(#{id},#{firstName},#{age})
    </insert>


    <!--

        // 需求3:根据学生姓名和年龄查询用户,传两个参数(多个参数怎么办?)
        List<Student> findByNameAndAge(String name, Integer age);
        如果接口中参数由多个普通类型,SQL默认可以使用 arg[0+]或者 parm[1+]接收

        如果想强制使用某个变量名接收,可以在接口形参位置添加@Param("标识")

        错误提示信息
            BindingException: Parameter 'xxx' not found. Available parameters are [arg1, arg0, param1, param2]

        paramterType可以省略不写
        resultType 表示的是返回值类型或者返回值集合中元素的类型
    -->
    <select id="findByNameAndAge" resultType="domain.Student">
        select * from  student where  name = #{namex} and age = #{agex}
    </select>


    <!--
        // 需求4:完成需求3,传一个参数。
        List<Student> findByCondition(Student stu);

        有局限性:不能按照某一个条件范围查找,eg:查找年龄介于20~25之间
        因为不可能为一个成员变量赋两个值
    -->
    <select id="findByCondition"
            resultType="domain.Student">
        select  * from  student where name = #{name} and age = #{age}
    </select>


    <!--
        // 需求4:完成需求3,传一个参数map。传递一个student对象
        List<Student> findByConditionMap(Map map);
        这个封装方式,不受上述影响,更灵活。
    -->

    <!--
        resultType不能省略,否则报错
            ExecutorException: A query was run and no Result Maps were found for the Mapped Statement 'dao.StudentDao.findByConditionMap'.
            It's likely that neither a Result Type nor a Result Map was specified.

     -->
    <!--<select id="findByConditionMap">-->
    <select id="findByConditionMap" resultType="domain.Student">
        select * from student where name = #{namex} and age = #{agex}
    </select>

</mapper>

核心配置文件

<!-- 加载映射配置文件  这里使用的是/ -->
<mappers>
    <mapper resource="dao/StudentDao.xml"/>
</mappers>

Dao层接口StudentDao

public interface StudentDao {
    @Select("select * from student where  id = 1")
    Student findById();

    // 需求1:查询id为1的学生(强制要求)
    Student findById2(@Param("id") Integer id);

    // 需求2:创建一个Student对象并保存到数据库
    void save(Student stu);

    // 需求3:根据学生姓名和年龄查询用户,传两个参数(多个参数怎么办?)
    List<Student> findByNameAndAge(@Param("name") String name, @Param("agex") Integer age);

    // 需求4:完成需求3,传一个参数。
    // 4.1 把两个参数封装成一个实体对象
    // 如果把多个参数封装到一个实体对象中,参数类型有局限性,不能是两个一样的条件做范围查询
    List<Student> findByStudent(Student stu);

    // 4.2 把两个参数封装到Map集合中
    List<Student> findByMap(Map<String,Object> map);
}

测试类

/**
 * @Author Vsunks.v
 * @Date 2020/8/7 11:19
 * @Description:
 */
public class MybatisDemo {
    public static void main(String[] args) throws Exception {

        // 指定核心配置文件
        String resource = "mybatis-config.xml";
        // 把核心配置文件加载成流  Resources为我们提供的方便读取配置文件的工具类
        InputStream inputStream = Resources.getResourceAsStream(resource);

        // 通过构建的方式构建了一个SqlSessionFactory
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

        // SqlSession 就相当于我们之前的 Connection
        // JDK7新特性  try-with-resource
        // 需要释放资源的动作,自动释放在try()中开启的一些流、会话......
        try (SqlSession session = sqlSessionFactory.openSession(true)) {

            // getMapper  getDao   获取一个指定接口的实现类对象
            // 底层是动态代理
            // 动态代理可以增强有接口的类、接口(增强接口,就是现实接口)
            // 就相当于我们自己new StudentDaoImpl();
            // 这个StudentDaoImpl是Mybatis通过动态代理帮我们自动生成并且赋值给了studentDao
            StudentDao studentDao = session.getMapper(StudentDao.class);

            /*List<Student> students = studentDao.findAll();
            System.out.println("students = " + students);*/


            // 测试根据id查询
            /*Student student = studentDao.findById(1);
            System.out.println("student = " + student);*/

            // 测试添加学生
            //studentDao.saveStudent(new Student(null,"凤姐",20));

            // 根据名称和年龄查询用户,参数是两个基本类型
            //List<Student> students = studentDao.findByNameAndAge("美女", 20);
            //System.out.println("students = " + students);

            // 根据名称和年龄查询用户,参数是一个student对象
            //List<Student> students = studentDao.findByUser(new Student(null, "凤姐", 20));
            //System.out.println("students = " + students);

            // 根据名称和年龄查询用户,参数是一个map集合

            HashMap<String, Object> map = new HashMap<>();
            map.put("name", "王二蛋");
            map.put("age", 20);

            System.out.println("studentDao.findByMap(map) = " + studentDao.findByMap(map));


            // 手动提交
            //session.commit();

            // session.close();
        }

    }
}

4. 核心配置文件

4.0 注意

核心配置文件中各种配置的顺序,需要符合官方要求,否则(运行时)会报错。错误提示如下:

<!--
    如果没有按照指定顺序配置,会报错
        SAXParseException; lineNumber: 66; columnNumber: 17; 元素类型为 "configuration" 的内容必须匹配 "(properties?,settings?,typeAliases?
    按照错误提示,修改配置顺序即可。
-->

4.1 properties(重要)

引入外部的properties文件,一般用作引入数据库链接参数的配置。

核心配置文件

<?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">
<!-- 这是一个mybatis的核心配置文件,文件名字任意-->
<configuration>
    <!--引入核心配置文件 -->
    <properties resource="jdbc.properties"/>

    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 加载映射配置文件 -->
    <mappers>
        <mapper resource="dao/StudentDao.xml"/>
    </mappers>
</configuration>

jdbc.properties

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://192.168.115.130:3306/db1
# 数据库用户名可以是username之外任意名称
jdbc.username=root
jdbc.password=root

4.2 Settings(重要)

<!-- mybatis的settings配置 -->
<settings>
    <!--
        1. 驼峰命名和底杠命名自动转换
        mybatis可以完成查询结果集到实体对象自动封装的原理:
            结果集字段名和实体属性名一致,就可自动封装
        当两者不一致时,
            1. 手动为结果集字段起别名,让其和实体属性名一致
            2. 开启驼峰命名和底杠命名自动转换
     -->
    <setting name="mapUnderscoreToCamelCase" value="true"/>
    <!--
        2. 日志配置:
        指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
        该值可以不用设置,mybatis会自动查找日志实现,查找顺序为:SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING。
        但是对于可配置可不配置的属性,我们建议显示配置

        LOG4J  
            要求:1. 导入log4j的jar包  2. 有一个log4j.properties文件
     -->
    <setting name="logImpl" value="LOG4J"/>
</settings>

4.3 TypeAliases(了解)

<!-- 起别名 -->
<typeAliases>
    <!--
        type 全限定类名
        alias 别名
        别名不区分大小写
     -->
    <!--<typeAlias type="domain.Student" alias="student"/>-->

    <!-- 为包下所有的实体类起别名,不区分大小写 -->
    <package name="domain"/>

</typeAliases>

起别名后,在映射配置文件中类型处可以直接使用别名(不区分大小写)

<select id="findByMap" resultType="Student">
       select * from student where first_username=#{name}
       and
       age=#{age}
</select>

系统为常见的类型起好了别名,详见官方文档

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

整体使用频率不高,因为插件会自动生成,而且写全的更好理解。

4.4 Environments(了解)

会配置连接四要素即可

<environments default="dev">
    <environment id="dev">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <!-- 连接数据库四要素 -->
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>
    <environment id="test">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <!-- 连接数据库四要素 -->
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>
</environments>

4.5 Mappers(重点)

<!-- 配置映射配置文件(接口实现类)的位置 -->
<mappers>
    <!-- 加载指定包下面的接口或者映射配置文件(优先推荐) -->
    <package name="dao"/>

    <!--
        从类路径下加载指定的映射配置文件(次推荐)
        路径中,需要使用 / 分层,而非使用 .
        如果有多个映射配置文件需要加载,就需要配置多个mapper分别加载进来
     -->
    <!--<mapper resource="dao/StudentDao.xml"/>-->
    <!--<mapper resource="dao/TeacherDao.xml"/>-->

    <!-- 使用完全限定资源定位符(URL)不用 -->
    <!--<mapper url="file://ip:端口/var/mappers/AuthorMapper.xml"/>-->

    <!-- 加载接口,识别接口上的注解 不推荐 -->
    <!--<mapper class="dao.StudentDao"/>-->
</mappers>

5. 经验分享

5.1 生成Mybatis配置文件

本质是新建了一个文件模板,按照下面的方式新建两个模板即可(Mybatis-configMybatis-Mapper

1596773132571

5.2 接口映射配置文件跳转

使用一个插件free-idea-mybatis

这个插件是个zip包,不要解压,直接安装即可。

已知bug:

​ 多个模块之间有相同内容会提示/跳转错误,卸载其他模块即可。

5.3 ${}和#{}区别(面试题)

#{} MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样)。 这样做更安全,更迅速,通常也是首选做法。

${} 会做字符串的拼接,把${参数名}中参数名对应的值拼接进SQL语句,可能会有SQL注入的风险,效率更低。但是,如果你需要在SQL语句中直接插入一个不转义的字符串,可以使用这种方式。一般情况下会把表名或者字段名通过这方方式传递到SQL语句中,比方说 ORDER BY后面的列名。

5.4 MybatisUtils工具类抽取

/**
 * mybatis工具类,可以实现的功能
 * 1. 自动维护SQLSessionFactory
 * 2. 获取SQLSession
 * 3. 获取dao接口代理对象
 *
 * @Author Vsunks.v
 * @Date 2020/12/4 16:30
 * @Blog blog.sunxiaowei.net
 * @Description:
 */
public class MybatisUtils {

    // 私有构造
    private MybatisUtils() {
    }

    // 维护一个SQLSessionFactory对象
    private static SqlSessionFactory ssf;

    // 静态代码块初始化SQLSessionFactory
    static {
        // 加载配置文件
        String resource = "mybatis-config.xml";

        try {
            // 获取流
            InputStream is = Resources.getResourceAsStream(resource);
            // 通过builder build一个SqlSessionFactory
            ssf = new SqlSessionFactoryBuilder().build(is);

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //2. 获取SQLSession
    public static SqlSession getSqlSession() {
        return ssf.openSession(true);
    }


    // 3. 获取dao接口代理对象
    public static <T> T getMapper(Class<T> tClass){
        return getSqlSession().getMapper(tClass);
    }
}

tisUtils {

// 私有构造
private MybatisUtils() {
}

// 维护一个SQLSessionFactory对象
private static SqlSessionFactory ssf;

// 静态代码块初始化SQLSessionFactory
static {
    // 加载配置文件
    String resource = "mybatis-config.xml";

    try {
        // 获取流
        InputStream is = Resources.getResourceAsStream(resource);
        // 通过builder build一个SqlSessionFactory
        ssf = new SqlSessionFactoryBuilder().build(is);

    } catch (IOException e) {
        e.printStackTrace();
    }
}

//2. 获取SQLSession
public static SqlSession getSqlSession() {
    return ssf.openSession(true);
}


// 3. 获取dao接口代理对象
public static <T> T getMapper(Class<T> tClass){
    return getSqlSession().getMapper(tClass);
}

}


  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值