近期舆情热点事件,佛山市seo网站设计工具,wordpress好用的模板,广州海珠区房价多少钱一平方目录
【K】Mybatis使用Select注解书写简单sql
【K】MySQL 数据类型与 Java 类型的对应关系
【K】Mybatis相同代码复用
1. 定义公共 SQL 片段
2. 引用公共 SQL 片段
3. 使用参数
4. 复用和组合
5. 注意事项
【K】mysql如何实现插入一条数据后立刻获取该数据自增长id进行…目录
【K】Mybatis使用Select注解书写简单sql
【K】MySQL 数据类型与 Java 类型的对应关系
【K】Mybatis相同代码复用
1. 定义公共 SQL 片段
2. 引用公共 SQL 片段
3. 使用参数
4. 复用和组合
5. 注意事项
【K】mysql如何实现插入一条数据后立刻获取该数据自增长id进行调用
背景解析
代码使用
【K】Mybatis新增数据存在就更新不存在就添加
常规方法
Replace关键字
【K】MyBatis执行多个sql语句
背景
代码举例
实例举例
分析总结
【K】Mybatis 不同条件拼接不同sql
举例1
举例2: 判断某一个值
举例3
【K】-IFNULL处理N/A
背景知识
SQL语句分析
改进后的SQL语句
知识扩展
注意事项
【K】Mybatis条件查询where标签
【K】使用resultMap封装对象一对多
数据库模型
实体类
MyBatis 配置
举例
【K】Mybatis使用常见类型的类型别名 【K】Mybatis使用Select注解书写简单sql
//1. 基本查询
Select(SELECT * FROM users WHERE id #{id})
User selectUserById(int id);//2. 动态查询
Select(script SELECT * FROM users if testid ! null WHERE id #{id} /if /script)
ListUser selectUsersById(Param(id) Integer id);//3. 返回 Map
Select(SELECT * FROM users)
MapKey(id)
MapInteger, User selectUsersAsMap();//4. 使用注解参数
Select(SELECT * FROM ${tableName})
ListUser selectUsersFromTable(Param(tableName) String tableName);//5. 结果映射
Select(SELECT id, name, email FROM users WHERE id #{id})
Results({Result(property id, column id),Result(property name, column name),Result(property email, column email)
})
User selectUserDetailedById(int id);//6. 联合查询
Select(SELECT u.id, u.name, a.city FROM users u INNER JOIN address a ON u.id a.user_id WHERE u.id #{id})
User selectUserWithAddress(int id);//7. 分页查询
Select(SELECT * FROM users LIMIT #{limit} OFFSET #{offset})
ListUser selectUsersByPage(Param(limit) int limit, Param(offset) int offset);
【K】MySQL 数据类型与 Java 类型的对应关系
在 MyBatis 中Java 类型和 MySQL 数据库类型之间的映射是通过 typeHandlers 来实现的。以下是一些常见的 MySQL 数据类型与 Java 类型的对应关系以及在 MyBatis 的 XML 配置文件中如何配置它们的示例。
MySQL 数据类型Java 类型MyBatis XML 配置中的类型别名CHARStringVARCHARVARCHARStringVARCHARBLOBbyte[]BLOBTEXTStringVARCHARINTEGERint/IntegerINTEGERTINYINTbyte/ByteTINYINTSMALLINTshort/ShortSMALLINTMEDIUMINTint/IntegerINTEGERBIGINTlong/LongBIGINTFLOATfloat/FloatFLOATDOUBLEdouble/DoubleDOUBLEDECIMALjava.math.BigDecimalDECIMALDATEjava.sql.DateDATETIMEjava.sql.TimeTIMEDATETIMEjava.sql.TimestampTIMESTAMPTIMESTAMPjava.sql.TimestampTIMESTAMPBOOLEANboolean/BooleanBOOLEANENUMStringVARCHARSETStringVARCHAR
在 MyBatis 的配置文件 mybatis-config.xml 中你不需要为每种类型映射都显式定义 typeHandler因为 MyBatis 已经内置了对这些常见类型的处理。但如果你需要自定义类型处理器你可以这样配置
typeHandlerstypeHandler handlercom.example.MyCustomTypeHandler/
/typeHandlers
以下是一个包含所有类型映射的 MyBatis 映射文件 (UserMapper.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.mapper.UserMapperresultMap idUserResultMap typeUserresult propertyid columnid javaTypeint jdbcTypeINTEGER /result propertyusername columnusername javaTypeString jdbcTypeVARCHAR /result propertypassword columnpassword javaTypeString jdbcTypeVARCHAR /result propertyemail columnemail javaTypeString jdbcTypeVARCHAR /result propertyprofilePhoto columnprofile_photo javaTypebyte[] jdbcTypeBLOB /result propertyage columnage javaTypeInteger jdbcTypeTINYINT /result propertybalance columnbalance javaTypejava.math.BigDecimal jdbcTypeDECIMAL /result propertybirthDate columnbirth_date javaTypejava.sql.Date jdbcTypeDATE /result propertyloginTime columnlogin_time javaTypejava.sql.Timestamp jdbcTypeTIMESTAMP /result propertyisActive columnis_active javaTypeBoolean jdbcTypeBOOLEAN //resultMapselect idselectUsers resultMapUserResultMapSELECT * FROM users/select!-- Other CRUD operations go here --/mapper
在这个示例中resultMap 定义了如何将数据库表 users 中的列映射到 Java 类 User 的属性上。每个 result 元素指定了一个属性到列的映射包括 Java 类型 (javaType) 和 JDBC 类型 (jdbcType)。
请注意实际开发中可能不需要为每个字段都显式指定 jdbcType因为 MyBatis 通常能够推断出对应的类型。但在某些情况下特别是当 MyBatis 无法准确推断类型时例如对于 null 值指定 jdbcType 可以避免类型相关的错误。
【K】Mybatis相同代码复用
在 MyBatis 中为了避免重复编写相同的 SQL 片段可以使用 sql 元素定义可重用的 SQL 代码块并通过 include 元素在需要的地方引入这些代码块。这种方式提高了代码的可维护性和可读性。以下是如何使用这些元素来提取和复用相同的代码段的总结
1. 定义公共 SQL 片段 使用 sql 标签定义公共的 SQL 片段并为其指定一个唯一的 id。这个 id 将在后续的 include 标签中被引用。 sql idcommon_sql_whereif testid ! nullAND id #{id}/if!-- 可以继续添加其他公共条件 --/sql
2. 引用公共 SQL 片段 在实际的查询语句中使用 include 标签引入公共 SQL 片段。通过 refid 属性指定需要引入的公共 SQL 片段的 id。 select idselectWithCommonWhere resultTypeYourResultTypeSELECT * FROM your_table WHERE 11include refidcommon_sql_where//select
3. 使用参数 在公共 SQL 片段中可以使用 MyBatis 的参数占位符 #{} 来引用传入的参数。确保传入的参数名称与 if 测试条件中的参数名称相匹配。
4. 复用和组合 可以将多个 sql 片段组合在一起使用多个 include 标签来构建复杂的查询条件。 select idselectAdvanced resultTypeYourResultTypeSELECT * FROM your_tableWHERE 11include refidcommon_sql_where/!-- 可以继续引入其他公共 SQL 片段 --/select
5. 注意事项 - 确保 include 标签中的 refid 正确无误地指向了预定义的 sql 片段的 id。 - 在 sql 片段中定义的条件必须符合 SQL 语法特别是在使用 if 条件时要注意不要遗漏必要的 SQL 关键字比如 AND。 - 当在 sql 片段中使用动态 SQL如 if时要注意条件的逻辑组合以避免生成无效的 SQL。
通过这种方式可以有效地管理和复用 SQL 代码减少冗余并使得 SQL 语句的维护变得更加简单。
【K】mysql如何实现插入一条数据后立刻获取该数据自增长id进行调用
背景解析
useGeneratedKeys 取值范围true|false 默认值是false。
含义设置是否使用JDBC的.getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。
代码使用 insert idinsert parameterTypecom.hy.common.entity.UseruseGeneratedKeystrue keyPropertyidinsert into user (name, age)values ( #{name,jdbcTypeVARCHAR}, #{age,jdbcTypeINTEGER})/insert OverrideTransactional(readOnly false)public int insertUser() {User user new User();user.setName(why);user.setAge(18);int count userMapper.insert(user);System.out.println(count); // 插入的条数:1int id user.getId(); System.out.println(id); // 自增的id:666return id;}
【K】Mybatis新增数据存在就更新不存在就添加
常规方法
先查询是否存在存在就更新不存在就添加.
如果数据量过大, 使用foreach批量操作
举例: 集合唯一索引 id
可以查询所有的id集合idSet, 使用in idSet查询那些存在, 返回结果集oldSet.
然后遍历判断idSet是否存在oldSet, 存在走更新逻辑不存在走添加逻辑.
Replace关键字
REPLACE关键字的使用 使用REPLACE的最大好处就是可以将DELETE和INSERT合二为一形成一个原子操作。这样就可以不必考虑在同时使用DELETE和INSERT时添加事务等复杂操作了。 在使用REPLACE时表中必须有唯一索引而且这个索引所在的字段不能允许空值否则REPLACE就和INSERT完全一样的。 在执行REPLACE后系统返回了所影响的行数如果返回1说明没有重复的记录如果返回2说明有重复记录系统先DELETE这条记录然后再INSERT这条记录。 语法和INSERT非常的相似如下面的REPLACE语句是插入或更新一条记录。
REPLACE INTO users (id,name,age) VALUES(1, 李嘉欣, 18);
【K】MyBatis执行多个sql语句
背景
驱动默认不开启支持多个sql执行。
在数据库连接的url增加参数allowMultiQueries值为true多个SQL直接一以“;”分隔即可xxx.jdbcUrljdbc:mysql://xx.xx.xx:3306/xxxxx?characterEncodingutf-8autoReconnecttruefailOverReadOnlyfalseallowMultiQueriestrueallowMultiQueriestrue
代码举例 select idgetUserAndOrders resultSetsuser,ordersselect * from user where id #{id};select * from orders where user_id #{id};
/select实例举例
场景删除用户的时候需要先删除用户的外键关联数据否则会触发规则报错。本人遇到的是循环拼接不同字段条件的修改sql执行。
直接写多条语句用“”隔开即可
delete iddeleteUserById parameterTypeStringdelete from sec_user_role where userId#{id};delete from sec_user where id#{id};
/delete
分析总结
执行多个SQL查询并返回多个结果集的原因简述
在某些业务场景中需要从不同的数据表中提取数据并组合成一个复合数据对象。执行多个查询并一次性返回所有结果集可以减少数据库IO操作提高性能。将相关查询逻辑集中到一个地方有助于提高代码的可读性和可维护性。
MyBatis执行多个查询并处理结果集的方法简述
MyBatis允许通过resultSets属性在一个select元素中执行多个查询并命名各个结果集。可以使用SqlSession的selectList或selectMap方法来获取这些结果集。结果集可以映射到不同的Java对象并可通过自定义resultMap进行详细配置。
总结
MyBatis支持一次执行多个SQL查询并返回多个结果集这有助于优化性能和提升代码质量。
【K】Mybatis 不同条件拼接不同sql
在MyBatis中可以使用动态SQL功能来根据不同的条件拼接不同的SQL语句。动态SQL是MyBatis的一大特色它允许在XML映射文件中构建灵活的SQL语句。主要通过if, choose, when, otherwise, where, set, foreach等元素来实现条件逻辑。
举例1
以下是一个使用MyBatis动态SQL的例子我们将创建一个根据不同条件来查询用户的例子。
首先定义一个User对象和一个UserMapper接口
// User.java
public class User {private Integer id;private String name;private String email;// getters and setters...
}// UserMapper.java
public interface UserMapper {ListUser findUsers(MapString, Object params);
}然后在MyBatis的XML映射文件中我们定义动态SQL查询
!-- UserMapper.xml --
mapper namespacecom.example.mapper.UserMapperselect idfindUsers resultTypecom.example.UserSELECT id, name, emailFROM userswhereif testid ! nullAND id #{id}/ifif testname ! nullAND name #{name}/ifif testemail ! nullAND email #{email}/if/where/select
/mapper在这个例子中where元素会智能地插入WHERE关键字并且只有当内部的条件成立时才会插入相应的条件语句并且会处理好条件语句前的AND或OR关键字。
现在当我们调用findUsers方法时可以传递一个包含id、name、email等键的Map对象。MyBatis会根据Map中的键值对是否存在来动态构建SQL语句。
// 使用MyBatis的SqlSession来执行查询
SqlSession sqlSession sqlSessionFactory.openSession();
try {UserMapper mapper sqlSession.getMapper(UserMapper.class);MapString, Object params new HashMap();params.put(name, John Doe);ListUser users mapper.findUsers(params);// 处理查询结果...
} finally {sqlSession.close();
}在上面的Java代码中我们创建了一个包含name键的Map并将其作为参数传递给findUsers方法。MyBatis会生成一个包含AND name John Doe条件的SQL语句因为Map中只有name键。
举例2: 判断某一个值
不同条件拼接不同sql
/whereORDER BY
if testname ! null and name ! and name 1.toString()dept DESC
/if
if testname ! null and name ! and name 2.toString()type DESC
/if
Postman访问 注意事项
前言
name代码为String
XML 代码为: if testname ! null and name ! and name 1.toString()
postman入参可以为name: 1,或name: 11需要加上单引号加单引号后为字符,类型为Charactor 举例3
某些特殊业务场景下的, 为了替换#{demoWay}的替换写法... if testdemoWay ! null and testdemoWay ! if testdemoWay equal ![CDATA[ and demo_str #{demoStr} ]] /ifif testdemoWay gt ![CDATA[ and demo_str #{demoStr} ]] /ifif testdemoWay lt ![CDATA[ and demo_str #{demoStr} ]] /ifif testdemoWay gte ![CDATA[ and demo_str #{demoStr} ]] /ifif testdemoWay lte ![CDATA[ and demo_str #{demoStr} ]] /if/if 这种动态SQL的方法使得SQL语句的构建非常灵活可以根据传入的参数不同构建不同的查询条件而不必编写多个几乎相同的查询语句。这样的设计既简化了代码也使得维护更加容易。
【K】-IFNULL处理N/A
背景知识
在数据库中有时需要生成具有特定格式的唯一ID。例如这里的ID由当前日期格式为yyyymmdd和一个顺序号四位数组成。每当需要添加新的记录时就要生成一个新的ID该ID比当天已有的最大ID大1。
SQL语句分析
原始的SQL语句试图获取当天最大的ID然后将其加1以生成新的ID。如果当天没有ID就默认使用0001作为顺序号。
公司表获取最大ID且加1:
ID示例:yyyymmdd0001SELECTIFNULL(RIGHT(ac.id 1, 4), 0001) numMax
FROMapp_company ac
WHERELEFT(ac.id, 8) DATE_FORMAT(now(), %Y%m%d)
ORDER BYRIGHT(ac.id, 4) DESC
LIMIT 1这个查询有几个问题
IFNULL函数不会处理非NULL的“无效”值如N/A。在没有任何记录的情况下RIGHT(ac.id 1, 4)将不会返回任何结果因此IFNULL将返回0001。使用ORDER BY和LIMIT来获取最大值效率较低。
改进后的SQL语句
改进后的SQL语句使用MAX函数来找出当天最大的ID然后通过IFNULL处理当天没有任何ID的情况。这样就不需要ORDER BY和LIMIT子句因为MAX函数已经能够找到最大的ID。
SELECTIFNULL(MAX(RIGHT(ac.id, 4)) 1, 0001) numMax
FROMapp_company ac
WHERELEFT(ac.id, 8) DATE_FORMAT(now(), %Y%m%d)知识扩展
IFNULL: MySQL中的IFNULL函数用来检查第一个表达式是否为NULL如果是就返回第二个参数的值。MAX: MAX函数返回一组值中的最大值如果集合为空则返回NULL。RIGHT: RIGHT函数从字符串的右侧返回指定数量的字符。LEFT: LEFT函数从字符串的左侧返回指定数量的字符。DATE_FORMAT: DATE_FORMAT函数用于格式化日期值。
注意事项
在实际使用中直接在数据库层面进行ID的生成可能会有并发问题特别是在高并发的环境下。为了确保ID的唯一性和顺序可能需要采用其他机制比如应用层的锁或者使用数据库的序列在MySQL 8.0中为AUTO_INCREMENT属性。
此外如果ac.id是字符型字段直接进行 1操作可能会导致错误因为字符型和数值型的操作不同。在这种情况下可能需要先将ID的顺序号部分转换为数值型进行加法操作后再转换回字符型。
【K】Mybatis条件查询where标签
MyBatis 的 where 标签用于动态生成 SQL 查询语句中的 WHERE 条件。该标签的主要作用是简化 SQL 编写并自动处理 WHERE 关键字和条件之间的逻辑关系如 AND 或 OR。当内部条件为空时它会智能地省略 WHERE 关键字而当有条件时则会自动加上 WHERE 关键字。这样可以避免在动态 SQL 中手动编写复杂的逻辑来判断是否需要添加 WHERE 关键字。 where 标签的基本规则 where 标签内部可以包含 if、choose、when、otherwise 等子标签。 如果 where 标签内部的条件都不成立则整个 where 标签不会生成任何内容。 如果 where 标签内部至少有一个条件成立则会自动在这些条件前添加 WHERE 关键字。 where 标签会自动处理条件之间的第一个 AND 或 OR 关键字。
示例
假设我们有一个 User 表包含 id、name、email 等字段现在我们要根据这些字段的不同组合来查询用户。
UserMapper 接口
public interface UserMapper {ListUser findUsers(MapString, Object params);
}UserMapper.xml 映射文件
mapper namespacecom.example.mapper.UserMapperselect idfindUsers resultTypecom.example.UserSELECT id, name, emailFROM Userwhereif testid ! nullid #{id}/ifif testname ! null and name ! AND name #{name}/ifif testemail ! null and email ! AND email #{email}/if/where/select
/mapper在上述例子中
如果 params 中没有任何一个键值对则 SQL 语句将是 SELECT id, name, email FROM User。 如果 params 中只有 name 键值对则 SQL 语句将是 SELECT id, name, email FROM User WHERE name 指定的name值。 如果 params 中有 name 和 email 键值对则 SQL 语句将是 SELECT id, name, email FROM User WHERE name 指定的name值 AND email 指定的email值。
这种方式确保了 WHERE 条件的灵活性和正确性同时避免了手动编写复杂的逻辑来控制 SQL 语句的准确性。使用 where 标签可以大大提高 SQL 语句的可维护性和可读性。
【K】使用resultMap封装对象一对多
在 MyBatis 中resultMap 是一个非常强大的映射工具它能够处理复杂的数据库关系如一对一、一对多和多对多的关系。通过正确使用 resultMap可以在执行单个查询时获取关联的数据而不必执行多次查询这样可以提高应用程序的性能。
下面是一个使用 resultMap 来处理一对一和一对多关系的完整示例。
数据库模型
假设我们有以下三个表
1. 用户表 user 2. 部门表 department 3. 用户联系人表 user_linkman
用户表user:
CREATE TABLE user (id int(11) NOT NULL AUTO_INCREMENT,code varchar(255) DEFAULT NULL,name varchar(255) DEFAULT NULL,age int(2) unsigned DEFAULT NULL,department_id int(11) NOT NULL COMMENT 部门id,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT6 DEFAULT CHARSETutf8mb4 COMMENT用户表;
部门表department:
CREATE TABLE department (id int(11) NOT NULL AUTO_INCREMENT COMMENT 部门id,department_name varchar(255) DEFAULT NULL COMMENT 部门名称,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT3 DEFAULT CHARSETutf8mb4 COMMENT部门表;
用户联系人表user_linkman:
CREATE TABLE user_linkman (id int(11) NOT NULL AUTO_INCREMENT COMMENT 用户联系人表主键id,user_id int(11) DEFAULT NULL COMMENT 用户id,linkman_id varchar(255) DEFAULT NULL COMMENT 联系人id,PRIMARY KEY (id)
) ENGINEInnoDB AUTO_INCREMENT8 DEFAULT CHARSETutf8mb4 COMMENT用户联系人表;
实体类
用户实体类User:
package com.example.demo.entity;import lombok.Data;
import java.util.List;Data
public class User {private String id;private String code;private String name;private int age;private Department department; // 对应部门实体private ListUserLinkman linkmenList; // 对应联系人列表
}
MyBatis 配置
在 MyBatis 的映射文件中我们可以定义一个 resultMap 来描述如何从数据库结果集映射到我们的实体类。
resultMap iduserResultMap typeUserid propertyid columnid /result propertycode columncode /result propertyname columnname /result propertyage columnage /association propertydepartment columndepartment_id javaTypeDepartment selectselectDepartmentById /collection propertylinkmenList ofTypeUserLinkman columnid selectselectLinkmanListByUserId /
/resultMapselect idselectDepartmentById resultTypeDepartmentSELECT id, department_name AS departmentName FROM department WHERE id #{id}
/selectselect idselectLinkmanListByUserId resultTypeUserLinkmanSELECT id, user_id AS userId, linkman_id AS linkmanId FROM user_linkman WHERE user_id #{id}
/selectselect idselectUserById resultMapuserResultMapSELECT * FROM user WHERE id #{id}
/select
在上述配置中我们定义了一个 userResultMap
- association 用于处理一对一的关系这里是用户和部门的关系。 - collection 用于处理一对多的关系这里是用户和联系人的关系。
通过这种配置当我们调用 selectUserById 查询时MyBatis 会自动执行 selectDepartmentById 和 selectLinkmanListByUserId 查询来填充 User 实体中的 department 和 linkmenList 属性。
举例
假设我们需要查询某次考试的所有单位信息包括名称、参考人数、通过人数、通过率以及本部门所有参考人员的信息。我们可以创建一个对应的 resultMap
resultMap idCountResultMap typecom.example.demo.entity.vo.ExamTestVoresult columndepartment jdbcTypeVARCHAR propertydepartment/result columnexam_num jdbcTypeVARCHAR propertyexamNum/result columnpass_num jdbcTypeVARCHAR propertypassNum/result columnpercent_pass jdbcTypeVARCHAR propertypercentPass/collection propertyuserList javaTypelist columnid ofTypeUser selectselectUserListByExamId /
/resultMap
这里的 collection 标签将会把某个考试 ID 对应的所有用户信息作为一个列表映射到 ExamTestVo 的 userList 属性中。这样通过单个查询我们就能获取一个考试的所有相关信息包括每个单位的详细数据和参考人员的列表。
【K】Mybatis使用常见类型的类型别名
MyBatis 提供了一系列内置的类型别名用于简化 XML 配置文件中的类型引用。这些别名代表了 Java 中的一些常见类型。使用类型别名可以让你的 MyBatis 配置文件更加简洁易懂。
下面是一些常见的 MyBatis 内置类型别名及其对应的 Java 类型
Java 类型MyBatis 别名byte_bytelong_longshort_shortint_intInteger_integerdouble_doublefloat_floatboolean_boolean
还有一些引用类型的别名
Java 类型MyBatis 别名StringstringBytebyteLonglongShortshortIntegerintDoubledoubleFloatfloatBooleanbooleanDatedateBigDecimaldecimalBigDecimalbigdecimalObjectobjectMapmapHashMaphashmapListlistArrayListarraylistCollectioncollectionIteratoriterator
使用这些类型别名的例子
select idselectUserById resultType_intSELECT age FROM user WHERE id #{id}
/selectselect idselectUserName resultTypestringSELECT name FROM user WHERE id #{id}
/selectselect idselectAllUsers resultTypemapSELECT * FROM user
/select
在上述例子中resultType_int 表示查询的结果是一个基本类型 intresultTypestring 表示查询的结果是 String 类型而 resultTypemap 表示查询的结果是 Map 类型的集合。
要注意的是当我们使用类型别名 _int 时通常是在查询返回单个值的场景比如统计数量或者查询某个特定的数值 有用请点赞养成良好习惯
疑问、交流、鼓励请留言