【MyBatis笔记】 4 - 设置配置文件模板、MyBatis获取参数值的两种方式、@Param源码分析

视频链接:https://www.bilibili.com/video/BV1VP4y1c7j7?p=22&spm_id_from=pageDriver

1、设置mybatis-config.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>

    <properties resource="jdbc.properties"></properties>

    <typeAliases>
        <package name=""></package>
    </typeAliases>

    <!--设置连接数据库的环境-->
    <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>
        <package name=""/>
    </mappers>
</configuration>

添加模版步骤

在这里插入图片描述

创建模版

完成后就可以直接new一个mybatis-config模版啦。
在这里插入图片描述

2、设置xxxMapper.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="">

</mapper>

过程与config模版相同。
在这里插入图片描述

3、获取参数值

3.1 JDBC原生的获取参数值的方式

  • 字符串拼接
  • 占位符拼接
    @Test
    public void testJDBC() throws SQLException, ClassNotFoundException {
        String username = "cherry";
        Class.forName("");
        Connection connection = DriverManager.getConnection("", "", "");
        // 1. 字符串拼接 ->获得预编译对象 -》sql注入问题
        PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where username = '" + username + "'");

        // 2. 占位符
        PreparedStatement ps2 = connection.prepareStatement("select * from t_user where username = ?");
        ps2.setString(1, username);
    }

3.2 MyBatis获取参数值的两种方式

MyBatis获取参数值的两种方式:${}和#{}

  • ${}的本质就是字符串拼接
  • #{}的本质就是占位符赋值

${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;
但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号(尽量使用这一种)。

3.3 MyBatis获取参数值的五种情况

情况1: 单个字面量类型的参数

若mapper接口中的方法参数为单个的字面量类型
此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号

ParameterMapper接口:

public interface ParameterMapper {
    /**
     * 单个的字面量类型:
     * 根据用户名查询用户信息
     */
    User getUserByUserName(String username);
}

对应在ParameterMapper.xml中配置。
方式一:

<!--    User getUserByUserName(String username);-->
<!--    使用#{},里面内容可以随便写,都是传进来的username的值-->
    <select id="getUserByUserName" resultType="User">
       select * from t_user where username = #{username}
    </select>

方式二:

<!--    User getUserByUserName(String username);-->
    <select id="getUserByUserName" resultType="User">
        <!-- 
       select * from t_user where username = ${username}
          如果使用这种方式,得到的sql语句是:
          Preparing: select * from t_user where username = RUOYI
          而其中username的值‘RUOYI’没有单引号,语句不正确,会报错。
          因此要手动添加单引号
       -->
        select * from t_user where username = '${username}'
    </select>

测试类:

    /**
     * MyBatis获取参数值的各种情况:
     * 情况1: mapper接口方法的参数为单个字面量的参数
     * 可以通过${} #{}以任意的字符串获得参数值,但需要注意${}的单引号问题
     */
    @Test
    public void testgetUserByUserName(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        User user = mapper.getUserByUserName("RUOYI");
        System.out.println(user);
    }

情况2:多个字面量类型的参数

若mapper接口中的方法参数为多个时
此时MyBatis会自动将这些参数放在一个map集合中,以arg0,arg1…为键,以参数为值;
以 param1,param2…为键,以参数为值;
因此只需要通过${}和#{}访问map集合的键就可以获取相对应的 值,注意${}需要手动加单引号

ParameterMapper接口:

public interface ParameterMapper {
    /**
     * 验证登录
     */
    User checkLogin(String username, String password);
}

对应在ParameterMapper.xml中配置。

<!--    User checkLogin(String username, String password);-->
    <select id="checkLogin" resultType="User">
        <!--
        写:select * from t_user where username = #{username} and password = #{password}
        会报错:Parameter 'username' not found. Available parameters are [arg1, arg0, param1, param2]
        因为sql语句没有解析成功-->

        <!--以map集合形式存储,arg0->param1, arg1->param2,这时直接用键arg访问就好了,用param访问也行。

		以下两种方式选一个:-->
        select * from t_user where username = #{arg0} and password = #{arg1}
        select * from t_user where username = '#{param1}' and password = '#{param2}'
    </select>

测试类:

    /**
     * 情况2:mapper接口方法的参数为多个时
     * 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储
     * a》以arg0,arg1。。为键,参数为值
     * b》以param0,param1。。为键,参数位置
     * 因此只需要通过#{}和${}以键的方式访问值即可,但需要注意${}的单引号问题
     */
    @Test
    public void testCheckLogin(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        User user = mapper.checkLogin("RUOYI","123456");
        System.out.println(user);
    }

情况3:map集合类型的参数

若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在map中
只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号

ParameterMapper接口:

public interface ParameterMapper {
	/**
     * 验证登录
     */
    User checkLoginByMap(Map<String, Object> map);
}

对应在ParameterMapper.xml中配置。

<!--    User checkLoginByMap(Map<String, Object> map);-->
    <select id="checkLoginByMap" resultType="User">
        select * from t_user where username = #{username} and password = #{password}
    </select>

测试类:

    /**
     * 情况3:若mapper接口方法的参数有多个时,可以手动将这些参数放在一个map中存储
     * 只需要通过#{} ${}以键的方式访问值即可,但是需要注意${}的单引号问题
     */
    @Test
    public void testCheckLoginByMap(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);

        Map<String, Object> map = new HashMap<>();
        map.put("username","RUOYI");
        map.put("password","123456");

        User user = mapper.checkLoginByMap(map);
        System.out.println(user);
    }

