顺德大良网站建设百度网站大全首页

bicheng/2026/1/20 1:16:03/文章来源:
顺德大良网站建设,百度网站大全首页,不用实名的云服务器,网站建设与维护工作内容经过前几篇博客的学习 Spring 系列的基本操作已经实现的差不多了#xff0c;接下来#xff0c;我们来学习更重要的知识#xff0c;将前端传递的数据存储起来#xff0c;或者查询数据库里面的数据。 一、MyBatis 是什么#xff1f; MyBatis 是一款优秀的持久层框架接下来我们来学习更重要的知识将前端传递的数据存储起来或者查询数据库里面的数据。 一、MyBatis 是什么 MyBatis 是一款优秀的持久层框架它支持自定义 SQL 、存储过程以及高级映射。 MyBatis 去除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO Plain Old Java Objects 普通老式 Java 对象为数据库中的记录。 简单来说 MyBatis 是更简单完成程序和数据库交互的工具也就是更简单的操作和读取数据库工具。 Mybatis官网 二、为什么要学习 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 操作示例回顾 下面的一个完整案例展示了通过 JDBC 的 API 向数据库中添加一条记录修改一条记录查询一条记录的操作。 -- 创建数据库 create database if not exists library default character set utf8mb4; -- 使用数据库 use library; -- 创建表 create table if not exists soft_bookrack ( book_name varchar(32) NOT NULL, book_author varchar(32) NOT NULL, book_isbn varchar(32) NOT NULL primary key ) ; 以下是 JDBC 操作的具体实现代码 import javax.sql.DataSource; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class SimpleJdbcOperation { private final DataSource dataSource; public SimpleJdbcOperation(DataSource dataSource) { this.dataSource dataSource; } /** * 添加一本书 */ public void addBook() { Connection connection null; PreparedStatement stmt null; try { //获取数据库连接 connection dataSource.getConnection(); //创建语句 stmt connection.prepareStatement( insert into soft_bookrack (book_name, book_author, book_isbn) values (?,?,?); ); //参数绑定 stmt.setString(1, Spring in Action); stmt.setString(2, Craig Walls); stmt.setString(3, 9787115417305); //执行语句 stmt.execute(); } catch (SQLException e) { //处理异常信息 } finally { //清理资源 try { if (stmt ! null) { stmt.close(); } if (connection ! null) { connection.close(); } } catch (SQLException e) { // } } } /** * 更新一本书 */ public void updateBook() { Connection connection null; PreparedStatement stmt null; try { //获取数据库连接 connection dataSource.getConnection(); //创建语句 stmt connection.prepareStatement( update soft_bookrack set book_author? where book_isbn?; ); //参数绑定 stmt.setString(1, 张卫滨); stmt.setString(2, 9787115417305); //执行语句 stmt.execute(); } catch (SQLException e) { //处理异常信息 } finally { //清理资源 try { if (stmt ! null) { stmt.close(); } if (connection ! null) { connection.close(); } } catch (SQLException e) { // } } } /** * 查询一本书 */ public void queryBook() { Connection connection null; PreparedStatement stmt null; ResultSet rs null; Book book null; try { //获取数据库连接 connection dataSource.getConnection(); //创建语句 stmt connection.prepareStatement( select book_name, book_author, book_isbn from soft_bookrack where book_isbn ? ); //参数绑定 stmt.setString(1, 9787115417305); //执行语句 rs stmt.executeQuery(); if (rs.next()) { book new Book(); book.setName(rs.getString(book_name)); book.setAuthor(rs.getString(book_author)); book.setIsbn(rs.getString(book_isbn)); } System.out.println(book); } catch (SQLException e) { //处理异常信息 } finally { //清理资源 try { if (rs ! null) { rs.close(); } if (stmt ! null) { stmt.close(); } if (connection ! null) { connection.close(); } } catch (SQLException e) { // } } } public static class Book { private String name; private String author; private String isbn; //省略 setter getter 方法 } } 从上述代码和操作流程可以看出对于 JDBC 来说整个操作非常的繁琐我们不但要拼接每一个参数而且还要按照模板代码的方式一步步的操作数据库并且在每次操作完还要手动关闭连接等而所有的这些操作步骤都需要在每个方法中重复书写。于是我们就想那有没有一种方法可以更简单、更方便的操作数据库呢 答案是肯定的这就是我们要学习 MyBatis 的真正原因它可以帮助我们更方便、更快速的操作数据库。 三、怎么学MyBatis MyBatis 学习只分为两部分 配置 MyBatis 开发环境 使用 MyBatis 模式和语法操作数据库。 四、第一个MyBatis查询 开始搭建 MyBatis 之前我们先来看一下 MyBatis 在整个框架中的定位框架交互流程图 MyBatis 也是一个 ORM 框架 ORM Object 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 utf8; -- 使用数据数据 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 ); -- 创建文章表 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 ); -- 创建视频表 drop table if exists videoinfo; create table videoinfo( vid int primary key, title varchar(250), url varchar(1000), createtime datetime default now(), updatetime datetime default now(), uid int ); -- 添加一个用户信息 INSERT INTO mycnblog.userinfo (id, username, password, photo, createtime, updatetime, state) VALUES (1, admin, admin, , 2021-12-06 17:10:48, 2021-12-06 17:10:48, 1); -- 文章添加测试数据 insert into articleinfo(title,content,uid) values(Java,Java正文,1); -- 添加视频 insert into videoinfo(vid,title,url,uid) values(1,java title,http://www.baidu.com,1); 4.2 添加MyBatis框架支持 添加 MyBatis 框架支持分为两种情况一种情况是对自己之前的 Spring 项目进行升级另一种情况是创建一个全新的 MyBatis 和 Spring Boot 的项目下面我们分别来演示这两种情况的具体实现。 4.2.1 老项目添加MyBatis 如果是在老项目中新增功能添加框架支持 !-- 添加 MyBatis 框架 -- dependency groupIdorg.mybatis.spring.boot/groupId artifactIdmybatis-spring-boot-starter/artifactId version2.1.4/version /dependency !-- 添加 MySQL 驱动 -- dependency groupIdmysql/groupId artifactIdmysql-connector-java/artifactId scoperuntime/scope /dependency 添加了 MyBatis 之后为什么还需要添加 MySQL 驱动呢 MyBatis 就像一个平台类似京东而数据库相当于商家有很多种不止有 MySQL 还有 SQL Server 、 DB2 等等 ..... 因此这两个都是需要添加的。 扩展在老项目中快速添加框架跟简单的操作方式是使用 EditStarters 插件 EditStarters 插件的使用方法  搜索“MyBatis”添加即可 4.2.2 新项目添加MyBatis 如果是新项目创建 Spring Boot 项目的时候添加引用就可以了如下图所示 4.3 配置连接字符串和MyBatis 此步骤需要进行两项设置数据库连接字符串设置和 MyBatis 的 XML 文件配置。 4.3.1 配置连接字符串 如果是 application.yml 添加如下内容 # 数据库连接配置 spring: datasource: url: jdbc:mysql://localhost:3306/mycnblog?characterEncodingutf8useSSLfalse username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver 注意事项 如果使用 MySQL 是 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 添加实体类 先添加用户的实体类 import lombok.Data; import java.util.Date; Data public class User { private Integer id; private String username; private String password; private String photo; private Date createTime; private Date updateTime; } 4.4.2 添加 mapper 接口 数据持久层的接口定义 import org.apache.ibatis.annotations.Mapper; import java.util.List; Mapper public interface UserMapper { public ListUser getAll(); } 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.demo.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.demo.mapper.UserMapper select idgetAll resultTypecom.example.demo.model.User select * from userinfo /select /mapper 以下是对以上标签的说明 1. mapper 标签需要指定 namespace 属性表示命名空间值为 mapper 接口的全限定名包括全包名 . 类名。 2. select查询标签是用来执行数据库的查询操作的 id是和 Interface接口中定义的方法名称一样的表示对接口的具体实现方法。 resultType是返回的数据类型也就是开头我们定义的实体类。 4.4.4 添加 Service 服务层实现代码如下 import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; Service public class UserService { Resource private UserMapper userMapper; public ListUser getAll() { return userMapper.getAll(); } } 4.4.5 添加 Controller 控制器层的实现代码如下 import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; RestController RequestMapping(/u) public class UserController { Resource private UserService userService; RequestMapping(/getall) public ListUser getAll(){ return userService.getAll(); } } 以上代码写完整个 MyBatis 的查询功能就实现完了接下来使用 postman 来测试一下。 4.4.6 使用 postman 测试 五、增、删、改操作 接下来我们来实现一下用户的增加、删除和修改的操作对应使用 MyBatis 的标签如下 标签插入语句 标签修改语句 标签删除语句 具体实现如下。 5.1 增加用户操作 controller 实现代码 RequestMapping(value /add,method RequestMethod.POST) public Integer add(RequestBody User user){ return userService.getAdd(user); } mapper interface Integer add(User user); mapper.xml insert idadd insert into userinfo(username,password,photo,state) values(#{username},#{password},#{photo},1) /insert Postman 添加访问 默认情况下返回的是受影响的行数如上图所示用到的 json 数据如下 {username:mysql,password:mysql,photo:img.png} 特殊的添加返回自增 id 默认情况下返回的是受影响的行号如果想要返回自增 id 具体实现如下。 controller 实现代码 RequestMapping(value /add2, method RequestMethod.POST) public Integer add2(RequestBody User user) { userService.getAdd2(user); return user.getId(); } mapper 接口 Mapper public interface UserMapper { // 添加返回自增id void add2(User user); } mapper.xml 实现如下 !-- 返回自增id -- insert idadd2 useGeneratedKeystrue keyPropertyid insert into userinfo(username,password,photo,state) values(#{username},#{password},#{photo},1) /insert useGeneratedKeys这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键比如像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段默认值false。 keyColumn设置生成键值在表中的列名在某些数据库像 PostgreSQL中当主键列不是表中的第一列的时候是必须设置的。如果生成列不止一个可以用逗号分隔多个属性名称。 keyProperty指定能够唯一识别对象的属性MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值默认值未设置unset。如果生成列不止一个可以用逗号分隔多个属性名称。 postman 返回结果 5.2 修改用户操作 controller /** * 修改操作 * * param id * param name * return */ RequestMapping(/update) public Integer update(Integer id, String name) { return userService.update(id, name); } mapper.xml 实现代码 update idupdate update userinfo set username#{name} where id#{id} /update 5.3 删除用户操作 delete iddelById parameterTypejava.lang.Integer delete from userinfo where id#{id} /delete 六、查询操作 6.1 单表查询 下面我们来实现一下根据用户 id 查询用户信息的功能。 Controller 实现代码如下 RequestMapping(/getuser) public User getUserById(Integer id) { return userService.getUserById(id); } Mapper.xml 实现代码如下 select idgetUserById resultTypecom.example.demo.model.User select * from userinfo where id#{id} /select 6.1.1 参数占位符 #{} 和 ${} #{}预编译处理。 ${}字符直接替换。 预编译处理是指MyBatis 在处理#{}时会将 SQL 中的 #{} 替换为?号使用 PreparedStatement 的 set 方法来赋值。直接替换是 MyBatis 在处理 ${} 时就是把 ${} 替换成变量的值。 预编译处理和字符串替换的区别故事头等舱和经济舱乘机分离的故事 在坐飞机的时候头等舱和经济舱的区别是很大的如下图所示 一般航空公司乘机都是头等舱和经济舱分离的头等舱的人先登机登机完之后封闭经济舱然后再让经济舱的乘客登机这样的好处是可以避免浑水摸鱼经济舱的人混到头等舱的情况这就相当于预处理可以解决程序中不安全越权处理的问题。 而直接替换的情况相当于头等舱和经济舱不分离的情况这样经济舱的乘客在通过安检之后可能越权摸到头等舱如下图所示 这就相当于参数直接替换它的问题是可能会带来越权查询和操作数据等问题比如后面的 SQL 注入问题。 6.1.2 ${} 优点 select idgetAllBySort parameterTypejava.lang.String resultTypecom.example.demo.model.User select * from userinfo order by id ${sort} /select 使用 ${sort} 可以实现排序查询而使用 #{sort} 就不能实现排序查询了因为当使用 #{sort} 查询时如果传递的值为 String 则会加单引号就会导致 sql 错误。 6.1.3 SQL 注入问题 select idisLogin resultTypecom.example.demo.model.User select * from userinfo where username${name} and password${pwd} /select sql 注入代码 “ or 11” 结论用于查询的字段尽量使用 #{} 预查询的方式。 6.1.4 like 查询 like 使用 #{} 报错 select idfindUserByName2 resultTypecom.example.demo.model.User select * from userinfo where username like %#{username}%; /select 相当于 select * from userinfo where username like %username%; 这个是不能直接使用 ${} 可以考虑使用 mysql 的内置函数 concat() 来处理实现代码如下 select idfindUserByName3 resultTypecom.example.demo.model.User select * from userinfo where username like concat(%,#{username},%); /select 6.2 多表查询 如果是增、删、改返回搜影响的行数那么在 mapper.xml 中是可以不设置返回的类型的如下图所示 然而即使是最简单查询用户的名称也要设置返回的类型否则会出现如下错误。 查询不设置返回类型的错误示例演示 controller 代码 RequestMapping(/getname) public String getNameById(Integer id) { return userService.getNameById(id); } mapper.xml 实现代码 select idgetNameById select username from userinfo where id#{id} /select 访问接口执行结果如下 显示运行了一个查询但没有找到结果映射也就是说对于它的优点是使用方便直接定义到某个实体类即可。 6.2.2 返回字典映射resultMap resultMap 使用场景 字段名称和程序中的属性名不同的情况可使用 resultMap 配置映射 一对一和一对多关系可以使用 resultMap 映射并查询数据。 字段名和属性名不同的情况   程序中的属性如下  mapper.xml 代码如下 select idgetUserById resultTypecom.example.demo.model.User select * from userinfo where id#{id} /select  查询的结果如下 这个时候就可以使用 resultMap 了resultMap 的使用如下 mapper.xml resultMap idBaseMap typecom.example.demo.model.User id columnid propertyid/id result columnusername propertyusername/result result columnpassword propertypwd/result /resultMap select idgetUserById resultMapcom.example.demo.mapper.UserMapper.BaseMap select * from userinfo where id#{id} /select  查询的结果就有值了如下图所示 6.2.3 多表查询 6.2.3.1 一对一的表映射 一对一映射要使用 标签具体实现如下一篇文章只对应一个作者 resultMap idBaseMap typecom.example.demo.model.ArticleInfo id propertyid columnid/id result propertytitle columntitle/result result propertycontent columncontent/result result propertycreatetime columncreatetime/result result propertyupdatetime columnupdatetime/result result propertyuid columnuid/result result propertyrcount columnrcount/result result propertystate columnstate/result association propertyuser resultMapcom.example.demo.mapper.UserMapper.BaseMap columnPrefixu_ /association /resultMap select idgetAll resultMapBaseMap select a.*,u.username u_username from articleinfo a left join userinfo u on a.uidu.id /select 以上使用 标签表示一对一的结果映射 property 属性指定 Article 中对应的属性即用户。 resultMap 属性指定关联的结果集映射将基于该映射配置来组织用户数据。 columnPrefix 属性绑定一对一对象时是通过 columnPrefixassociation.resultMap.column 来映射结果集字段。association.resultMap.column是指 标签中 resultMap属性对应的结果集映射中column字段。 注意事项column不能省略 articleinfo import java.time.LocalDateTime; Data public class ArticleInfo { private Integer id; private String title; private String content; private LocalDateTime createtime; private LocalDateTime updatetime; private Integer rcount; private User user; } ArticleController import com.example.demo.model.ArticleInfo; import com.example.demo.service.ArticleService; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.annotation.Resource; import java.util.List; RequestMapping(/a) RestController public class ArticleController { Resource private ArticleService articleService; RequestMapping(/getall) public ListArticleInfo getAll() { return articleService.getAll(); } } columnPrefix 如果省略并且恰好两个表中如果有相同的字段那么就会导致查询出错示例如下 resultMap idBaseMap typecom.example.demo.model.ArticleInfo id propertyid columnid/id result propertytitle columntitle/result result propertycontent columncontent/result result propertycreatetime columncreatetime/result result propertyupdatetime columnupdatetime/result result propertyuid columnuid/result result propertyrcount columnrcount/result result propertystate columnstate/result association propertyuser resultMapcom.example.demo.mapper.UserMapper.BaseMap /association /resultMap select idgetAll resultMapBaseMap select a.*,u.id from articleinfo a left join userinfo u on a.uidu.id /select service import com.example.demo.mapper.ArticleMapper; import com.example.demo.model.ArticleInfo; import org.springframework.stereotype.Service; import javax.annotation.Resource; import java.util.List; Service public class ArticleService { Resource private ArticleMapper articleMapper; public ListArticleInfo getAll() { return articleMapper.getAll(); } } Mapper import com.example.demo.model.ArticleInfo; import org.apache.ibatis.annotations.Mapper; import java.util.List; Mapper public interface ArticleMapper { ListArticleInfo getAll(); } mapper.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.demo.mapper.ArticleMapper resultMap idBaseMap typecom.example.demo.model.ArticleInfo id columnid propertyid/id result columntitle propertytitle/result result columncontent propertycontent/result association propertyuser resultMapcom.example.demo.mapper.UserMapper.BaseMap /association /resultMap select idgetAll resultMapBaseMap select a.*,u.* from articleinfo a left join userinfo u on u.ida.uid /select /mapper userinfo 表中有 id 字段 articleinfo 中也有一个 id 字段会导致查询出错结果如下   两篇文章都是 uid1 的作者写的但这块显示的 user id 有两个查询出错了。 正确的做法是添加 columnPrefix 实现代码如下 resultMap idBaseMap typecom.example.demo.model.ArticleInfo id columnid propertyid/id result columntitle propertytitle/result result columncontent propertycontent/result association propertyuser resultMapcom.example.demo.mapper.UserMapper.BaseMap columnPrefixu_ /association /resultMap 执行结果如下 6.2.3.2 一对多一个用户多篇文章案例   一对多需要使用 标签用法和 相同如下所示 resultMap idBaseMap typecom.example.demo.model.User id columnid propertyid / result columnusername propertyusername/result result columnpassword propertypassword/result result columnphoto propertyphoto/result collection propertyalist resultMapcom.example.demo.mapper.ArticleInfoMapper.BaseMap columnPrefixa_ /collection /resultMap select idgetUserById resultMapBaseMap select u.*,a.title a_title from userinfo u left join articleinfo a on u.ida.uid where u.id#{id} /select 七、复杂情况动态SQL使用 动态 sql 是 Mybatis 的强大特性之一能够完成不同条件下不同的 sql 拼接。 可以参考官方文档 Mybatis 动态 sql 7.1 if标签 在注册用户的时候可能会有这样一个问题如下图所示 注册分为两种字段必填字段和非必填字段那如果在添加用户的时候有不确定的字段传入程序应该如何实现呢 这个时候就需要使用动态标签来判断了比如添加的时候性别 sex 为非必填字段具体实现如下 insert idinsert parameterTypeorg.example.model.User useGeneratedKeystrue keyPropertyid insert into user( username, password, nickname, if testsex ! null sex, /if birthday, head ) values ( #{username}, #{password}, #{nickname}, if testsex ! null #{sex}, /if #{birthday}, #{head} ) /insert 注意 test 中的 sex 是传入对象中的属性不是数据库字段。 7.2 trim标签 之前的插入用户功能只是有一个 sex 字段可能是选填项如果有多个字段一般考虑使用标签结合标签对多个字段都采取动态生成的方式。 标签中有如下属性 prefix表示整个语句块以prefix的值作为前缀 suffix表示整个语句块以suffix的值作为后缀 prefixOverrides表示整个语句块要去除掉的前缀 suffixOverrides表示整个语句块要去除掉的后缀  调整 UserMapper.xml 的插入语句为 insert idinsert parameterTypeorg.example.model.User useGeneratedKeystrue keyPropertyid insert into user trim prefix( suffix) suffixOverrides, if testusername ! null username, /if if testpassword ! null password, /if if testnickname ! null nickname, /if if testsex ! null sex, /if if testbirthday ! null birthday, /if if testhead ! null head, /if if testcreateTime ! null create_time, /if /trim trim prefixvalues ( suffix) suffixOverrides, if testusername ! null #{username}, /if if testpassword ! null #{password}, /if if testnickname ! null #{nickname}, /if if testsex ! null #{sex}, /if if testbirthday ! null #{birthday}, /if if testhead ! null #{head}, /if if testcreateTime ! null #{createTime}, /if /trim /insert 在以上 sql 动态解析时会将第一个 部分做如下处理 基于 prefix 配置开始部分加上 ( 基于 suffix 配置结束部分加上 ) 多个 组织的语句都以 , 结尾在最后拼接好的字符串还会以 , 结尾会基于 suffixOverrides 配置去掉最后一个 , 注意 if test“createTime ! null” 中的 createTime 是传入对象的属性 7.3 where标签 传入的用户对象根据属性做 where 条件查询用户对象中属性不为 null 的都为查询条件。如 user.username 为 a 则查询条件为 where usernamea UserMapper 接口中新增条件查询方法 ListUser selectByCondition(User user); UserMapper.xml 中新增条件查询 sql select idselectByCondition parameterTypeorg.example.model.User resultMapBaseResultMap select id, username, password, nickname, sex, birthday, head, create_time from user where if testusername ! null and username#{username} /if if testpassword ! null and password#{password} /if if testnickname ! null and nickname#{nickname} /if if testsex ! null and sex#{sex} /if if testbirthday ! null and birthday#{birthday} /if if testhead ! null and head#{head} /if if testcreateTime ! null and create_time#{createTime} /if /where /select 以上标签也可以使用 trim prefixwhere prefixOverridesand 替换。 7.4 set标签 根据传入的用户对象属性来更新用户数据可以使用标签来指定动态内容。 UserMapper 接口中修改用户方法根据传入的用户 id 属性修改其他不为 null 的属性 int updateById(User user); UserMapper.xml 中添加更新用户 sql update idupdateById parameterTypeorg.example.model.User update user set if testusername ! null username#{username}, /if if testpassword ! null password#{password}, /if if testnickname ! null nickname#{nickname}, /if if testsex ! null sex#{sex}, /if if testbirthday ! null birthday#{birthday}, /if if testhead ! null head#{head}, /if if testcreateTime ! null create_time#{createTime}, /if /set where id#{id} /update 以上标签也可以使用 trim prefixset suffixOverrides, 替换。 7.4 foreach标签 对集合进行遍历时可以使用该标签。标签有如下属性 collection绑定方法参数中的集合如 ListSetMap或数组对象 item遍历时的每一个对象 open语句块开头的字符串 close语句块结束的字符串 separator每次遍历之间间隔的字符串 示例根据多个文章 id 来删除文章数据。 ArticleMapper 中新增接口方法 int deleteByIds(ListInteger ids); ArticleMapper.xml 中新增删除 sql delete iddeleteByIdsdelete from articlewhere id inforeach collectionlist itemitem open( close) separator,#{item}/foreach /delete

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/88676.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

