-
知识点一
.xml映射文件:
在使用MyBatis时,先要看POJO类中的属性名和数据库字段是否一致,如果一致的话,#{value}就直接写入字段名(属性名即可);如果不一样的话,需用通过resultMap进行配置映射,#{}里面写映射的property值。
输出映射:
resultType:
查询到的列名和resultType指定的pojo的属性名一致,才能映射成功。
reusltMap:
可以通过resultMap 完成一些高级映射。
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称(任意写都行)。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
${}:表示拼接字符串,不加任何修饰的拼接
#{}:表示一个占位符
${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
#{}和${}
在MyBaits的Sql映射文件#{}表示的是一个占位符号,通过#{}可以实现JDBC编程中的向占位符设置值,并会自动进行java类型和jdbc类型的转换。#{}可以接收简单类型值或pojo属性值。
1-1 如果parameterType指定的类型是pojo类型,那么#{}中的写的是pojo对象的属性名称或属性.属性…;
1-2 如果parammeterType指定的类型是基本数据类型(String long double等),那么#{}中的变量名称可以随意编写;
-
知识点二
resultType/resultMap:指定的就是单条记录所映射的java对象,所以不能写list,只能写成POJO对象(单条多条都一样)只不过mapper写的时候返回值要区分list<User>,还是User 08视频
mapper
//根据用户名列查询用户列表
public List<User> findUserByName(String name)throws Exception;
xml
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">(这里输出的不用输出List,输出对象即可)
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
-
知识点三
自增主键返回
mysql自增主键,执行insert提交之前自动生成一个自增主键。
通过mysql函数获取到刚插入记录的自增主键:
LAST_INSERT_ID()
是insert之后调用此函数。
修改insertUser定义:
<!-- 添加用户
parameterType:指定输入 参数类型是pojo(包括 用户信息)
#{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
-->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<!--
将插入数据的主键返回,返回到user对象中
SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用与自增主键
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
<!--
使用mysql的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
-->
<!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address}) -->
</insert>
非自增主键返回(使用uuid)
使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。
执行思路:
先通过uuid()查询到主键,将主键输入 到sql语句中。
执行uuid()语句顺序相对于insert语句之前执行。
-
知识点四
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
开发规范:
1、在mapper.xml中namespace等于mapper接口地址
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
<select id="selectUser" //与 PersonMapper.java 接口对应的方法
parameterType="int" //传入的参数格式 ,传入的是基本数据类型,可以不写
resultType="hashmap" //返回的数据类型,当返回多个参数的时候,建议使用 resultMap
resultMap="userResultMap" //返回的数据类型,相当于对 resultType="hashmap" 的封装。resultType、resultMap两者只能存在一个 parameterMap="deprecated" //已经废弃,现在使用 resultType 和 resultType
statementType="PREPARED"...
-
疑问一: resultMap,需要进行映射,虽然项目里都是用这个的,但是就目前而言,resultType依然可以达到要求,这个东西只是select中才会有的,也就是说,如果没有用到select,那就根本不用写映射.
解答:并不是,如果是insert插入好多列,(对象实现)此时还数据库字段和pojo字段还不一样,这种情况下也得需要映射的
property:POJO属性名,column:数据库字段
<resultMap type="com.thunisoft.avcp.module.meeting.model.TMeeting"
id="meetingResult">
<id property="cId" column="C_ID"></id>
<result property="cName" column="C_NAME" />
<result property="cContent" column="C_CONTENT" />
<result property="dtCreateTime" column="DT_CREATE_TIME" />
<result property="dtStartTime" column="DT_START_TIME" />
<result property="dtEndTime" column="DT_END_TIME" />
<result property="nType" column="N_TYPE" />
<result property="nStatus" column="N_STATUS" />
<result property="nValid" column="N_VALID" />
<collection property="metaList"
ofType="com.thunisoft.avcp.module.meeting.model.TMeetingMeta"
javaType="java.util.List">
<id property="cId" column="m_c_id" />
<result property="cMeetingId" column="C_MEETING_ID" />
<result property="cKey" column="C_KEY" />
<result property="cValue" column="C_VALUE" />
</collection>
</resultMap>
<insert id="insertMeeting" parameterType="com.thunisoft.avcp.module.meeting.model.TMeeting">
INSERT INTO
SC_AVCP.T_MEETING (
C_ID,
C_NAME,
C_CONTENT,
DT_CREATE_TIME,
DT_START_TIME,
DT_END_TIME,
N_TYPE,
N_STATUS,
N_VALID
)
values(
#{cId},
#{cName},
#{cContent},
#{dtCreateTime},
#{dtStartTime},
#{dtEndTime},
#{nType},
#{nStatus},
#{nValid}
)
</insert>
-
疑问二:paramter中什么时候可以省略?string为啥也能省
解答:当传入基本数据类型的时候,此字段是可省的.Mybatis官方文档中是的typeHandlers是有String这个类型的,也就是说,这个parameterType在传入string类型的时候是可选的
-
知识点五
动态SQL:foreach
例一:
sql片段:(片段中尽量不要用where)
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex = #{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username LIKE '%${userCustom.username}%'
</if>
<if test="ids!=null">
<!-- 使用 foreach遍历传入ids
collection:指定输入 对象中集合属性
item:每个遍历生成对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中需要拼接的串
-->
<!-- 使用实现下边的sql拼接:
AND (id=1 OR id=10 OR id=16)
-->
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
id=#{user_id}
</foreach>
<!-- 实现 “ and id IN(1,10,16)”拼接 -->
<!-- <foreach collection="ids" item="user_id" open="and id IN(" close=")" separator=",">
每个遍历需要拼接的串
#{user_id}
</foreach> -->
</if>
</if>
</sql>
sql片段引用:
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo"
resultType="cn.itcast.mybatis.po.UserCustom">
SELECT * FROM USER
<!--
where可以自动去掉条件中的第一个and
-->
<where>
<!-- 引用sql片段 的id,如果refid指定的id不在本mapper文件中,需要前边加namespace -->
<include refid="query_user_where"></include>
<!-- 在这里还要引用其它的sql片段 -->
</where>
</select>
mapper:
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;//UserQueryVo对象中含有list,private List<Integer> ids;
例二:
mapper:
int getTotalCount(String phone, TMeeting meeting,
@Param("statusList") List<Integer> statusList);
<!-- 根据手机号码加载会议总数 -->
<select id="getTotalCount" resultType="Integer">
SELECT count(*)
FROM
SC_AVCP.T_MEETING MEETING
,
SC_AVCP.T_PARTICIPANT
PARTICIPANT
where MEETING.c_id = PARTICIPANT.c_meeting_id AND
MEETING.N_VALID = 1
AND PARTICIPANT.c_phone =
#{0}
AND N_STATUS IN
<foreach collection="statusList" index="index" item="item"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
例三:
public void addScheduleInfoJson(List<ScheduleInfoJson> ScheduleInfoJsonList);
<insert id="addScheduleInfoJson" useGeneratedKeys="true"
parameterType="java.util.List">
insert into
sc_libra.t_libra_ydxx(c_id,c_jbfy,c_ydbh,c_ftxh,dt_ydkssj,dt_ydjssj,c_ydr,c_ydr_lxfs,n_sfqxyd,c_ajbh,dt_gxsj,n_status,n_times)
values
<foreach collection="list" item="item" index="index"
separator=",">
(#{item.ydid},#{item.jbfy},#{item.ydbh},#{item.ftxh},#{item.ydkssj},#{item.ydjssj},#{item.ydr},#{item.lxfs},#{item.qxyd},#{item.ajbhs},NOW(),0,0)
</foreach>
</insert>