情况实体类类型的参数

若mapper接口中的方法参数为实体类对象时 此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号

ParameterMapper接口:

public interface ParameterMapper {
    /**
     * 添加用户信息
     */
    int insertUser(User user);
}

对应在ParameterMapper.xml中配置。

<!--        int insertUser(User user);-->
<!--    找到相对应的get方法,如username->找getUsername(),看get/set方法-->
    <insert id="insertUser">
        insert into t_user values(null, #{username}, #{password}, #{age}, #{gender}, #{email})
    </insert>

测试类:

    /**
     * 情况4:mapper接口方法的参数是实体类类型的参数(web从control层传过来的)
     * 只需要通过#{} ${}以属性的方式访问属性值即可,但是需要注意${}的单引号问题
     */
    @Test
    public void testInsertUser(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);

        User user = new User(null, "Pandora", "4444", 66, "m", "1111@gmail.com");
        mapper.insertUser(user);
    }

情况5: 使用@Param标识参数

可以通过@Param注解标识mapper接口中的方法参数

此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;
param1,param2...为键,以参数为值;
只需要通过${}和#{}访问map集合的键就可以获取相对应的值, 注意${}需要手动加单引号

ParameterMapper接口:

public interface ParameterMapper {
    /**
     * 验证登录 (使用@Param)
     */
    User checkLoginByParam(@Param("username") String username, @Param("password") String password);
}

对应在ParameterMapper.xml中配置。

<!--    以@Param的值为键,参数为值; 或以"param1"/"param2"为键,参数为值-->
<!--    User checkLoginByParam(@Param("username") String username, @Param("password") String password);-->
    <select id="checkLoginByParam" resultType="User">
        select * from t_user where username = #{username} and password = #{password}
    </select>

测试类:

    /**
     * 情况5:使用@Param注解来命名参数
     * 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储
     * a》以@Param的值为键,参数为值; @Param(value = "xxx")
     * b》以param0,param1...为键,参数为值
     */
    @Test
    public void testCheckLoginByParam(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        User user = mapper.checkLoginByParam("RUOYI","123456");
        System.out.println(user);
    }

4、@Param源码分析

sql语句的唯一标识 command name00

分析代码
目的:验证@Param存储参数的两种方式

    /**
     * 情况5:使用@Param注解来命名参数
     * 此时MyBatis会将这些参数放在一个map集合中,以两种方式进行存储
     * a》以@Param的值为键,参数为值; @Param(value = "xxx")
     * b》以param1,param2...为键,参数为值
     */
    @Test
    public void testCheckLoginByParam(){
        SqlSession sqlSession = SqlSessionUtils.getSqlSession();
        ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);
        User user = mapper.checkLoginByParam("RUOYI","123456");
        System.out.println(user);
    }

在这里插入图片描述

