成都教育网站建设,seo品牌优化百度资源网站推广关键词排名,设计效果图怎么收费,wordpress微博目录
1. 数据库字段和 Java 对象不一致
2. 多表查询
3. 动态 SQL 使用
4. if 标签
5. trim 标签
6. where 标签
7. set 标签
8. foreach 标签
9. 通过注解实现
9.1 查找所有数据
9.2 通过 id 查找 1. 数据库字段和 Java 对象不一致
我们先来看一下数据库中的数…目录
1. 数据库字段和 Java 对象不一致
2. 多表查询
3. 动态 SQL 使用
4. if 标签
5. trim 标签
6. where 标签
7. set 标签
8. foreach 标签
9. 通过注解实现
9.1 查找所有数据
9.2 通过 id 查找 1. 数据库字段和 Java 对象不一致
我们先来看一下数据库中的数据 接下来我们在之前代码的基础上修改字段的名称
/*** 数据库字段和 Java 对象不完全一致*/
Data
public class User {private Integer id;private String name;private String pwd;private String photo;private Date createtime;private Date updatetime;
}
Slf4j
SpringBootTest
class UserMapperTest {Autowiredprivate UserMapper userMapper;Testvoid queryAll() {ListUser users userMapper.queryAll();log.info(users.toString());}BeforeEachvoid setUp() {log.info(before...);}AfterEachvoid tearDown() {log.info(after...);}
}
可以看到能够获取数据但是对应字段的值为 null 了 因为数据库的字段命名规则和 Java 的命名规则不一致数据库命名字母小写以下划线分割Java 属性命名小驼峰第一个英文单词首字母小写其他英文单词首字母大写。 一个 xml 文件中可以存在多个 resultMap只需要 id 不同即可 ListUser queryAllMap(); resultMap idBaseMap typecom.example.demo.model.Userid propertyid columnid/idresult propertyname columnusername/resultresult propertypwd columnpassword/result/resultMapselect idqueryAllMap resultMapBaseMapselect * from userinfo/select
Testvoid queryAllMap() {ListUser users userMapper.queryAllMap();log.info(users.toString());}
此时我们可以看到成功查询到数据 那么具体的关系如下图标注所示 2. 多表查询
我们再新建一张表
-- 创建⽂章表
drop table if exists articleinfo;
create table articleinfo(id int primary key auto_increment,title varchar(100) not null,content text not null,createtime datetime default now(),updatetime datetime default now(),uid int not null,rcount int not null default 1,state int default 1
)default charset utf8mb4;
如下图所示 添加文章的数据
-- ⽂章添加测试数据
insert into articleinfo(title,content,uid)values(Java,Java正⽂,1);
文章添加数据后如下图所示 首先是 SQL 语句的多表查询
select * from articleinfo ta
left join userinfo tb on ta.uid tb.id; 接下来通过 Mybatis 实现
首先新建 ArticleInfo 类
Data
public class ArticleInfo {private Integer id;private String title;private String content;private Date createtime;private Date updatetime;private Integer rcount;private User user;
}新建 ArticleMapper.xml 文件
resultMap idBaseMap typecom.example.demo.model.ArticleInfoid propertyid columnid/idresult propertytitle columntitle/resultresult propertycontent columncontent/resultresult propertycreatetime columncreatetime/resultresult propertyupdatetime columnupdatetime/resultassociation propertyuser resultMapcom.example.demo.mapper.UserMapper.BaseMap/association/resultMapselect idqueryArticle resultMapBaseMapselect *from articleinfo taleft join userinfo tb on ta.uid tb.id/select
添加测试类
Slf4j
SpringBootTest
class ArticleMapperTest {Autowiredprivate ArticleMapper articleMapper;Testvoid queryArticle() {ListArticleInfo articleInfos articleMapper.queryArticle();log.info(articleInfos.toString());}
}
运行结果如下图所示 我们可以看到上述方式的结果显示的不够完整且需要输入的 SQL 语句过多。 接下来我们通过另一种方式来实现
ListArticleInfo queryArticle2();
在 ArticleMapper.xml 文件中添加以下配置
resultMap idBaseMap2 typecom.example.demo.model.ArticleInfoid propertyid columnid/idresult propertytitle columntitle/resultresult propertycontent columncontent/resultresult propertycreatetime columncreatetime/resultresult propertyupdatetime columnupdatetime/resultresult propertyuserId columnuserid/resultresult propertyusername columnusername/result/resultMapselect idqueryArticle2 resultMapBaseMap2selectta.*,tb.id as userid,tb.username as usernamefrom articleinfo taleft join userinfo tb on ta.uid tb.id/select
添加测试类
Testvoid queryArticle2() {ListArticleInfo articleInfos articleMapper.queryArticle2();log.info(articleInfos.toString());}
查询数据如下图所示 需要注意在实际的开发中要尽量避免使用 *无论数据库中有多少字段都需要一一罗列出来。
如下所示
resultMap idBaseMap2 typecom.example.demo.model.ArticleInfoid propertyid columnid/idresult propertytitle columntitle/resultresult propertycontent columncontent/resultresult propertycreatetime columncreatetime/resultresult propertyupdatetime columnupdatetime/resultresult propertyuserId columnuserid/resultresult propertyusername columnusername/result/resultMapselect idqueryArticle2 resultMapBaseMap2selectta.id as id,ta.title as title,ta.content as content,ta.createtime as createtime,ta.updatetime as updatetime,tb.id as userid,tb.username as usernamefrom articleinfo taleft join userinfo tb on ta.uid tb.id/select
3. 动态 SQL 使用
在实际的应用中并不是每个信息都是必填的也就是动态 SQL根据输入参数的不同动态的拼接 SQL。
我们先来看一下表中现有的数据 接下来我们插入数据
void insert(ArticleInfo articleInfo);
insert idinsertinsert into articleinfo(title,content,uid,state)values (#{title},#{content},#{userId},#{state})/insert Testvoid insert() {ArticleInfo articleInfo new ArticleInfo();articleInfo.setTitle(测试文章);articleInfo.setContent(测试文章内容);articleInfo.setUserId(1);articleInfo.setState(null);articleMapper.insert(articleInfo);} 可以看到上面我们是自行将 state 的值设置为了 null那么如果我们没有给这个字段赋值呢
修改 XML 文件 insert idinsertinsert into articleinfo(title,content,uid)values (#{title},#{content},#{userId})/insert 可以看到当我们没有对 state 赋值时进行了自动默认赋值为1
那么这显然是不符合我们的预期的我们想要实现的是当用户没有输入数据时应该为默认值输入数据时显示为输入的数据。此时就需要用到标签了。
4. if 标签
我们的目标是根据用户输入的情况动态拼接 SQL。
void insertByCondition(ArticleInfo articleInfo);
insert idinsertByConditioninsert into articleinfo(title,content,uidif teststate!null,state/if)values(#{title},#{content},#{userId}if teststate!null,#{state}/if)/insert
Testvoid insertByCondition() {ArticleInfo articleInfo new ArticleInfo();articleInfo.setTitle(测试文章2);articleInfo.setContent(测试文章内容2);articleInfo.setUserId(1);articleMapper.insert(articleInfo);} 由于我们并没有设置 state 的状态因此默认为1
接下来我们设置 state 为0
Testvoid insertByCondition() {ArticleInfo articleInfo new ArticleInfo();articleInfo.setTitle(测试文章3);articleInfo.setContent(测试文章内容3);articleInfo.setUserId(1);articleInfo.setState(0);articleMapper.insertByCondition(articleInfo);}
可以看到成功运行 当我们需要对多个字段应用 if 标签时会存在报错 如果统一把逗号放在字段前面当第一个字段为 null 时整个 SQL 的最前面就会多一个逗号如果统一把逗号放在字段后面当最后一个字段为 null 时整个 SQL 的最后面会多一个逗号。
5. trim 标签
上面的插入数据功能如果所有字段都是非必填项就考虑使用标签结合标签对多个字段都采取动态生成的方式。 标签中有如下属性
prefix表示整个语句块以prefix的值作为前缀suffix表示整个语句块以suffix的值作为后缀prefixOverrides表示整个语句块要去除掉的前缀suffixOverrides表示整个语句块要去除掉的后缀 使用 trim 标签
insert idinsertByConditioninsert into articleinfotrim prefix( suffix) prefixOverrides, suffixOverrides,if testtitle!nulltitle,/ifif testcontent!nullcontent,/ifif testuserId!nulluid,/ifif teststate!nullstate/if/trimvaluestrim prefix( suffix) prefixOverrides, suffixOverrides,if testtitle!null#{title},/ifif testcontent!null#{content},/ifif testuserId!null#{content},/ifif teststate!null#{state},/if/trim/insert
可以看到此时能够正确执行 6. where 标签
当我们需要使用 where 语句进行条件筛选时
ListArticleInfo queryBycondition(Param(uid) Integer uid,Param(state)Integer state);
select idqueryBycondition resultTypecom.example.demo.model.ArticleInfoselect * from articleinfowhereif testuid!nulluid #{uid}/ifif teststate!nulland state#{state}/if/select
Testvoid queryBycondition() {ListArticleInfo articleInfos articleMapper.queryBycondition(1,1);log.info(articleInfos.toString());}
可以看到成功执行 此时我们修改代码如下 Testvoid queryBycondition() {ListArticleInfo articleInfos articleMapper.queryBycondition(1,null);log.info(articleInfos.toString());}
依然可以成功执行 当我们修改代码如下时 Testvoid queryBycondition() {ListArticleInfo articleInfos articleMapper.queryBycondition(null,1);log.info(articleInfos.toString());}
产生报错信息 添加语句 1 1继续修改代码如下
select idqueryBycondition resultTypecom.example.demo.model.ArticleInfoselect * from articleinfowhere 1 1if testuid!nulland uid #{uid}/ifif teststate!nulland state#{state}/if/select
此时可以看到成功执行 接下来我们使用 where 标签实现以上功能。
在 XML 文件中添加以下语句
select idqueryBycondition resultTypecom.example.demo.model.ArticleInfoselect * from articleinfowhereif testuid!nulland uid #{uid}/ifif teststate!nulland state#{state}/if/where/select
可以已经生成了 where 并且去掉了 and 当两个字段均为 null 时可以看到直接去掉了 where
Testvoid queryBycondition() {ListArticleInfo articleInfos articleMapper.queryBycondition(null,null);log.info(articleInfos.toString());} 综上我们可以知道 where 标签具有以下作用
生成 where 关键字去除多余的 and如果没有 where 条件就不会生成 where 关键字
7. set 标签
void updateByCondition(Param(uid) Integer uid,Param(state)Integer state);
update idupdateByConditionupdate articleinfosetif testuid!nulluid #{uid},/ifif teststate!nullstate #{state},/if/update
Testvoid updateByCondition() {articleMapper.updateByCondition(1,null);}
运行后产生以下报错 接下来我们使用 set 标签
update idupdateByConditionupdate articleinfosetif testuid!nulluid #{uid},/ifif teststate!nullstate #{state},/if/set/update
运行成功 综上我们可以看到 set 标签的作用
生成 set 关键字去除最后一个逗号也可以使用 trim 标签
8. foreach 标签
对集合进行遍历时可以使用该标签。标签有如下属性
collection绑定方法参数中的集合如 ListSetMap或数组对象item遍历时的每⼀个对象open语句块开头的字符串close语句块结束的字符串separator每次遍历之间间隔的字符串
因此我们来通过 foreach 标签实现以下目标 接下来我们通过代码实现
void batchDelete(ListInteger ids);
delete idbatchDeletedelete from articleinfo where id inforeach collectionlist open( close) separator, itemid#{id}/foreach/delete
Testvoid batchDelete() {ListInteger ids Arrays.asList(2,3,4,5,6,10,11);articleMapper.batchDelete(ids);}
可以看到成功运行 表中相应的数据也删除了 注意 还需要注意的是 collection 也可以是参数的名称 9. 通过注解实现
Mybatis 的实现有两种方式
xml注解
9.1 查找所有数据
接下来我们来看一下如何通过注解来实现
Mapper
public interface UserMapper2 {Select(select * from userinfo)ListUser queryAll();
}
Slf4j
SpringBootTest
class UserMapper2Test {Autowiredprivate UserMapper2 userMapper2;Testvoid queryAll() {ListUser userList userMapper2.queryAll();log.info(userList.toString());}
}
运行结果如下 9.2 通过 id 查找
Mapper
public interface UserMapper2 {Select(select * from userinfo where id #{uid})User queryById(Integer aaa);
}
Slf4j
SpringBootTest
class UserMapper2Test {Autowiredprivate UserMapper2 userMapper2;Testvoid queryById() {User user userMapper2.queryById(1);log.info(user.toString());}
}
可以看到运行结果如下 一个项目中注解和 XML 的方式可以并存对于简单的 SQL 使用注更加方便但是对于动态 SQL 注解写起来非常麻烦。