映射配置文件获取自增主键
用INSERT标签举例:
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
<!-- useGeneratedKeys获取自增主键 ,返回到User类的id属性 -->
Insert into User (username,birthday,sex)
values (#{username},#{birthday},#{sex})
</insert>
映射配置文件获取非自增主键
<insert id="insertUser" >
<!-- 主键为非自增时 -->
<!--插入前先执行以下操作 -->
<selectKey order="BEFORE" resultType="interger" keyProperty="id">
select max(id)+1 from User
</selectKey>
<!-- 获取到的主键值用于新插入记录的id值 ,可避免插入重复的id -->
Insert into User (id,username,birthday,sex)
values (#{id},#{username},#{birthday},#{sex})
<!--#{id,jdbcType=INTEGER}
给参数指定数据类型-->
</insert>
Mybatis 中$与#取值的区别
- #{}类似jdbc中的PreparedStatement,对于传入的参数,在预处理阶段会使用?代替,比如:
select * from User where id=#{id}
预编译后为:
select * from User where id=?
- ${}则是直接与sql语句进行拼串,这样不安全,会有sql注入风险,例如:
//登录验证代码
select * from user where name=' "+name+" ' and password=' "+password+" '
利用${}的方式传入name = 1 OR 1 = 1 与 password = 1 OR 1 = 1 时,将导致原本的SQL字符串被填为:
select * from user where (name = '1' OR '1'='1') and (password = '1' OR '1'='1')
也就是实际上运行的SQL命令会变成:SELECT * FROM user,因此达到无账号密码,亦可登录网站。
所以能使用#{}的地方应尽量使用#{}。
${}的应用场景
如果想要tablename或者ordey by字段这些不支持预编译的字段也变成动态输入的,可以使用${}接收传入参数值。例如:
selec * from ${table};
编译后如下,不会报错:
selec * from tablename;
多参函数
- Mybatis会为多参函数的参数自动创建一个Map,自动编号为{0,1,2…}或者{param1, param2, param3…}。此时在映射文件中要通过索引获取参数值:
<select id="getUserById" resultType="com.mj.domain.User">
select * from User where id=#{0} and username=#{1}
</select>
或者
<select id="getUserById" resultType="com.mj.domain.User">
select * from User where id=#{param1} and username=#{{param2}
</select>
- 也可以手动通过注解的方式给参数指定key值
public User getUserByIdandsex(@Param("id") Integer id, @Param("sex")String sex);
- 还可以自己创建Map<key,value>传入参数中。
集合形式返回结果
=返回类型为集合时, resultType中写元素类名
1.List
List<User> findAll();
映射文件的实现:
<select id="findAll" resultType="com.mj.domain.User">
select * from User
</select>
2.Map
查询多条记录封装为为Map
@MapKey("id")//指明id作为Key
Map<String ,User> findAllReturnMap();
实现:
<select id="findAllReturnMap" resultType="com.mj.domain.User">
select * from User
</select>
注意查询单条记录封装为Map时,resultType=“map”
resultMap自定义封装规则
Java程序中会使用一个类对应数据库中的一张表,当类的属性命名与数据库表中的列名相同时,Mybatis可以自动完成封装。当命名不一致时,可以在映射文件中使用resultMap自定义封装规则。
<!--type:指定为哪个JavaBean自定义封装规则:全类名
id:唯一标识-->
<resultMap id="myUser" type="com.mj.dao.IUserDao">
<!-- 指定主键对应规则-->
<id property="id" column="id"/>
<!-- 指定普通列对应规则-->
<result property="name" column="username"/>
<result property="birth" column="birthday"/>
<!-- 若类中属性还包含对其他类的引用,则用association封装该类-->
<association property="属性名" javaType="全类名">
<!-- 接下来定义该属性对应对象的封装规则 -->
<id property="XX" column="YY"/>
<result property="XXXX" column="YYYYY"/>
</association>
<!-- 若类中属性还包含对集合的引用,则用collection封装-->
<collection property="属性名" ofType="全类名">
<!-- 指定主键对应规则-->
<id property="XX" column="YY"/>
<!-- 指定普通列对应规则-->
<result property="XX" column="YYYY"/>
</collection>
</resultMap>
再将sql实现语句中的resultType改用为:
resultMap=“myUser”