(1)打断点,进入debug模式

在这里插入图片描述

选择step into进行调试
在这里插入图片描述

(2)Mapper底层使用代理模式创建,我们按step into进入缓存cachedInvokerinvoke()方法

在这里插入图片描述

(3)进入了invoke(),再进一步进入了mapperMethodexecute()方法(step into)。
在这里插入图片描述

execute()方法中包含一个switch语句,分别对应增删改查等关键字对应的处理流程。
在这里插入图片描述

(4)点击step over跳进switch语句内部,光标放在command上,点击加号,查看command内容。name为该sql语句的唯一标识,type为对应操作,即SELECT。
在这里插入图片描述

在这里插入图片描述

再点击step into,发现convertArgsToSqlCommandParam()方法是由paramNameResolver参数名称解析器中的getNamedParams()获取命名参数方法解析的,进一步step into进这个方法。
在这里插入图片描述

(5)进入getNamedParams()方法,查看names,发现names是一个map集合,包含了传进来的"username"、"password" 参数。
在这里插入图片描述

由结果再翻上去看@Param的解析过程。
在这里插入图片描述

(6)回到getNamedParams()方法,继续step over
在这里插入图片描述

两次循环entrySet后,发现param集合中得到两种映射

  • @Param的value作为key,参数值为value
  • param1, param2...作为key,参数值为value
    在这里插入图片描述

至此,@Param源码分析完毕,印证结论:可以使用#{param1}#{username}两种方式获得参数值。

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
Mybatis-Plus Generator是基于Mybatis-Generator的扩展,支持自定义代码生成器模板。 自定义模板参数设置步骤如下: 1. 新建自定义模板文件Mybatis-Plus Generator的classpath:templates目录下新建自定义模板文件,例如在该目录下新建一个MyMapper.xml.vm文件。 2. 在代码生成器配置文件配置自定义模板路径 在代码生成器的配置文件配置自定义模板路径,在该文件中找到templateEngine节点下的velocityTemplatePath节点,并将其设置为自定义模板文件所在目录的绝对路径。 例如: ``` <templateEngine> <type>velocity</type> <velocity> <properties> <property> <name>file.resource.loader.path</name> <value>/Users/username/mybatis-plus-generator/templates</value> </property> </properties> </velocity> </templateEngine> ``` 3. 设置自定义模板参数 在自定义模板文件中,使用Velocity模板语言来设置自定义参数。例如,在MyMapper.xml.vm文件中添加以下内容: ``` <?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="$packageName.$moduleName.mapper.$entityNameMapper"> <resultMap id="BaseResultMap" type="$packageName.$moduleName.entity.$entityName"> #foreach($column in $table.columns) <result column="$column.columnName" property="$column.propertyName" jdbcType="$column.jdbcType" /> #end </resultMap> </mapper> ``` 在该模板中,使用了$packageName、$moduleName、$entityName等参数,这些参数需要在代码生成器的配置文件中进行设置。 在代码生成器的配置文件中找到strategyConfig节点下的superEntityClass、entityLombokModel、entityColumnConstant、entityBuilderModel、controllerMappingHyphenStyle、versionFieldName、logicDeleteFieldName、tablePrefix、fieldPrefix、include、exclude、entityTableFieldAnnotationEnable等节点,将其设置为需要的参数。 例如: ``` <strategyConfig> <superEntityClass>com.baomidou.mybatisplus.extension.activerecord.Model</superEntityClass> <entityLombokModel>true</entityLombokModel> <entityColumnConstant>true</entityColumnConstant> <entityBuilderModel>true</entityBuilderModel> <controllerMappingHyphenStyle>true</controllerMappingHyphenStyle> <versionFieldName>version</versionFieldName> <logicDeleteFieldName>deleted</logicDeleteFieldName> <tablePrefix>sys_</tablePrefix> <fieldPrefix>sys_</fieldPrefix> <include>sys_user,sys_role,sys_permission</include> <exclude>sys_log</exclude> <entityTableFieldAnnotationEnable>true</entityTableFieldAnnotationEnable> </strategyConfig> ``` 以上是自定义模板参数设置步骤,按照这些步骤进行设置即可。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值