苏宁易购网页布局设计搜索引擎优化岗位

文章目录 1 桥接模式(Bridge Pattern)1.1 介绍1.2 概述1.3 桥接模式的结构 2 案例一2.1 需求2.2 代码实现 3 案例二2.1 需求2.1 代码实现 🙊 前言:本文章为瑞_系列专栏之《23种设计模式》的桥接模式篇。本文中的部分图和概念等资料…

做网站盐城哈尔滨高端模板建站

文章目录 前言一、qnx 上的窗口系统——screen二、screen + egl + opengles 最简实例1.使用 addvariant 命令创建工程目录2. 添加源码文件3. common.mk 文件4. 编译与执行总结参考资料前言 本文主要介绍如何在QNX 系统上使用egl和opengles 控制GPU渲染一个三角形并显示到屏幕上…

网站建设问题及对策新手做网站应该注意什么

本文首先对该系统进行了详细地描述,然后对该系统进行了详细的描述。管理人员增加了系统首页、个人中心、用户管理、景点分类管理、景点简介管理、旅游路线管理、文章分类管理、公告文章管理、系统管理理等功能。这套黄河风景线旅游网站是根据当前的现实需要&#xf…

学术会议网站建设百色建设厅网站

实验配置 eNSP 什么是二层交换 二层交换是指在同一个ip网段内,数据通过二层交换机进行转发。 什么是mac地址 mac地址也叫做硬件地址,是以太网协议的链路层地址。简单的来说,mac地址就是我们硬件的身份证,独一无二。它是由48个bi…

