1.selectKey元素
selectKey:
int insert2(TUser record);
<insert id="insert2" parameterType="TUser">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
insert into t_user (id, user_name, real_name,
sex, mobile,
email,
note, position_id)
values (#{
id,jdbcType=INTEGER},
#{
userName,jdbcType=VARCHAR},
#{
realName,jdbcType=VARCHAR},
#{
sex,jdbcType=TINYINT}, #{
mobile,jdbcType=VARCHAR},
#{
email,jdbcType=VARCHAR},
#{
note,jdbcType=VARCHAR},
#{
positionId,jdbcType=INTEGER})
</insert>
其中,select LAST_INSERT_ID()表示得到mysql数据库中最新的字段,插入时按照规则自动生成值。
oracle为:
<selectKey keyProperty=“id” order= " Before" resultType="int">
select SEQ_ID.nextval from dual
</selectKey>
order:
BEFORE:表示该sql语句在数据库,执行之前,获得该主键id,先获取主键id,先在数据库中占号,然后在插入。
AFTER:表示该sql语句在数据库中,执行之后,获取该主键id,执行结束后,再给号。
selectKey 一般使用oracle数据库中(没有自动增长)
2.sql元素和参数
<sql id="Base_Column_List">
id, user_name, real_name, sex, mobile, email, note,
position_id
</sql>
sql元素: 用来定义可重用的 SQL 代码段,可以包含在其他语句中;
参数:向sql语句中传递的可变参数
预编译 #{}:将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号,能够很大程度防止sql注入;
传值 KaTeX parse error: Unexpected character: '' at position 34: …中,无法防止sql注入; ̲ 表名、选取的列是动态的,or…
为什么 #{}可以防止sql注入,而${}不行?
因为:
#{}:将传入的数据都当成一个字符串,会对自动传入的数据加一个单引号,能够很大程度防止sql注入;
${}:传入的数据直接显示生成在sql中,无法防止sql注入;
主要是引号的区别。
在Preparing中,生成sql语句,${}参数已经掺入到sql语句中,而#{}则使用?占位符代替。
<select id="selectBySymbol" resultMap="BaseResultMap">
select
#{
inCol}
from ${
tableName} a
where a.sex = #{
sex}
order by ${
orderStr}
</select>
#{inCol}会被替换为对应的属性,在属性的名称外面加一层引号。
3.注解方式配置
注解方式就是将SQL语句直接写在接口上,对于需求比较简单的系统,效率较高。缺点在于,每次修改sql语句
都要编译代码,对于复杂的sql语句可编辑性和可读性都差,一般不建议使用这种配置方式;
@Select
@Results
@Insert
@Update
@Delete
使用xml:
List<TJobHistory> selectByUserId(int userId);
<resultMap id="BaseResultMap" type="com.enjoylearning.mybatis.entity.TJobHistory">
<id column="id" property="id" jdbcType="INTEGER" />
<result column="user_id" property="userId" jdbcType="INTEGER" />
<result column="comp_name" property="compName" jdbcType="VARCHAR" />
<result column="years" property="years" jdbcType="INTEGER" />
<result column="title" property="title" jdbcType="VARCHAR" />
</resultMap>
<select id="selectByUserId" resultMap="BaseResultMap" parameterType="java.lang.Integer">
select
<include refid="Base_Column_List" />
from t_job_history
where user_id = #{
userId,jdbcType=INTEGER}
</select>
使用注解:
定义一个resultmap:jobInfo
@Results(id="jobInfo",value={
@Result(property="id",column="id",id = true),
@Result(property="userId",column="user_id"),
@Result(property="compName",column="comp_name"),
@Result(property="years",column="years"),
@Result(property="title",column="title")
})
@Select("select id, user_id, comp_name, years, title from t_job_history"
+ " where user_id = #{userId}")
List<TJobHistory> selectByUserId(int userId);
@ResultMap("jobInfo")
@Select("select id, user_id, comp_name, years, title from t_job_history")
List<TJobHistory> selectAll();
@Insert("insert into t_job_history (id, user_id, comp_name, years, title)"
+ " values (#{id,jdbcType=INTEGER}, #{userId,jdbcType=INTEGER},"
+ "#{compName,jdbcType=VARCHAR},"
+ "#{years,jdbcType=INTEGER}, #{title,jdbcType=VARCHAR})")
@Options(useGeneratedKeys=true,keyProperty="id")
int insert(TJobHistory record);
3.动态sql元素
@Test
// if用于select,并与where配合
public void testSelectIfOper() {
// 2.获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取对应mapper
TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
String email = "qq.com";
Byte sex = null;
List<TUser> list = mapper.selectIfOper(email, sex);
// List<TUser> list = mapper.selectIfandWhereOper(email, sex);
System.out.println(list.size());
}
List<TUser> selectIfOper(@Param("email")String email,@Param("sex")Byte sex);
<select id="selectIfOper" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user a
where
<if test="email != null and email != ''">
a.email like CONCAT('%', #{
email}, '%') and
</if>
<if test="sex != null ">
a.sex = #{
sex}
</if>
</select>
其中,like语句为:like CONCAT(’%’, #{email}, ‘%’)
如果,sex == null,则会报异常。
可以使用:
<select id="selectIfandWhereOper" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from t_user a
<where>
<if test="email != null and email != ''">
and a.email like CONCAT('%', #{
email}, '%')
</if>
<if test="sex != null ">
and a.sex = #{
sex}
</if>
</where>
</select>
where标签可以自动消除符合条件的语句and,or关键字。
如果只更新不为null的字段,
@Test
// if用于update,并与set配合
public void testUpdateIfOper() {
// 2.获取sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 3.获取对应mapper
TUserMapper mapper = sqlSession.getMapper(TUserMapper.class);
TUser user = new TUser();
user.setId(3);
user.setUserName("cindy");
user.setRealName("王美丽");
user.setEmail("xxoo@163.com");
user.setMobile("18695988747");
user.setNote("cindy's note");
user.setSex((byte) 2);
user.setPositionId(1);
System.out.println(mapper.updateIfOper(user));
// System.out.println(mapper.updateIfAndSetOper(user));
}
<update id="updateIfOper" parameterType="TUser">
update t_user
set
<if test="userName != null">
user_name = #{
userName,jdbcType=VARCHAR},
</if>
<if test="realName != null">
real_name = #{
realName,jdbcType=VARCHAR},
</if>
<if test="sex != null">
sex = #{
sex,jdbcType=TINYINT},
</if>
<if test="mobile != null">
mobile = #{
mobile,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{
email,jdbcType=VARCHAR},
</if>
<if test="note != null">
note = #{
note,jdbcType=VARCHAR},
</if>
<if test="positionId != null">
position_id = #{
positionId,jdbcType=INTEGER}
</if>
where id = #{
id,jdbcType=INTEGER}
</update>
如果sql语句中,想要得到某个依赖对象中的某个属性,使用#{对象.属性}
在sql语句中,
<if test="email != null">
email = #{
email,jdbcType=VARCHAR},
</if>
<if test="note != null">
note = #{
note,jdbcType=VARCHAR},
</if>
<if test="positionId != null">
position_id = #{
positionId,jdbcType=INTEGER}
</if>
如果最后一句positionId == null,那么sql语句最后会多个逗号(,),运行时,报错。
使用set标签,可以自动消除最后一个逗号。
<update id="updateIfAndSetOper" parameterType="TUser">
update t_user
<set>
<if test="userName != null">
user_name = #{
userName,jdbcType=VARCHAR},
</if>
<if test="realName != null">
real_name = #{
realName,jdbcType=VARCHAR},
</if>
<if test="sex != null">
sex = #{
sex,jdbcType=TINYINT},
</if>
<if test="mobile != null">
mobile = #{
mobile,jdbcType=VARCHAR},
</if>
<if test="email != null">
email = #{
email,jdbcType=VARCHAR},
</if>
<if test="note != null">
note = #{
note,jdbcType=VARCHAR},
</if>
<if test="positionId != null">
position_id = #{
positionId,jdbcType=INTEGER},
</if>
</set>
where id = #{
id,jdbcType=INTEGER}
</update>
insert中,可能也会出现最后多一个逗号的情况,
<insert id="insertIfOper" parameterType="TUser">
insert into t_user (
<if test="id != null">
id,
</if>
<if test="userName != null">
user_name,
</if>
<if test="realName != null">
real_name,
</if>
<if test="sex != null">
sex,
</if>
<if test="mobile != null">
mobile,
</if>
<if test="email != null">
email,
</if>
<if test="note != null">
note,
</if>
<if