MyBatis学习记录(2)之参数传递

MyBatis学习记录(2)之参数传递

参数传递

从 java 代码中把参数传递到 mapper.xml 文件

1. 一个简单类型参数的传递

Dao 接口中方法的参数只有一个简单类型(java 基本类型和 String),使用占位符 #{ 任意字符 },和方法的参数名无关。

  • 接口方法:
Student selectById(int id);
  • mapper 文件:
<select id="selectById" resultType="com.bjpowernode.domain.Student">
	select id,name,email,age from student where id=#{studentId}
</select>

#{studentId} , studentId 是自定义的变量名称,可以是任意值和方法参数名无关。

2. 多个参数-使用@Param

多个简单类型的参数,先使用@Param定义参数名称

再在mapper文件中使用方式 #{@Param定义的参数名}来获取参数

  • 接口方法:
List<Student> selectByNameOrAge(@Param("myname") String name, @Param("myage") Integer age);
  • mapper 文件:
<select id="selectByNameOrAge" resultType="com.bjpowernode.domain.Student">
    select id,name,email,age from student where name=#{myname} or age=#{myage}
</select>
3. 多个参数-使用对象

使用 java 对象传递参数, java 的属性值就是 sql 需要的参数值。 每一个属性就是一个参数。

语法格式: #{ property, javaType=java 中数据类型名, jdbcType=数据类型名称 }

javaType, jdbcType 的类型 MyBatis 可以检测出来,一般不需要设置。
常用格式: #{ property }

  • 接口方法:
List<Student> selectMultiObject(Student student);
  • mapper 文件:
<select id="selectMultiObject" resultType="com.bjpowernode.domain.Student">
     select id,name,email,age from student where name=#{name} or age=#{age}
</select>
4. 多个参数-按位置

如果传递多个参数的话,mybatis会自动将参数封装在Map集合中,参数的键是从 param1 开始的

引用参数语法: #{param位置} , 第一个参数是#{param1}, 第二个是#{param2}

  • 接口方法:
List<Student> selectMultiByNameAndAge(String name,Integer age);
  • mapper 文件:
<select id="selectMultiByNameAndAge" resultType="com.bjpowernode.domain.Student">
	select id,name,email,age from student where name=#{arg0} or age=#{arg1}
</select>
5. 多个参数-使用Map

Map 集合可以存储多个值, 使用Map向 mapper 文件一次传入多个参数。Map 集合使用 StringkeyObject 类型的值存储value。 mapper 文件使用 # { key } 引用参数值。

  • 接口方法:
List<Student> selectMultiByMap(Map<String,Object> map);
  • mapper 文件:
<select id="selectMultiByMap" resultType="com.bjpowernode.domain.Student">
	select id,name,email,age from student where name=#{stuname} or age=#{stuage}
</select>
6. 参数传递总结
  1. 单个参数:直接使用#{参数名}进行取值,mybatis没做特殊处理,参数名可以随便写。

  2. 多个参数:使用#{param1},#{param2}取值

  3. 命名参数:通过@param(“key”)明确指定封装map中的key,就可以通过#{key}取出参数值了

  4. POJO:如果多个参数正好是业务模型,这时候就可以传入业务模型,通过#{属性名}就可以取值了

  5. Map:如果多个参数不是业务模型,而且不经常使用,可以自定义Map传入

  6. TO:如果多个参数不是业务模型,而且经常使用,可以自定义一个TO来传输对象

#和$

  • #:占位符,告诉 mybatis 使用实际的参数值代替。并使用 PreparedStatement 对象执行 sql 语句, #{…}代替sql 语句的“?”。 可以避免SQL注入,这样做更安全,更迅速,通常也是首选做法

  • $:字符串替换, 告诉 mybatis 使用$包含的“字符串”替换所在位置。使用 Statement 把 sql 语句和${…}的内容连接起来(相当于是String字符串中的+号),有SQL注入的风险。主要用在替换表名,列名,不同列排序等操作。

  • 接口方法:

Student findByDiffField(@Param("col") String columName, @Param("fval") Object fieldValue);
  • mapper 文件:
<!--
	相当于"select id,name,email,age from student where" + "columName" + "=?"
-->
<select id="findByDiffField" resultType="com.bjpowernode.domain.Student">
	select id,name,email,age from student where  ${col} = #{fval}
</select>

结果从mapper文件中返回给java

一、resultType

resultType: 执行 sql 得到 ResultSet 转换后的类型,使用类型的完全限定名别名
注意:

  • 如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身。
  • resultType 和 resultMap,不能同时使用。
1. 返回简单类型
<select id="countStudent" resultType="int">
	select count(*) from student
</select>

或者

<select id="countStudent" resultType="java.lang.Integer">
	select count(*) from student
</select>
2. 返回对象类型
  • 可以在MaBatis的主配置文件中对对象指定别名
