如何免费做公司网站,17做网站骗子,秦皇岛黄金海岸门票多少钱,seo是一种利用搜索引擎的1.MyBatis 是什么#xff1f;
MyBatis 是⼀款优秀的持久层框架#xff0c;它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置 和映射原始类型、接⼝和 Java POJO#…1.MyBatis 是什么
MyBatis 是⼀款优秀的持久层框架它⽀持⾃定义 SQL、存储过程以及⾼级映射。MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的⼯作。MyBatis 可以通过简单的 XML 或注解来配置 和映射原始类型、接⼝和 Java POJOPlain Old Java Objects普通⽼式 Java 对象为数据库中的记录。
简单来说 MyBatis 是更简单完成程序和数据库交互的⼯具也就是更简单的操作和读取数据库⼯具。
Mybatis官⽹
2.为什么要学习 MyBatis
对于后端开发来说程序是由以下两个重要的部分组成的
1. 后端程序
2. 数据库 ⽽这两个重要的组成部分要通讯就要依靠数据库连接⼯具那数据库连接⼯具有哪些⽐如之前的 JDBC还有今天我们将要介绍的 MyBatis那已经有了 JDBC 了为什么还要学习 MyBatis 这是因为 JDBC 的操作太繁琐了我们回顾⼀下 JDBC 的操作流程
1. 创建数据库连接池 DataSource
2. 通过 DataSource 获取数据库连接 Connection
3. 编写要执⾏带 ? 占位符的 SQL 语句
4. 通过 Connection 及 SQL 创建操作命令对象 Statement
5. 替换占位符指定要替换的数据库字段类型占位符索引及要替换的值
6. 使⽤ Statement 执⾏ SQL 语句
7. 查询操作返回结果集 ResultSet更新操作返回更新的数量
8. 处理结果集
9. 释放资源
对于 JDBC 来说整个操作⾮常的繁琐我们不但要拼接每⼀个参 数⽽且还要按照模板代码的⽅式⼀步步的操作数据库并且在每次操作完还要⼿动关闭连接等 ⽽所有的这些操作步骤都需要在每个⽅法中重复书写。于是我们就想那有没有⼀种⽅法可以更简 单、更⽅便的操作数据库呢
答案是肯定的学习 MyBatis 的真正原因就是它可以帮助我们更⽅便、更快速的操作数据 库。
3.怎么学MyBatis
MyBatis 学习只分为两部分
配置 MyBatis 开发环境使⽤ MyBatis 模式和语法操作数据库
4.第⼀个MyBatis查询
开始搭建 MyBatis 之前我们先来看⼀下 MyBatis 在整个框架中的定位框架交互流程图 MyBatis 也是⼀个 ORM 框架ORMObject Relational Mapping即对象关系映射。在⾯向 对象编程语⾔中将关系型数据库中的数据与对象建⽴起映射关系进⽽⾃动的完成数据与对象 的互相转换
1. 将输⼊数据即传⼊对象SQL 映射成原⽣ SQL
2. 将结果集映射为返回对象即输出对象
ORM 把数据库映射为对象
数据库表table-- 类class
记录record⾏数据-- 对象object
字段field -- 对象的属性attribute
⼀般的 ORM 框架会将数据库模型的每张表都映射为⼀个 Java 类。 也就是说使⽤ MyBatis 可以像操作对象⼀样来操作数据库中的表可以实现对象和数据库表之间 的转换接下来我们来看 MyBatis 的使⽤吧。
4.1 创建数据库和表
接下来我们要实现的功能是使⽤ MyBatis 的⽅式来读取⽤户表中的所有⽤户我们使⽤个⼈博 客的数据库和数据包具体 SQL 如下。
-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;
-- 使⽤数据数据
use mycnblog;
-- 创建表[⽤户表]
drop table if exists userinfo;
create table userinfo(id int primary key auto_increment,username varchar(100) not null,password varchar(32) not null,photo varchar(500) default ,createtime datetime default now(),updatetime datetime default now(),state int default 1
) default charset utf8mb4; 4.2 添加MyBatis框架⽀持
添加 MyBatis 框架⽀持分为两种情况⼀种情况是对⾃⼰之前的 Spring 项⽬进⾏升级另⼀种情况是 创建⼀个全新的 MyBatis 和 Spring Boot 的项⽬下⾯我们分别来演示这两种情况的具体实现。
4.2.1 ⽼项⽬添加MyBatis
如果是在⽼项⽬中新增功能添加框架⽀持
!-- 添加 MyBatis 框架 --
dependencygroupIdorg.mybatis.spring.boot/groupIdartifactIdmybatis-spring-boot-starter/artifactIdversion2.1.4/version
/dependency
!-- 添加 MySQL 驱动 --
dependencygroupIdmysql/groupIdartifactIdmysql-connector-java/artifactIdversion5.1.38/versionscoperuntime/scope
/dependency
添加了 MyBatis 之后为什么还需要添加 MySQL 驱动呢 MyBatis 就像⼀个平台类似京东⽽数据库相当于商家有很多种不⽌有 MySQL还有 SQL Server、DB2 等等.....因此这两个都是需要添加的。
在⽼项⽬中快速添加框架更简单的操作⽅式是使⽤EditStarters插件 EditStarters 插件的使⽤⽅法 搜索“MyBatis”添加即可
4.2.2 新项⽬添加MyBatis 4.3 配置连接字符串和MyBatis 此步骤需要进⾏两项设置数据库连接字符串设置和 MyBatis 的 XML ⽂件配置。
4.3.1 配置连接字符串
如果是 application.yml 添加如下内容
# 数据库连接配置
spring:datasource:url: jdbc:mysql://localhost:3306/mycnblog?characterEncodingutf8useSSLfalseusername: rootpassword: 123456driver-class-name: com.mysql.cj.jdbc.Driver
注意事项 如果使⽤ mysql-connector-java 是 5.x 之前的使⽤的是“ com.mysql.jdbc.Driver ” 如果是⼤于 5.x 使⽤的是“ com.mysql.cj.jdbc.Driver ” 。
4.3.2 配置 MyBatis 中的 XML 路径
MyBatis 的 XML 中保存是查询数据库的具体操作 SQL配置如下
# 配置 mybatis xml 的⽂件路径在 resources/mapper 创建所有表的 xml ⽂件
mybatis:mapper-locations: classpath:mapper/**Mapper.xml
4.4 添加业务代码
下⾯按照后端开发的⼯程思路也就是下⾯的流程来实现 MyBatis 查询所有⽤户的功能 4.4.1 添加实体类
先添加⽤户的实体类
package com.example.springmybatisdemo.model;import lombok.Data;import java.util.Date;
Data
public class User {private Integer id;private String name;private String password;private String photo;private Date createtime;private Date updatetime;
}4.4.2 添加 mapper 接⼝
数据持久层的接⼝定义
package com.example.springmybatisdemo.mapper;import com.example.springmybatisdemo.model.User;
import org.apache.ibatis.annotations.Mapper;import java.util.List;Mapper
public interface UserMapper {ListUser queryAll();
}4.4.3 添加 UserMapper.xml
数据持久成的实现mybatis 的固定 xml 格式
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.springmybatisdemo.mapper.UserMapper/mapper
UserMapper.xml 查询所有⽤户的具体实现 SQL
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.springmybatisdemo.mapper.UserMapperselect idqueryAll resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo/select
/mapper 以下是对以上标签的说明
mapper标签需要指定 namespace 属性表示命名空间值为 mapper 接⼝的全限定 名包括全包名.类名。select查询标签是⽤来执⾏数据库的查询操作的id是和 Interface接⼝中定义的⽅法名称⼀样的表示对接⼝的具体实现⽅法。resultType是返回的数据类型也就是开头我们定义的实体类。
4.4.4 添加 Service
服务层实现代码如下
4.4.5 添加 Controller
控制器层的实现代码如下
4.4.6 使⽤ postman 测试
5.增、删、改操作
接下来我们来实现⼀下⽤户的增加、删除和修改的操作对应使⽤ MyBatis 的标签如下
insert标签插⼊语句
update标签修改语句
delete标签删除语句
数据持久层的接⼝定义
package com.example.springmybatisdemo.mapper;import com.example.springmybatisdemo.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;Mapper
public interface UserMapper {/*** 查询所有数据* return*/ListUser queryAll();/*** 根据id来查询*/User queryById(Param(uid) Integer id);/*** 插入*/Integer insert(User user);/*** 修改数据*/void update(User user);/*** 删除数据*/void delete(Integer id);}数据持久层的实现
?xml version1.0 encodingUTF-8?
!DOCTYPE mapper PUBLIC -//mybatis.org//DTD Mapper 3.0//EN http://mybatis.org/dtd/mybatis-3-mapper.dtd
mapper namespacecom.example.springmybatisdemo.mapper.UserMapperselect idqueryAll resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo/selectselect idqueryById resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo where id ${id}/selectinsert idinsertinsert into userinfo (username,password,photo)values (#{username},#{password},#{photo})/insertupdate idupdateupdate userinfo set username #{username},password #{password},photo #{photo} where id #{id}/updatedelete iddeletedelete from userinfo where id #{id}/delete
/mapper
特殊的添加返回⾃增 id
默认情况下返回的是受影响的⾏号如果想要返回⾃增 id具体实现如下 useGeneratedKeys这会令 MyBatis 使⽤ JDBC 的 getGeneratedKeys ⽅法来取出由数据 库内部⽣成的主键⽐如像 MySQL 和 SQL Server 这样的关系型数据库管理系统的⾃动 递增字段默认值false。 keyColumn设置⽣成键值在表中的列名在某些数据库像 PostgreSQL中当主键列 不是表中的第⼀列的时候是必须设置的。如果⽣成列不⽌⼀个可以⽤逗号分隔多个属性 名称。 keyProperty指定能够唯⼀识别对象的属性MyBatis 会使⽤ getGeneratedKeys 的返回 值或 insert 语句的 selectKey ⼦元素设置它的值默认值未设置unset。如果⽣成列 不⽌⼀个可以⽤逗号分隔多个属性名称。
6.查询操作
6.1 单表查询
下⾯我们来实现⼀下根据⽤户 id 查询⽤户信息的功能。 Controller 实现代码如下
RequestMapping(/getuser)
public User getUserById(Integer id) {return userService.getUserById(id);
}Mapper.xml 实现代码如下 select idqueryById resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo where id ${id}/select
6.1.1 参数占位符 #{} 和 ${}
#{}预编译处理。${}字符直接替换。
预编译处理是指MyBatis 在处理#{}时会将 SQL 中的 #{} 替换为?号使⽤ PreparedStatement 的 set ⽅法来赋值。直接替换是MyBatis 在处理 ${} 时就是把 ${} 替换成变量的值。 6.1.2 ${} 优点
使⽤ ${sort} 可以实现排序查询⽽使⽤ #{sort} 就不能实现排序查询了因为当使⽤ #{sort} 查询时 如果传递的值为 String 则会加单引号就会导致 sql 错误。
6.1.3 SQL 注⼊问题
sql 注⼊代码“ or 11”
使用#号
select idqueryByNameAndPassWord resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo where username #{username} and password #{password}/select 测试
Testvoid queryByNameAndPassWord() {String username admin;String password or 11;User user userMapper.queryByNameAndPassWord(username,password);log.info(user null ? null:user.toString());}
结果数据没有查询出来响应正常 使用$符号 select idqueryByNameAndPassWord resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo where username ${username} and password ${password}/select
测试 Testvoid queryByNameAndPassWord() {String username admin;
// String password 123;String password or 11;User user userMapper.queryByNameAndPassWord(username,password);log.info(user null ? null:user.toString());} 结果数据不该被查出来结果被查出来 什么时候使用$ 排序时只能使用$。 6.1.4 like 查询
使用#号 使用$符号
程序可以正常运行但是$存在SQL注入的问题
需要使用MySQL的内置函数
select idqueryByLike resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo where username like concat(%,#{name},%)/select $和#区别 6.2 多表查询
如果是增、删、改返回搜影响的⾏数那么在 mapper.xml 中是可以不设置返回的类型的
insert idinsertinsert into userinfo (username,password,photo)values (#{username},#{password},#{photo})/insertupdate idupdateupdate userinfo set username #{username},password #{password},photo #{photo} where id #{id}/updatedelete iddeletedelete from userinfo where id #{id}/delete
对于select查询标签来说⾄少需要两个属性
id 属性⽤于标识实现接⼝中的那个⽅法
结果映射属性结果映射有两种实现标签resultMap 和resultType 。
6.2.1 返回类型resultType
绝⼤数查询场景可以使⽤ resultType 进⾏返回如下代码所示
select idqueryAll resultTypecom.example.springmybatisdemo.model.Userselect * from userinfo/select
它的优点是使⽤⽅便直接定义到某个实体类即可。
6.2.2 返回字典映射resultMap
resultMap 使⽤场景
字段名称和程序中的属性名不同的情况可使⽤ resultMap 配置映射⼀对⼀和⼀对多关系可以使⽤ resultMap 映射并查询数据。
字段名和属性名不同的情况
数据库中 程序中
public class User {private Integer id;private String name;private String pwd;private String photo;private Date createtime;private Date updatetime;
}mapper.xml
resultMap idBaseMap typecom.example.springmybatisdemo.model.Userid propertyid columnid/idresult propertyname columnusername/resultresult propertypwd columnpassword/result/resultMapselect idqueryAllByMap resultMapBaseMapselect * from userinfo/select 6.2.3 多表查询
在多表查询时如果使⽤ resultType 标签在⼀个类中包含了另⼀个对象是查询不出来被包含的对象 的⽐如以下实体类
Data
public class ArticleInfo {private Integer id;private String title;private String content;private LocalDateTime createtime;private LocalDateTime updatetime;private Integer rcount;// 包含了 userinfo 对象private UserInfo user;
}
程序的执⾏结果如下图所示 此时我们就需要使⽤特殊的⼿段来实现联表查询了。
6.2.3.1 ⼀对⼀的表映射
⼀对⼀映射要使⽤ association标签具体实现如下⼀篇⽂章只对应⼀个作者
resultMap idBaseMap typecom.example.springmybatisdemo.model.ArticleInfoid propertyid columnid/idresult propertytitle columntitle/resultresult propertycontent columncontent/resultresult propertycreatetime columncreatetime/resultresult propertyupdatetime columnupdatetime/resultassociation propertyuser resultMapcom.example.springmybatisdemo.mapper.UserMapper.BaseMap/association/resultMapselect idqueryArticle resultMapBaseMapselect*from articleinfo taleft join userinfo tb on ta.uid tb.id/select
以上使⽤ 标签association表示⼀对⼀的结果映射
property 属性指定 Article 中对应的属性即⽤户。resultMap 属性指定关联的结果集映射将基于该映射配置来组织⽤户数据。columnPrefix 属性绑定⼀对⼀对象时是通过 columnPrefixassociation.resultMap.column 来映射结果集字段。 association.resultMap.column是指 标签中 resultMap属性对应的结果集映 射中column字段。
注意columnPrefix 属性不能省略如果省略当联表中如果有相同的字段那么就会导致查询出错。 ⽐如两篇⽂章都是⼀个⼈写的如果没有 columnPrefix 就会导致查询的⽤户 id因为和⽂章表 id 相 同查询出错。
articleinfo
public class ArticleInfo {private Integer id;private String title;private String content;private Date createtime;private Date updatetime;private Integer rcount;private User user;
} Mapper
Mapper
public interface ArticleMapper {ListArticleInfo queryArticle();
}6.2.3.2 ⼀对多⼀个用户多篇⽂章案例
⼀对多需要使⽤ collection标签⽤法和association 相同
7.复杂情况动态SQL使用
动态 sql 是Mybatis的强⼤特性之⼀能够完成不同条件下不同的 sql 拼接。
动态SQL根据输入参数不同动态的拼接SQL
可以参考官⽅⽂档mybatis – MyBatis 3 | 动态 SQL
7.1 if标签
在注册⽤户的时候可能会有这样⼀个问题如下图所示 注册分为两种字段必填字段和⾮必填字段那如果在添加⽤户的时候有不确定的字段传⼊程序应该 如何实现呢
这个时候就需要使⽤动态标签 if来判断了⽐如添加的时候性别 state为⾮必填字段具体实现如下
insert idinsertByCondition insert into articleinfo(title,content,uidif teststate!null,state/if)values(#{title},#{content},#{userId}if teststate!null,#{state}/if)/insert
注意 test 中的 state是传⼊对象中的属性不是数据库字段。
7.2trim 标签
之前的插⼊⽤户功能只是有⼀个 state字段可能是选填项如果所有字段都是⾮必填项就考虑使⽤ trim标签结合if标签对多个字段都采取动态⽣成的⽅式。
trim标签中有如下属性
prefix表示整个语句块以prefix的值作为前缀suffix表示整个语句块以suffix的值作为后缀prefixOverrides表示整个语句块要去除掉的前缀suffixOverrides表示整个语句块要去除掉的后缀
调整 UserMapper.xml 的插⼊语句为 insert idinsertByCondition insert into articleinfo(trim prefix( suffix) prefixOverrides, suffixOverrides,if testtitle!nulltitle,/ifif testcontent!nullcontent,/ifif testuid!nulluid,/ifif teststate!nullstate/if)/trimtrim prefix( suffix) prefixOverrides, suffixOverrides,if testtitle!null#{title},/ifif testcontent!null#{content},/ifif testuserId!null#{userId},/ifif teststate!null#{state}/if/trim/insert
7.3 where标签
传⼊的⽤户对象根据属性做 where 条件查询⽤户对象中属性不为 null 的都为查询条件。
select idqueryByCondition resultTypecom.example.springmybatisdemo.model.ArticleInfoselect *from articleinfowhereif testuid!nulland uid #{uid}/ifif teststate!nulland state#{state}/if/where
测试 Testvoid queryByCondition() {ListArticleInfo articleInfos articleMapper.queryByCondition(null,null);log.info(articleInfos.toString());} where标签的作用
7.4 set标签
根据传⼊的⽤户对象属性来更新⽤户数据可以使⽤标签来指定动态内容。
update idupdateByCondition update articleinfosetif testuid!nulluid#{uid},/ifif teststate!nullstate#{state}/if/set/update
set标签作用 7.5foreach 标签
对集合进⾏遍历时可以使⽤该标签。foreach标签有如下属性
collection绑定⽅法参数中的集合如 ListSetMap或数组对象item遍历时的每⼀个对象open语句块开头的字符串close语句块结束的字符串separator每次遍历之间间隔的字符串
代码示例 delete idbatchDeletedelete from articleinfo where id inforeach collectionlist open( close) separator, itemid#{id}/foreach/delete 属性分析 8、其他
Mybatis的实现有两种方式
1.xml方式
2.注解的方式
例如
package com.example.springmybatisdemo.mapper;import com.example.springmybatisdemo.model.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;Mapper
public interface UserMapper2 {Select(select * from userinfo)ListUser queryAll();Select(select * from userinfo where id #{id})User queryById(Integer aaa);
}测试
package com.example.springmybatisdemo.mapper;import com.example.springmybatisdemo.model.User;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.annotations.Select;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.util.List;Slf4j
SpringBootTest
class UserMapper2Test {Autowiredprivate UserMapper2 userMapper2;Testvoid queryAll() {ListUser userList userMapper2.queryAll();log.info(userList.toString());}Testvoid queryById() {User user userMapper2.queryById(1);log.info(user.toString());}
}
但是动态SQL写出来比较复杂