mybatis3.x入门及初步使用(2)
一.入参参数的使用(parameterType):
- 单个参数:
当传递参数为一个时,可以不用写parameterType,#{}内可以随意写
也可以使用@Param(“xxx”)注解,给该参数其别名
- 传递多个参数时(map):
1.可以使用Map把多个参数放入map,再把map传递。取值时,使用parameterType="Map/map/java.util.Map"接收,使用具体值时,使用#{key}的形式取值。
dao层:
//添加video
int addVideoByMap(Map<String,Object> videoParams);
映射文件:
<insert id="addVideoByMap" parameterType="map">
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`, `cover_img`, `price`,
`create_time`, `point`)
VALUES
( #{title}, #{summary}, #{coverImg}, #{price}, #{createTime}, #{point});
</insert>
测试:
Map<String,Object> map = new HashMap<>();
map.put("title","haha");
map.put("summary","lala");
map.put("coverImg","adasd");
map.put("price",11155);
map.put("createTime",new Date());
map.put("point",5.8);
int i = videoDao.addVideoByMap(map);
System.out.println(i);
或者传递map时,可以使用@Param(“xxx”)注解,给参数取别名,就可以不用使用parameterType接收了
dao层:
//添加video
int addVideoByMap(@Param("videoMap") Map<String,Object> videoParams);
映射文件:注意取值时,要使用"别名.key"的形式取值
<insert id="addVideoByMap">
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`, `cover_img`, `price`,
`create_time`, `point`)
VALUES
( #{videoMap.title}, #{videoMap.summary},
#{videoMap.coverImg}, #{videoMap.price}, #{videoMap.createTime}, #{videoMap.point});
</insert>
- 传递多个参数(注解形式):
传递多个参数,也可以直接使用@param(“xxx”)注解,给每个参数取一个别名,不需要使用parameterType接收,使用时直接使用#{别名}的形式,获取值
dao层:
//添加video的注解形式
int addCideoByAnno(@Param("title")String title,@Param("summary")String summary);
映射文件:
<insert id="addCideoByAnno">
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`)
VALUES
(#{title},#{summary})
</insert>
测试:
int i = videoDao.addCideoByAnno("lala", "lala");
System.out.println(i);
- 传递多个参数(pojo类形式):
把所有的参数,包装成一个pojo(实体类),传递pojo到mapper映射文件,可以使用parameterType="pojo的全路径"或者配置@Param(“xxx”)别名的形式传递,使用时,#{属性名}传递
parameterType:
dao层:
//添加video的pojo类形式
int addVideoByPojo(Video video);
映射文件:
<insert id="addVideoByPojo" parameterType="com.ceh.entity.Video">
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`)
VALUES
(#{title},#{summary})
</insert>
测试:
Video video = new Video();
video.setTitle("papa");
video.setSummary("papa");
int i = videoDao.addVideoByPojo(video);
@Param:
dao层:
//添加video的pojo类形式
int addVideoByPojo(@Param("video") Video video);
映射文件:
<insert id="addVideoByPojo" >
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`)
VALUES
(#{video.title},#{video.summary})
</insert>
二.mybatis的驼峰式命名:
有的时候,我们的数据库表设计的是例如:role_name这样的格式,但是我们的java的pojo类是驼峰式命名,这时,我们可以开启mybatis的驼峰式映射规则,他就可以自动的把数据库表中类似role_name的变为roleName这样的驼峰式命名。
<!--下划线自动映射驼峰字段-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
三.mybatis如何获取新增之后的主键:
当我们添加一条新的数据时,主键可能是自增的,我们有些业务是可能需要获得这些新增的主键,mybatis也提供了对应的配置
<insert id="addVideoByPojo" useGeneratedKeys="true" keyColumn="id" keyProperty="id" >
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`)
VALUES
(#{video.title},#{video.summary})
</insert>
在对应的映射文件插入sql中添加:
useGeneratedKeys=“true”:开启自增策略
keyColumn=“id”:映射数据库表中的主键列名
keyProperty=“id”:映射pojo类中对应的主键
这样在我们传入参数的pojo类中,对应的主键就有值了,该值就是此条数据自增之后的主键值(注意,一定要保存之后提交事务,不提交,主键也会有值,但是刷新或者出现异常之后,后续对应这个主键做的操作就无效了!)
四.mybatis的动态sql:
- if-where:
多用于查询:不知道传递那些参数的时候,可以直接传递pojo类,然后使用动态sql来进行忽略
dao层:
//根据查询条件查询video 但是有些业务不知道要根据什么查询,所以这里传递video实体类
//传递什么值,我们查什么值
List<Video> selectByVideo(@Param("video") Video video);
mapper:
<!--List<Video> selectByVideo(Video video);-->
<select id="selectByVideo" resultType="com.ceh.entity.Video">
select
*
from
video
/*where标签作用:
1.没有条件满足时,where不显示 select * from video
2.当前面条件不满足时,sql语句会多一个and连接符,where标签会去除第一个多余的and
*/
<where>
/*判断video.title不为空或者不为空字符串再添加该条件*/
<if test="video.title != null and video.title != ''">
title = #{video.title}
</if>
/*判断video.summary不为空或者不为空字符串再添加该条件*/
<if test="video.summary != null and video.summary != ''">
and summary = #{video.summary}
</if>
/*判断video.price不等于0再添加此条件*/
<if test="video.price != 0">
and price = #{video.price}
</if>
</where>
</select>
其他dao层和测试忽略....
- if-set
多用于update语句:if和上边作用一致,不满足条件,就不把语句块内的sql拼接,set标签替代原来的set,去除最后一个多余的逗号。
<!--//修改video,前台传递哪些,我们修改那些,不传递不修改
int updateVideo(Video video);
set标签:当price没有满足条件时,那么上边的条件生效,就会在末尾处多加一个逗号,
出现sql错误,set标签就是去除末尾的多余的逗号
-->
<update id="updateVideo" parameterType="com.ceh.entity.Video">
update
video
<set>
<if test="title != null and title != ''">
title = #{title},
</if>
<if test="summary != null and summary != ''">
summary = #{summary},
</if>
<if test="price != 0">
price = #{price}
</if>
</set>
where
id = #{id}
</update>
- trim:
拼接前后缀,去除多余符号(不常用,它的作用和上边的if-where和if-set差不多,不用这个)
- foreach
循环传递的list、array和map等,多用于批量操作
<!--//批量删除
int deleteByList(List<Integer> ids);
foreach:
collection="ids":要遍历的数据,可以是array、list、map的key(map的value是list)当起别名之后
可以直接使用别名
item="id":遍历之后的每个元素的名称
separator=",":按照什么分割
open="(":前缀,foreach遍历之前加一个(
close=")":后缀,foreach遍历之后加一个)
delete from video where id in (#{id},#{id},#{id}...)
-->
<delete id="deleteByList">
delete
from
video
where
id
in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>
<!--//批量增加int saveVideoList(@Param("videos")List<Video> videos);-->
<insert id="saveVideoList">
INSERT INTO
`xdclassvideo`.`video`(`title`, `summary`,`price`)
VALUES
<foreach collection="videos" item="video" separator=",">
(#{video.title},#{video.summary},#{video.price})
</foreach>
</insert>
- choose-when-ohterwise:
和java中的switch语句差不多,遇见if-else if-else这样的场景时,可以使用.
注意:并不是每组标签只能单独使用,可以随意的拼凑,只要逻辑符合即可
五.sql语句的转义字符:
因为使用mybatis之后,我们的sql语句要写在xml文件中,但是有一些字符可能冲突:例如 >、<等
可以使用:<![CDATA[ 转义字符 ]]> 这样就会保留它原始的意义
六. mybatis常见配置:
- mybatis核心配置文件的配置顺序:
configuration(配置)
properties(属性):读取配置文件
settings(设置):设置mybatis
typeAliases(类型别名):配置别名
typeHandlers(类型处理器):不常用
objectFactory(对象工厂):不常用
plugins(插件,少用):后期的pageHelper配置在这里,插件
environments(环境配置,不配多环境,基本在Spring里面配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识):不常用
mappers(映射器):配置映射文件的位置,可以理解为加载映射文件
顺序一定不能乱,会报错!
- 配置别名:
我们在使用映射文件接收参数或者返回数据时,避免不了要使用自定义的pojo类,但是需要写全路径名,mybatis为我们提供了别名功能,我们可以为某一个或者某一个包下的类起别名,使用的时候直接使用别名即可,简化开发
<!--配置别名-->
<typeAliases>
<!--配置单个:不建议,多个要配置的时候,很麻烦-->
<!--<typeAlias type="com.ceh.entity.Video" alias="Video"/>-->
<!--扫描整个包,整个包的类都会起别名-->
<package name="com.ceh.entity"/>
</typeAliases>
- 加载配置文件:
一般数据库文件单独提取出来,在使用给的地方加载进去,方便管理,mybatis也提供了相应的功能
db.properties:
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql:///xxx?useUnicode=true&characterEncoding=utf-8&useSSL=false
jdbc.username=xxx
jdbc.password=xxx
mybatis核心配置文件:使用${xxx}的形式取值
<!--加载配置文件-->
<properties resource="db.properties" />
配置环境时使用:
<!--配置单个的环境信息 id:唯一标识,关联上边default-->
<environment id="my">
<!--事务管理器:JDBC为使用jdk自带的事务管理器,后期变为声明式事务-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源 POOLED:使用mybatis自带的数据库连接池,后期可以变为其他数据连接池-->
<dataSource type="POOLED">
<!--以下为数据源默认配置:注意这里的name的值,要和当前使用的数据源里面的属性名保持一致
(最好进入类里面查看getset方法)-->
<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>
- sql语句抽离片段:
编写sql时,一般有很多的地方重复书写,例如:查询同一张表的字段
可以把这些经常书写的片段抽离成单独的语句片段,在需要使用的地方引入即可
把查询语句的字段抽离出来:
<sql id="selectVideo">
id,title,summary,cover_img,price,create_time,point
</sql>
使用: <include refid="sql语句片段的id" />
<select id="selectVideoById" resultType="com.ceh.entity.Video">
select
<include refid="selectVideo" />
from
video
where id = #{id}
</select>