<!--定义resultType使用的别名-->
<typeAliases>
    <!-- 一个typeAlias用来定义一个类型的别名
          type:全限定类型名称
          alais:自定义别名
    -->
    <typeAlias type="com.bjpowernode.domain.Student" alias="mystudent" />
</typeAliases>

对应的用别名的查询语句:

<select id="selectStudentById" resultType="mystudent">
     select id,name,email,age from student where id=#{id}
</select>
  • 指定对应包下的类以类名作为别名
<!--
   name:包名,表示包中的类名就是别名, 这个包中的所有类的类名是别名(不用区分大小写)
-->
<typeAliases>
    <package name="com.bjpowernode.domain" />
</typeAliases>

对应的用别名的查询语句:

<select id="selectStudentById" resultType="StuDeNt"><!--用类名作为别名,不区分大小写-->
    select id,name,email,age from student where id=#{id}
</select>
3. 返回Map类型(基本不用)

sql 的查询结果作为 Map 的 keyvalue。推荐使用 Map<Object,Object>

注意: Map 作为接口返回值, sql 语句的查询结果最多只能有一条记录(可以没有)。 大于一条记录是错误。

<select id="selectByMap" resultType="java.util.HashMap">
	select name, email from student where age = #{age}
</select>
二、resultMap

从mapper.xml到java文件,返回结果类型为对象,且表的列名与对象的属性名不同时,可以有两种做法:

1. 在sql语句中通过as给字段起别名,使字段名与属性名相同
2. 使用resultMap将字段名与属性名一一对应进来
<!--先定义resultMap,给resultMap起个唯一名称
    type:java对象的类型, 一般使用类的全限定名称。
         sql语句执行结果的ResultSet会转为这个type指定的类型
    id:自定义的唯一名称,表示转换的规则
-->
<resultMap id="customMap" type="com.bjpowernode.vo.Customer">
    <!--数据库表的列和java对象的属性的对应关系-->
    <!--主键列使用id标签,属性的对应关系
        column:列名
        property:java对象的属性名
    -->
    <id column="id" property="cid"/>
    <!--非主键列,使用result标签-->
    <result column="name" property="cname"/>
    <result column="email" property="cemail"/>
    <result column="age" property="cage"/>
</resultMap>
<!--然后使用定义好的resultMap-->
<select id="selectResultTypeStudentById" resultMap="customMap">
     select id, name, email, age from student where id=#{id}
</select> 
三、like模糊查询
  1. 传入字符串:"%周%"
<select id="selectLikeOne" resultType="com.bjpowernode.domain.Student">
    select * from student where name like #{name}
</select>
  1. 传入字符串:"周"
<select id="selectLikeTwo" resultType="com.bjpowernode.domain.Student">
    select * from student where name like "%" #{name} "%"
</select>
四、selectKey 获取主键

主键列是自动增长时, mysql 提供了函数 LAST_INSERT_ID() 获取刚执行 insert 后的 id 列的值

MyBatis 框架提供了<selectKey>可以在一条 sql 句后,立即执行其他 sql 语句的能力。

语法:

<selectKey  keyColumn="sql 中列名" 
			keyProperty="java 对象属性名"
			order="BEFORE|AFTER,表示在插入语句之前还是之后查询" 
			resultType="java 中类型全限定名或别名">
	要执行的 sql 语句(没有表名)
</selectKey>

例子:

<insert id="insertSchool">
    insert into school(name,address) values(#{name},#{address})
    <selectKey keyColumn="stuId" keyProperty="id" resultType="int" order="AFTER">
        select last_insert_id() as stuId
        # 也可以这样写:select @@IDENTITY as stuId
	</selectKey>
</insert>

测试代码:

    School school = new School(......);
    int rows = dao.insertSchool(school);
    //获取刚刚添加的记录的主键值
    Integer id = school.getId();

理解:

把对象从java中传入到mapper,执行为插入操作之后,将从表中获取的keyColumn列的值赋值给传入对象的keyProperty属性

五、存在时更新,不存在时新增
  • 结构:
INSERT INTO
表名
	(字段1的名字,字段2的名字,字段3的名字,字段4的名字)
VALUES
	(“字段1的值”,“字段2的值”,“字段3的值”,“字段4的值”)
ON DUPLICATE KEY UPDATE
	字段1的名字=VALUES(字段1的名字),
	字段2的名字=VALUES(字段2的名字);

例如:当存在名字和性别相同的数据时,更新这条数据,不存在则新增

<insert id="insertBatch" keyProperty="name" useGeneratedKeys="true">
    insert into t_student(name, sex)
    values
    <foreach collection="entities" item="entity" separator=",">
        (#{entity.name}, #{entity.sex})
    </foreach>
    ON DUPLICATE KEY UPDATE name = VALUES(name), sex = VALUES(sex)
</insert>

注意,ON DUPLICATE KEY UPDATE 后面要跟不可重复字段(主键、唯一索引),当不可重复字段冲突时更新,不冲突时新增

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值