做书籍封皮的网站国际网站平台

文章目录 一、模型的处理二、TDR仿真2.1 修改求解模式2.2增加求解设置 三、查看仿真结果3.1 查看TDR结果3.2 查看S参数结果 四、结果分析4.1上升时间tr对仿真的影响 附:工程链接 在上一讲中,主要是通过观察S参数确定via的优化是否达到目标。但S参数只能看…

电视盒子做网站服务器深圳社保网上服务平台

一、HMM中的第三个基本问题 参数估计问题:给定一个观察序列OO1O2…OT,如何调节模型μ(A,B,π)的参数,使得P(O|μ)最大化: argmaxμP(Otraining|μ)arg \max_{\mu} P(O_{training}|\mu)模型的参数是指构成μ的πi,aij,bj(k)。本文…

wordpress 网站费用怎么做淘宝卷网站

随着技术的发展,人工智能的时代离我们越来越近,在人工智能的影响下许多传统行业开始向智能化方向转型,其中最明显的就是电话营销方面的工作。为了减轻人工销售负担出现了一个电销机器人系统,每天能拨打3000通电话,最高…

织梦可以做论坛网站吗自己制作的网站

freemodbus的官方介绍和下载入口,官方仓库链接:https://github.com/cwalter-at/freemodbus modbus自己实现的话往往是有选择的支持几条指令,像断帧和异常处理可能是完全不处理的,用freemodbus实现的话要简单很多,可移植…

