Mybatis 框架实战(上)
- Mybatis 持久层:简化工作量、灵活
- Spring 粘合剂:整合框架 AOP IOC DI
- SpringMvc 表现层:方便前后端数据的传输
Mybatis:
- 1.是对jdbc的封装,
- 2.将sql语句放在映射文件中(xml),
- 3.自动将输入参数映射到sql语句的动态参数上,
- 4.自动将sql语句执行的结果映射成java对象
入门示例:
1.创建项目mubatis-01
2.导入jar:
- mybatis-3.2.8
- mysql-connect
- log4j-1.2.17
3.加入配置文件
(1)db.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url = jdbc:mysql://localhost:3306/mysql_0219
jdbc.username = root
jdbc.password = 123456
(2)log4j.properties https://blog.csdn.net/sinat_30185177/article/details/73550377
log4j.rootLogger=DEBUG,A1
log4j.logger.org.mybatis=DEBUG
...
(3) mybatis核心配置文件:mybatis-config.xml
(4) BlogMapper.xml
包:com.jingbin.mybatis.mapper
4.编写接口:BlogMapper
5.创建pojo:Blog
6.创建工具类:MyBatisUtil
7.编写测试类:
testSelectBlog
发现要连接数据库,学习mysql内容
学习配置好了后:运行报错:Invalid bound statement (not found): mapper.BlogMapper.selectBlog
解决:https://www.cnblogs.com/cailijuan/p/9505244.html
1)使用创建接口的方式
2)不是用接口的方式
8.列名和属性名不一致的情况
数据库里的列名为author_id,属性名为authorId。在BlogMapper.xml里:
1.使用别名
select author_id as authorId from Blog where id=#{id}
2.使用 resultMap
<resultMap type="Blog" id="blogResultMap">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="author_id" property="authorId" jdbcType="INTEGER"/>
</resultMap>
<select id="selectBlog" parameterType="Integer" resultMap="blogResultMap">
select * from blog where id = #{id}
</select>
9.模糊查询之#
和$
的区别
模糊查询:根据博客名字查询博客列表
1)使用#
传参
2)使用$
传参
#
是占位符?,$
是字符串拼接。
mybatis定义:
- 使用
$
。如果参数是单指类型(简单类型),并且只有一个参数,则花括号里只能写value占位。 - 使用
$
可以直接将%
写里面,可能有sql注入的风险,建议最好使用#
。参数是字符串要使用 '' - 当参数表示表名或列名的时候,只能使用
$
<!-- 使用 $ 不区分大小写的查询 lower-->
<select id="selectBlogByTitle2" parameterType="string" resultType="Blog">
select * from blog where lower(title) like lower('%${value}%')
</select>
</mapper>
10.查询排序
需求:按照某一列排序
select * from blog order by CONVERT(${value} USING gbk)
gbk:输入中文时排序成功,否则会失败。且使用gbk规避魅族(gb2313)不排序问题。
11.分页-多参数传递
需求:查询分页数据
- 1)使用索引
按照参数的顺序,从0开始
select * from blog limit #{0}, #{1}
- 2)使用注解
注解的value值要和mapper的占位参数一致。
select * from blog limit #{offset}, #{pageSize}
List<Blog> selectBlogByPage2(@Param(value = "offset") int offset, @Param(value = "pageSize") int pageSize);
- 3)使用map(常用)
注意:mapper中的参数占位符要和测试中的map的key一一对应
select * from blog limit #{offset}, #{pageSize}
// 测试
SqlSession session = MyBatisUtil.getSqlSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
Map<String, Object> objectMap = new HashMap<>();
objectMap.put("offset", 0);
objectMap.put("pageSize", 2);
List<Blog> blogList = blogMapper.selectBlogByPage3(objectMap);
12.插入功能和获取刚刚插入的id
- 1)插入记录
需求:新增一个博客记录
<insert id="insertBlog" parameterType="Blog">
insert into `blog`(
`name`,
`age`,
`title`,
`author_id`,
`featured`
) values (
#{name},
#{age},
#{title},
#{author_id},
#{featured}
)
</insert>
// 提交
session.commit();
- 2)获取自增id
方式1:在mapper中配置
insert
节点的属性useGeneratedKeys
和keyProperty
节点
<insert id="insertBlog" parameterType="Blog" useGeneratedKeys="true" keyProperty="id"/>
方式2:在全局配置文件中配置setting
<!--定义数据库链接配置-->
<properties resource="db.properties"/>
<!--具体的insert也得配置 keyProperty节点-->
<settings>
<setting name="useGeneratedKeys" value="true"/>
</settings>
方式3:适用于没有自增主键的数据库
<insert id="insertBlogOracle" parameterType="Blog">
<selectKey resultType="java.lang.Integer" order="BEFORE" keyProperty="id">
select seq.nextval as id from dual
</selectKey>
insert into `blog`(
`name`,
`age`,
`title`,
`author_id`,
`featured`
) values (
#{name},
#{age},
#{title},
#{author_id},
#{featured}
)
</insert>
<insert id="insertBlogMysql" parameterType="Blog">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
insert into `blog`(
`name`,
`age`,
`title`,
`author_id`,
`featured`
) values (
#{name},
#{age},
#{title},
#{author_id},
#{featured}
)
</insert>
13.修改功能和修改部分字段注意的问题
<update id="updateBlog" parameterType="Blog">
update `blog`
set
`name` = #{name},
`age` = #{age},
`title` = #{title},
`author_id` = #{author_id},
`featured` = #{featured}
where
`id` = #{id}
</update>
注意:如果没有为对象设置所有的要修改的属性,那么未设置的属性会用成员变量的默认值填充。 解决: 方式1:数据库查一遍,再返回的数据修改。缺点:又执行了一遍数据库操作 方式2:查询语句里增加if else。
14.删除记录
<delete id="deleteBlogById">
delete from blog where id=#{id}
</delete>
动态sql 批量删除:使用动态sql实现 if、[choose、when、otherwise]、where、set、trim、foreach、sql片段
15.if
需求:
- 1.查询已激活的并且博客的名字是包含某个查询字符串的记录
- 2.如果用户没有输入任何查询字符串,那么就显示所有已激活的记录
// 如果用户输入了查询字符串 select * from blog where state = 'ACTIVE' and title like '%o%'
// 用户没有输入查询字符串 select * from blog where state = 'ACTIVE'
select * from blog
where state = 'ACTIVE'
<if test="value != null and value!=''">
and title like value[%%] 具体见代码
</if>
16.choose、when、otherwise
需求:
- 1、查询已激活的
- 2、如果用户输入了标题的查询关键字,则根据关键字查询
- 3、否则根据blog风格样式查询
- 4、如果什么都没有输入,则显示推荐的博客
<select id="selectActiveBlogByTitleOrStyle" parameterType="Blog" resultType="Blog">
select * from blog
where state = 'ACTIVE'
<choose>
<when test="title != null and title!=''">and lower(title) like lower(#{title})</when>
<when test="style != null and style!=''">and style = #{style}</when>
<otherwise> and featured = true</otherwise>
</choose>
</select>
17.where
需求:多条件查询,根据状态,标题,是否被推荐 自动修补查询条件,查询语句中的where关键字使用<where>标签替代,不能省略 and or 关键字
<select id="selectBlogByCondition" parameterType="Blog" resultType="Blog">
select * from blog
<where>
<if test="state != null and state!=''">
state = #{state}
</if>
<if test="title != null and title!=''">
and lower(title) like lower(#{title})
</if>
<if test="featured != null">
and featured = #{featured}
</if>
</where>
</select>
18.set
需求:按需修改,修改执行的列,未指定的不修改 set 会自动去掉if语句后面的逗号
<update id="updateBlogByCondition" parameterType="Blog">
update `blog`
<set>
<if test="name != null">`name` = #{name},</if>
<if test="age != null">`age` = #{age},</if>
<if test="title != null">`title` = #{title},</if>
<if test="author_id != null">`author_id` = #{author_id},</if>
<if test="featured != null">`featured` = #{featured},</if>
<if test="state != null">`state` = #{state},</if>
<if test="style != null">`style` = #{state},</if>
</set>
where `id` = #{id}
</update>
19.trim
<select id="selectBlogByConditionTrim" parameterType="Blog" resultType="Blog">
select * from blog
-- prefixOverrides 去掉前面的 and 或 or
<trim prefix="where" prefixOverrides="and | or">
<if test="state != null and state!=''">
state = #{state}
</if>
<if test="title != null and title!=''">
and lower(title) like lower(#{title})
</if>
<if test="featured != null">
and featured = #{featured}
</if>
</trim>
</select>
<update id="updateBlogByConditionTrim" parameterType="Blog">
update `blog`
-- suffixOverrides 去掉后面的 ,
<trim prefix="set" suffixOverrides=",">
<if test="name != null">`name` = #{name},</if>
<if test="age != null">`age` = #{age},</if>
<if test="title != null">`title` = #{title},</if>
<if test="author_id != null">`author_id` = #{author_id},</if>
<if test="featured != null">`featured` = #{featured},</if>
<if test="state != null">`state` = #{state},</if>
<if test="style != null">`style` = #{state},</if>
</trim>
where `id` = #{id}
</update>
20.foreach
需求:批量删除
<!-- parameterType 与 collection 一致-->
<delete id="deleteBlogList" parameterType="list">
delete from blog where id in
<foreach collection="list" item="item" open="(" close=")" separator=",">
#{item}
</foreach>
</delete>
@Test
public void testDeleteBlogList() {
SqlSession session = MyBatisUtil.getSqlSession();
BlogMapper blogMapper = session.getMapper(BlogMapper.class);
List<Integer> asList = Arrays.asList(1, 2);
int count = blogMapper.deleteBlogList(asList);
// 提交
session.commit();
session.close();
System.out.println("更新了" + count + "条记录");
}
- Robot Framework | 03 基于Public API创建你RFS测试
- Robot Framework | 02 从抛弃RIDE开始创建你的RFS测试
- ASP.NET5 Beta8可用性
- Docker Swarm集群初探
- 数据库逻辑设计
- 06.移动先行之谁主沉浮----我的代码我来写(Xaml的优势)
- [快学Python3]迭代器和生成器
- [快学Python3]INI文件读写
- Vijos P1131 最小公倍数和最大公约数问题【暴力】
- Vjios P1736 铺地毯【暴力,思维】
- Vijos P1116 一元三次方程求解【多解,暴力,二分】
- Python Selenium设计模式-POM
- [快学Python3]HTTP处理 - urllib模块
- Vijos P1786 质因数分解【暴力】
- java教程
- Java快速入门
- Java 开发环境配置
- Java基本语法
- Java 对象和类
- Java 基本数据类型
- Java 变量类型
- Java 修饰符
- Java 运算符
- Java 循环结构
- Java 分支结构
- Java Number类
- Java Character类
- Java String类
- Java StringBuffer和StringBuilder类
- Java 数组
- Java 日期时间
- Java 正则表达式
- Java 方法
- Java 流(Stream)、文件(File)和IO
- Java 异常处理
- Java 继承
- Java 重写(Override)与重载(Overload)
- Java 多态
- Java 抽象类
- Java 封装
- Java 接口
- Java 包(package)
- Java 数据结构
- Java 集合框架
- Java 泛型
- Java 序列化
- Java 网络编程
- Java 发送邮件
- Java 多线程编程
- Java Applet基础
- Java 文档注释
- matplotlib基础绘图命令之plot
- Qt官方示例-样式表
- 入坑 LinkedList,i 了 i 了
- Elasticsearch 利用API进行搜索
- 通过 Serverless Regsitry 快速开发与部署一个 WordCount 实例
- 聊聊dubbo-go的gracefulShutdownFilter
- 强烈推荐:2020年15道优秀的TypeScript练习题 (上集)
- 聊聊dubbo-go的GenericFilter
- Salesforce LWC学习(十九) 针对 lightning-input-field的label值重写
- MySQL定时备份方案
- Nginx多方面调优策略
- 太厉害了!这应该是目前Redis可视化工具最全的横向评测
- pip install时timeout设置
- 聊聊dubbo-go的TpsLimitFilter
- 聊聊dubbo-go的TokenFilter