MyBatis查询、新增、更新删除操作 MyBatis查询、新增、更新与删除操作指南
MomokaJunko 人气:0调试之控制台打印SQL
Mybatis的使用流程
先来回顾一下mybatis的使用流程
- 创建mybatis-config.xml 全局的配置⽂件
- 创建XXXMapper.xml配置⽂件
- 创建SqlSessionFactory
- ⽤SqlSessionFactory创建SqlSession对象
- ⽤SqlSession执⾏增删改查CRUD
打印sql的配置
内置的⽇志⼯⼚提供⽇志功能, 使⽤log4j配置打印sql,添加依赖
<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.30</version> </dependency>
在应⽤的classpath中创建名称为 log4j.properties 的⽂件
log4j.rootLogger=ERROR, stdout
log4j.logger.cn.junko=DEBUG
#打印更多的TRACE内容
#log4j.logger.cn.junko=TRACE
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
这样,我们在执行操作数据库的时候就会有日志打印出来
查询
多个参数
当需要多个参数进行查询的时候,一般用到取别名,方便识别和使用
<select id="selectByPointAndTitle" resultType="cn.junko.domain.Video"> select * from video where point = #{point} and title like concat('%',#{title},'%') </select>
List<Video> selectByPointAndTitle(@Param("point") int point,@Param("title") String title);
驼峰映射
前面也讲到,数据库字段是下划线,java属性是驼峰,怎么查询映射上去
方法: select cover_img as coverImg from video
但是多字段的时候怎么办,每个参数都进行as操作吗?这里就用到Mybatis的自带配置
<!--下划线⾃动映射驼峰字段--> <settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
这样就能够进行自动映射,例如cover_img会自动映射为coverImg
Mybatis入参parameterType
parameterType 参数类型
可以是基本类型
parameterType="java.lang.Long" parameterType="java.lang.String"
也可以是JAVA集合List或者Map
parameterType="java.util.Map" parameterType="java.util.List"
或者是自定义的对象
parameterType="cn.junko.domain.Video"
取参数值,具体某个字段的类型,从java类型映射到数据库类型
例⼦ #{title, jdbcType=VARCHAR}
注意:
- 多数情况不加是正常使⽤,但是如果出现报错:⽆效的列类型,则是缺少jdbcType;
- 只有当字段可为NULL时才需要jdbcType属性
常见的数据库类型和java列席对比
JDBC Type | Java Type |
---|---|
CHAR | String |
VARCHAR | String |
LONGVARCHAR | String |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
BIT | boolean |
BOOLEAN | boolean |
TINYINT | byte |
SMALLINT | short |
INTEGER | INTEGER |
INTEGER | int |
BIGINT | long |
REAL | float |
FLOAT | double |
DOUBLE | double |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
CLOB | Clob |
BLOB | Blob |
ARRAY | Array |
DISTINCT | mapping of underlying type |
STRUCT | Struct |
REF | Ref |
DATALINK | java.net.URL |
插入
编写mapper
<insert id="addVideo" parameterType="cn.junko.domain.Video" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO `video`(`title`, `summary`, `cover_img`, `price`, `create_time`, `c_id`, `point`) VALUES (#{title},#{summary},#{coverImg},#{price},#{createTime},#{cid},#{point}); </insert>
获取自增主键,则需要在标签头加入这三段,即可自动映射到实体类中
useGeneratedKeys="true" keyProperty="id" keyColumn="id"
测试
@Test public void addVideo(){ Video video = new Video(); video.setTitle("测试数据3"); video.setSummary("nihao.com"); video.setCoverImg("wangyi"); video.setPrice(8777); video.setCreateTime(new Date()); video.setCid(7); video.setPoint(5.7); int rows = videoMapper.addVideo(video); System.out.println("自增主键:"+video.getId()); System.out.println(video.toString()); }
foreach 批量插入
foreach批量插⼊多条视频记录,⽤于循环拼接的内置标签,常⽤于 批量新增、in查询等常⻅
包含以下属性:
collection:必填,值为要迭代循环的集合类型,情况有多种
⼊参是List类型的时候,collection属性值为list
⼊参是Map类型的时候,collection 属性值为map的key值item:每⼀个元素进⾏迭代时的别名
index:索引的属性名,在集合数组情况下值为当前索引值,当迭代对象是map时,这个值是
map的key
open:整个循环内容的开头字符串
close:整个循环内容的结尾字符串
separator: 每次循环的分隔符
例子
需要注意的是item别名取值iteam.xxx
<insert id="addVideoList" parameterType="cn.junko.domain.Video" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO `video`(`title`, `summary`, `cover_img`, `price`, `create_time`, `c_id`, `point`) VALUES <foreach collection="list" separator="," item="video"> (#{video.title},#{video.summary},#{video.coverImg},#{video.price},#{video.createTime},#{video.cid},#{video.point}) </foreach> </insert>
list.add(video1); list.add(video2); int rows = videoMapper.addVideoList(list); System.out.println(list);
主键自增同样适用
更新
普通的更新比较简单,这里使用一下if test标签
- 可以选择性更新⾮空字段
- if test标签介绍
- if 标签可以通过判断传⼊的值来确定查询条件,test 指定⼀个OGNL表达式
- 常⻅写法
//当前字段符合条件才更新这个字段的值 <if test='title != null and id == 87 '> title = #{title}, </if> <if test="title!=null"> title = #{title}, </if>
代码
<!-- /*suffixOverrides=","去掉后缀,*/--> <update id="updateVideo" parameterType="cn.junko.domain.Video"> UPDATE `video` <trim prefix="set" > <if test="title != null">`title` = #{title},</if> <if test="summary != null">`summary` = #{summary},</if> <if test="coverImg != null">`cover_img` = #{coverImg},</if> <if test="price != 0">`price` = #{price},</if> <if test="createTime != null">`create_time` = #{createTime},</if> <if test="cid != 0">`c_id` = #{cid},</if> <if test="point > 7.0">`point` = #{point}</if> </trim> WHERE `id` = #{id}; </update>
⼀定要看pojo类⾥⾯的是基本数据类型,还是包装数据类型
删除
delete删除语法
需求:删除某个时间段之后 且⾦额⼤于 10元的数据
<delete id="deleteByCreateTimeAndPrice" parameterType="java.util.Map"> delete from video where create_time <![CDATA[ > ]]> #{createTime} and price <![CDATA[ >= ]]> #{price} </delete>
为什么要转义字符:
由于MyBatis的sql写在XML⾥⾯, 有些sql的语法符号和xml⾥⾯的冲突
⼤于等于 <![CDATA[ >= ]]>
⼩于等于 <![CDATA[ <= ]]>
总结
加载全部内容