网站运营维护合同商务网站建设与维护 ppt

什么是SLAM? SLAM,即同时定位与地图构建技术,SLAM可以让机器人、无人机和其他自动化系统能够在未知环境中同时进行自我定位和环境映射。 为什么是NeRF-Based SLAM? 传统CG将输入图像重新投影再融合到新的视图摄像机中&#xff0c…

网站服务器如何搭建基于构件的软件开发流程

特点 1.只有append操作2.支持子切片3.内存共享问题 1.只有append操作 不支持随机增删 2.支持子切片 数组和切片都可以通过[start:end] 的形式 来获取子切片: 1.arr[start:end],获得[start,end)之间的元素。 2.arr[:end],获得[0,end)之间的元素。 3.arr[start:],获得[start,l…

平面设计手绘网站中国字幕组回怼韩国媒体

我有魔法✨为你劈开信息大海❗ 高效获取AIGC的热门事件🔥,更新AIGC的最新动态,生成相应的魔法简报,节省阅读时间👻 🔥资讯预览 YaRN方法:无需微调,高效扩展语言模型上下文窗口 蚂蚁…

河南和城乡建设厅网站内装设计

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1.使用__slots__2. property3.多重继承 4.定制类5.枚举类6.错误处理7.调试8. 文档测试9.单元测试10. 文件读写11. StringIO和BytesIO12. 操作文件和目录13.序列化14…

有好看图片的软件网站模板下载百度搜索提交入口

2024.4.8 题目来源我的题解方法一 去重排序滑动窗口 题目来源 力扣每日一题;题序:2009 我的题解 方法一 去重排序滑动窗口 参考官方题解。 记数组 nums的长度为 n。经过若干次操作后,若数组变为连续的,那么数组的长度不会改变&…

网站做多久能盈利WordPress单栏二次元主题

希望和各位大佬一起学习,如果文章内容有错请多多指正,谢谢! 个人博客链接:CH4SER的个人BLOG – Welcome To Ch4sers Blog DC-1 靶机下载地址:DC: 1 ~ VulnHub 0x01 信息收集 Nmap扫描目标主机,发现开…

做编程的 网站有哪些凡客软件

该课程全面解析数据产品和人工智能产品的开发与设计。学员将学习产品规划、数据分析以及AI技术应用,通过案例实践掌握产品开发流程,致力于帮助他们成功进入数据和人工智能产品领域。 课程大小:9.8G 课程下载:https://download.cs…

非凡网站建设 新三板网页模版设计

一、使用Executors创建线程池之前创建线程的时候都是用的Executors的newFixedThreadPool(),newSingleThreadExecutor(),newCachedThreadPool()这三个方法。当然Executors也是用不同的参数去new ThreadPoolExecutor1. newFixedThreadPool()创建线程数固定大小的线程池。 由于使用…

专做网站做男女之间的事情的网站

VLOOKUP函数是Excel中的一个纵向查找函数,它与LOOKUP函数和HLOOKUP函数属于一类函数,在工作中都有广泛应用,例如可以用来核对数据,多个表格之间快速导入数据等函数功能。功能是按列查找,最终返回该列所需查询列序所对应…

企业企业网站建公司营销网站建设

文章目录 5.6 有哪些池化方法 5.7 1x1卷积作用 5.8 卷积层和池化层有什么区别 5.9 卷积核是否一定越大越好 5.10 每层卷积是否只能用一种尺寸的卷积核 5.11 怎样才能减少卷积层参数量 5.12 在进行卷积操作时,必须同时考虑通道和区域吗 5.13 采用宽卷积的好处有什么 …

奎屯市住房和城乡建设局网站浠水网站建设

1、进入sql环境 》》》mysql -u root -p 》》》输入密码 2、sql语言的分类 3、注意事项: 4、基础操作: (1)查询所有数据库: show databases; 运行结果: (2)创建一个新的数据库&…

网站首页空白 wordpress网店网站怎么做的

题目 输入URL按下回车后,中间发生了什么 这个问题其实是计算机网络里面很经典的一个问题,不能去死机硬背,很考察对网络架构和通信原理的理解,也是各个互联网大厂喜欢考察的面试题。 一些图片参考了小林的计算机网络面经 从输入…