【后端高频面试题--Mybatis篇】
🚀 作者 :“码上有前”
🚀 文章简介 :后端高频面试题
🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬
后端高频面试题--Mybatis篇
- 什么是Mybatis?Mybatis的优缺点?
- Mybatis的特点
- Mybatis框架适合场合
- JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
- MyBatis与Hibernate有哪些不同?
- # 谈一下你对 mybatis 缓存机制的理解?
- Mybatis中一级缓存与二级缓存
- MyBatis在insert插入操作时如何返回主键ID
- MyBatis 的 #{} 和 ${} 的区别?
- 当实体类中的属性名和表中的字段名不一样,怎么办?
- 模糊查询like语句该怎么写?
- 通常一个XML映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
- 在 mybatis 中,resultType 和 ResultMap 的区别是什么?(必会)
- 在 Mybatis 中你知道的动态 SQL 的标签有哪些?作用分别是什么?
- Mybatis是如何进行分页的?分页插件的原理是什么?
- Mybatis中的Mapper接口和XML文件里的SQL是如何建立关系的?
- Mybatis用过哪些标签?
- Mybatis执行流程?
什么是Mybatis?Mybatis的优缺点?
MyBatis(原名为iBatis)是一种Java持久层框架,用于简化数据库访问的开发。它通过将数据库访问逻辑与业务逻辑分离,提供了一种灵活且简单的方式来进行数据库操作。
MyBatis的主要特点包括:
-
简化SQL编写:MyBatis通过提供XML配置文件和注解方式,将SQL语句与Java代码分离,使得SQL编写更加清晰和可维护。
-
强大的映射功能:MyBatis支持将查询结果自动映射到Java对象,通过配置映射关系,可以方便地进行对象与数据库表之间的转换。
-
动态SQL支持:MyBatis提供了动态SQL功能,可以根据不同条件拼接SQL语句,简化了复杂查询的编写。
-
缓存支持:MyBatis内置了一级缓存和二级缓存,可以提高查询性能,减少数据库访问次数。
-
插件扩展机制:MyBatis提供了插件扩展机制,可以通过插件来扩展和定制MyBatis的功能,如自定义拦截器、修改SQL执行过程等。
MyBatis的优点包括:
-
灵活性:MyBatis不强制使用特定的ORM模型,开发者可以自由地编写SQL和控制数据库访问逻辑,适用于复杂的业务需求。
-
性能优化:MyBatis提供了缓存机制和动态SQL支持,可以有效地提高数据库访问性能。
-
易于集成:MyBatis与Java应用集成简单,可以与各种主流的Java框架(如Spring)无缝集成,提供了丰富的整合支持。
-
易于学习和上手:相对于其他ORM框架,MyBatis学习曲线较为平缓,使用起来相对简单,容易上手。
MyBatis的缺点包括:
-
配置较复杂:MyBatis需要编写XML配置文件来映射SQL语句和Java对象,对于简单的CRUD操作可能会增加一些额外的配置和工作量。
-
SQL依赖:MyBatis需要开发者手动编写和维护SQL语句,对于不熟悉SQL的开发者来说,可能需要额外学习和掌握SQL的知识。
-
缺乏自动化:相对于全自动的ORM框架,MyBatis需要开发者手动编写SQL语句和映射关系,对于某些简单的业务需求,可能会显得繁琐。
综上所述,MyBatis作为一种轻量级的持久层框架,在灵活性、性能优化和易于集成等方面具有优势,但在配置复杂和SQL依赖方面存在一些缺点。开发者可以根据项目需求和个人经验,评估是否选择使用MyBatis。
Mybatis的特点
MyBatis是一种开源的持久层框架,它具有以下几个特点:
-
简化数据库操作:MyBatis通过提供简洁的配置和灵活的映射方式,将数据库操作的细节隐藏起来,开发者只需关注SQL语句的编写和结果的映射,而无需手动处理数据库连接、事务和结果集等底层细节。
-
灵活的SQL编写:MyBatis支持使用原生的SQL语句,开发者可以编写和优化自己的SQL语句,灵活性较高。同时,MyBatis也提供了动态SQL的功能,可以根据条件动态拼接SQL语句,方便实现复杂的查询和更新操作。
-
强大的映射功能:MyBatis提供了丰富的映射功能,可以将查询结果自动映射到Java对象中,大大简化了结果集的处理。同时,MyBatis还支持一对一、一对多、多对一和多对多等复杂的关联关系映射,方便进行对象之间的关联查询。
-
缓存支持:MyBatis提供了缓存机制,可以将查询结果缓存起来,下次相同的查询可以直接从缓存中获取,提高查询性能。MyBatis提供了一级缓存和二级缓存两种缓存级别,可以根据需求选择合适的缓存策略。
-
插件扩展:MyBatis支持插件机制,可以通过自定义插件来扩展和定制框架的功能。开发者可以通过插件来拦截和修改MyBatis的SQL执行过程,例如添加自定义的日志、性能监控等功能。
-
跨数据库支持:MyBatis可以适配多种不同的关系型数据库,例如MySQL、Oracle、SQL Server等,开发者可以在不同的数据库之间切换而无需修改大量的代码。
总体而言,MyBatis是一款灵活、简单且功能强大的持久层框架,它将数据库操作的细节封装起来,提供了便捷的配置和映射方式,同时支持自定义SQL和插件扩展,使得开发者可以更加高效地进行数据库操作。
Mybatis框架适合场合
MyBatis框架适用于以下场合:
-
需要灵活控制SQL语句:如果你需要对SQL语句进行细粒度的控制,包括编写复杂的查询语句、优化SQL性能或者使用数据库特定的高级功能,MyBatis是一个不错的选择。MyBatis允许你直接编写和优化原生SQL语句,同时提供了动态SQL的功能,方便根据条件拼接SQL语句。
-
需要高度可定制的映射:MyBatis提供了强大的结果映射功能,可以将查询结果自动映射到Java对象中。如果你的数据库结构与Java对象之间存在复杂的映射关系,例如一对一、一对多等关联关系,MyBatis可以很好地处理这些映射关系,并减少手动处理结果集的工作量。
-
需要对数据访问逻辑进行细粒度的控制:MyBatis允许你在SQL语句的执行过程中插入自定义的代码逻辑,包括拦截器、自定义类型处理器等。这样你可以对数据访问逻辑进行更细粒度的控制和定制,例如添加自定义的日志、缓存逻辑或者性能监控等。
-
需要细粒度地控制事务:MyBatis允许你对事务进行细粒度的控制,包括手动提交和回滚事务。如果你需要精确地控制事务边界,例如在一个方法中执行多个数据库操作,可以使用MyBatis的事务管理功能。
-
对性能有较高要求:MyBatis提供了一级缓存和二级缓存的支持,可以缓存查询结果,提高查询性能。通过合理配置和使用缓存,可以减少数据库访问次数,提高系统的响应速度和吞吐量。
总的来说,MyBatis适用于对SQL语句和数据访问逻辑有较高要求的项目,它提供了灵活的SQL编写方式、强大的结果映射功能和可定制性,可以满足复杂的业务需求。但同时,也需要开发者对数据库操作和SQL语句有一定的了解和掌握。
JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?
JDBC(Java Database Connectivity)是Java语言与数据库进行交互的标准接口,虽然它具有一定的优势,但也存在一些不足之处。以下是JDBC编程的一些不足之处以及MyBatis是如何解决这些问题的:
-
冗余的样板代码:JDBC编程需要大量的样板代码来处理数据库连接、事务管理、SQL语句的拼接和结果集的处理等。这些代码冗余且容易出错,增加了开发和维护的工作量。
MyBatis解决方案:MyBatis通过提供SQL映射配置文件和自定义接口来减少冗余的样板代码。开发者只需编写少量的配置和接口代码,MyBatis会自动处理数据库连接、事务管理和结果集的映射,简化了开发流程。
-
SQL与Java代码的混合:在JDBC编程中,SQL语句通常与Java代码混合在一起,导致SQL的可读性差、维护困难,并且在修改SQL时需要重新编译Java代码。
MyBatis解决方案:MyBatis将SQL与Java代码分离,通过XML配置文件或注解方式来定义SQL语句,使得SQL可读性更高,便于维护和修改,无需重新编译Java代码。
-
数据库操作的细节:JDBC编程需要开发者手动处理数据库连接的获取和释放、事务管理和异常处理等细节,容易出现资源泄露和错误处理不当的问题。
MyBatis解决方案:MyBatis封装了底层的数据库访问细节,自动管理数据库连接的获取和释放,提供了事务管理机制,简化了数据库操作的细节处理,减少了出错的可能性。
-
性能优化困难:JDBC编程需要开发者手动优化SQL语句、使用批处理和分页等技术来提高性能,这对于不熟悉数据库优化的开发者来说可能较为困难。
MyBatis解决方案:MyBatis提供了缓存机制、动态SQL和插件扩展等功能,可以帮助开发者进行性能优化。它提供了一些优化技术,如缓存查询结果、动态拼接SQL语句和自定义插件,简化了性能优化的工作。
综上所述,MyBatis通过提供SQL与Java代码分离、自动处理数据库连接和事务管理、性能优化等功能,解决了JDBC编程中存在的冗余代码、SQL与Java代码混合、细节处理和性能优化困难等问题,提供了更简洁、易于维护和优化的数据库访问解决方案。
MyBatis与Hibernate有哪些不同?
MyBatis和Hibernate是两个非常流行的Java持久层框架,它们在一些方面有着明显的不同:
-
SQL控制方式:MyBatis采用基于SQL的方式,开发者需要手动编写和优化SQL语句,可以对SQL进行精确控制和优化。而Hibernate采用基于对象的方式,开发者不需要编写SQL语句,框架会自动将对象持久化到数据库中,或者从数据库中检索对象。
-
对象关系映射(ORM):MyBatis将查询结果映射到Java对象中,提供了灵活的结果映射功能,可以处理复杂的关联关系。但是,开发者需要手动编写SQL语句和结果映射规则。Hibernate则完全执行ORM,自动将数据库表和Java对象进行映射,无需手动编写SQL语句和映射规则。
-
查询灵活性:MyBatis提供了动态SQL的功能,可以根据条件动态拼接SQL语句,灵活性较高,适合复杂查询。Hibernate使用Hibernate Query Language(HQL)进行查询,它是一种面向对象的查询语言,类似于SQL,但语法更接近于Java,可以方便地进行对象导航和查询。
-
缓存机制:MyBatis提供了一级缓存和二级缓存的支持,可以缓存查询结果,提高查询性能。一级缓存是在会话级别缓存,而二级缓存是在应用程序级别缓存。Hibernate也提供了缓存机制,但缓存的粒度更细,包括对象级缓存、集合级缓存等。
-
对数据库的依赖:MyBatis相对于Hibernate对数据库的依赖较低,开发者需要手动编写SQL语句和处理数据库连接、事务等细节。Hibernate则对数据库的依赖较高,框架会自动处理SQL语句的生成、连接管理和事务控制。
-
学习曲线:MyBatis相对于Hibernate来说学习曲线较陡峭,需要开发者熟悉SQL语句的编写和优化。Hibernate则相对较简单,使用者只需了解框架提供的API和配置,无需关注SQL语句的编写。
选择使用MyBatis还是Hibernate取决于项目的需求和开发者的偏好。如果对SQL的精确控制和灵活性有较高要求,或者需要处理复杂的关联关系,MyBatis可能是更好的选择。如果对开发速度和对象导航查询有较高要求,或者对SQL编写不熟悉,Hibernate可能更适合。
# 谈一下你对 mybatis 缓存机制的理解?
Mybatis中一级缓存与二级缓存
MyBatis提供了两级缓存来提高查询性能:一级缓存和二级缓存。
-
一级缓存:
- 一级缓存是MyBatis默认开启的,它是在SqlSession的生命周期内有效的。
- 当SqlSession执行查询操作时,查询的结果会被缓存到一级缓存中,下次相同的查询可以直接从缓存中获取结果,避免了重复查询数据库的开销。
- 一级缓存是基于对象引用的缓存,即当SqlSession关闭或执行了更新操作(插入、更新、删除)时,缓存将被清空,所有缓存的对象将失效。
-
二级缓存:
- 二级缓存是跨SqlSession的缓存,可以被多个SqlSession共享。
- 二级缓存需要手动配置并开启,在MyBatis的配置文件中进行配置。
- 当SqlSession执行查询操作时,结果会被缓存到二级缓存中,其他的SqlSession可以从二级缓存中获取结果。
- 二级缓存是基于缓存对象的序列化和反序列化,因此需要缓存的对象必须实现序列化接口。
- 更新操作会导致二级缓存的失效,因为更新操作可能会改变缓存中的数据。
需要注意的是,虽然缓存可以提高查询性能,但在某些场景下可能会导致数据不一致的问题。因此,对于经常变动的数据或者对数据强一致性要求较高的场景,建议谨慎使用缓存,或者在更新操作时手动刷新缓存。
可以通过配置文件中的<cache>
元素来配置二级缓存,通过<select>
元素的useCache
属性来控制是否使用一级缓存。
MyBatis在insert插入操作时如何返回主键ID
在MyBatis中,可以通过以下几种方式获取插入操作后的主键ID:
-
使用数据库的自增主键:
- 如果你的数据库表使用了自增主键,那么在执行插入操作后,可以通过
useGeneratedKeys
和keyProperty
属性来获取插入后的自增主键值。 - 在插入语句的
<insert>
元素中,设置useGeneratedKeys="true"
,表示使用数据库的自动生成的主键。 - 同时在
<insert>
元素中,设置keyProperty
,指定一个Java对象的属性名,用于接收自动生成的主键值。 - 插入完成后,可以通过获取该Java对象的属性值来获取主键ID。
- 如果你的数据库表使用了自增主键,那么在执行插入操作后,可以通过
-
使用数据库的序列:
- 如果你的数据库表使用了序列来生成主键,那么可以通过
selectKey
元素来获取插入后的主键值。 - 在插入语句的
<insert>
元素中,添加<selectKey>
元素,在其中定义查询序列的语句,并设置keyProperty
指定一个Java对象的属性名,用于接收序列生成的主键值。 - 插入完成后,可以通过获取该Java对象的属性值来获取主键ID。
- 如果你的数据库表使用了序列来生成主键,那么可以通过
下面是一个使用数据库的自增主键的示例:
<insert id="insertUser" parameterType="User" useGeneratedKeys="true" keyProperty="id">INSERT INTO user (username, password) VALUES (#{username}, #{password})
</insert>
在Java代码中,执行插入操作后,可以通过获取User对象的id属性来获取主键ID:
User user = new User();
user.setUsername("John");
user.setPassword("123456");
mapper.insertUser(user);
System.out.println(user.getId());
注意,获取主键ID的方式可能因数据库的不同而略有差异,具体应根据使用的数据库类型和配置进行相应的设置。
MyBatis 的 #{} 和 ${} 的区别?
在MyBatis中,#{}
和${}
是两种不同的参数替换方式,它们有以下区别:
-
#{}
参数替换方式:#{}
是预编译的方式,会将参数值进行安全地替换,并将参数值作为预编译的占位符传递给数据库驱动,以防止SQL注入攻击。#{}
可以用于替换任何位置的参数,包括SQL语句中的表名、列名、条件值等。#{}
可以接收任意类型的参数,并且会自动进行类型转换,例如数字、字符串、日期等。
-
${}
参数替换方式:${}
是文本替换的方式,会将参数值直接替换到SQL语句中,生成最终的SQL语句。${}
可以用于替换SQL语句中的表名、列名等静态部分,不能用于替换条件值等动态部分。${}
只是简单地将参数值替换到SQL语句中,不会进行预编译和安全检查,存在SQL注入的风险。
主要区别总结如下:
#{}
是预编译占位符,安全且可接收任意类型参数,适合替换动态的值。${}
是文本替换,不做预编译和安全检查,适合替换静态的表名、列名等部分。- 为了避免SQL注入攻击,推荐使用
#{}
替换动态值,尽量避免使用${}
替换动态值。
使用示例:
<!-- 使用#{param}方式 -->
<select id="getUserById" parameterType="int" resultType="User">SELECT * FROM user WHERE id = #{id}
</select><!-- 使用${param}方式 -->
<select id="getUserByTableName" parameterType="String" resultType="User">SELECT * FROM ${tableName} WHERE id = 1
</select>
在使用#{}
方式时,MyBatis会将参数值进行预编译和安全替换,生成类似于SELECT * FROM user WHERE id = ?
的SQL语句,然后将参数值传递给数据库驱动执行。
在使用${}
方式时,MyBatis会直接将参数值替换到SQL语句中,生成类似于SELECT * FROM tablename WHERE id = 1
的SQL语句。请注意,${}
方式存在潜在的安全风险,因此在使用时应谨慎验证和过滤参数值,以避免SQL注入攻击。
当实体类中的属性名和表中的字段名不一样,怎么办?
当实体类中的属性名和表中的字段名不一致时,可以通过在MyBatis中进行映射配置来解决。MyBatis提供了多种方式来处理属性与字段的映射关系:
-
使用
<resultMap>
:可以使用<resultMap>
标签来定义属性和字段之间的映射关系。在<resultMap>
中,可以使用<result>
标签指定属性和字段的对应关系,通过column
属性指定数据库字段名,通过property
属性指定实体类属性名。<resultMap id="userResultMap" type="User"><result column="user_name" property="userName"/><result column="user_age" property="userAge"/> </resultMap>
然后在SQL映射文件中使用
<resultMap>
:<select id="getUserById" resultMap="userResultMap">SELECT user_name, user_age FROM user WHERE id = #{id} </select>
这样,查询结果中的
user_name
字段会映射到userName
属性,user_age
字段会映射到userAge
属性。 -
使用
<result>
标签:除了使用<resultMap>
,也可以在SQL映射文件的SQL语句中使用<result>
标签直接指定属性和字段的对应关系。<select id="getUserById" resultType="User">SELECT user_name AS userName, user_age AS userAge FROM user WHERE id = #{id} </select>
在这个例子中,
user_name
字段会映射到userName
属性,user_age
字段会映射到userAge
属性。 -
使用注解:MyBatis也支持使用注解方式来进行属性和字段的映射配置。可以使用
@Results
和@Result
注解来指定属性和字段的对应关系。@Results({@Result(column = "user_name", property = "userName"),@Result(column = "user_age", property = "userAge") }) @Select("SELECT user_name, user_age FROM user WHERE id = #{id}") User getUserById(int id);
在这个例子中,
user_name
字段会映射到userName
属性,user_age
字段会映射到userAge
属性。
通过以上方式,可以将实体类的属性名和表中的字段名进行映射配置,使其能够正确地进行属性和字段之间的转换。
模糊查询like语句该怎么写?
在 MyBatis 中进行模糊查询可以使用 SQL 的 LIKE
语句,并结合通配符 %
或 _
来匹配模式。下面是几种常见的使用方式:
-
匹配开头或结尾的模糊查询:
<select id="searchUsers" resultType="User">SELECT * FROM user WHERE user_name LIKE #{keyword}% </select>
在这个例子中,
#{keyword}
是要匹配的关键字,%
是通配符,表示匹配任意字符。这样查询会返回所有user_name
以指定关键字开头的用户。 -
匹配包含的模糊查询:
<select id="searchUsers" resultType="User">SELECT * FROM user WHERE user_name LIKE %#{keyword}% </select>
在这个例子中,
#{keyword}
是要匹配的关键字,%
是通配符,表示匹配任意字符。这样查询会返回所有user_name
中包含指定关键字的用户。 -
自定义通配符:
<select id="searchUsers" resultType="User">SELECT * FROM user WHERE user_name LIKE CONCAT('%', #{keyword}, '%') </select>
在这个例子中,使用了
CONCAT
函数将%
和关键字拼接在一起,实现模糊匹配。这样查询会返回所有user_name
中包含指定关键字的用户。
请注意,上述示例中的 #{keyword}
是 MyBatis 中的占位符,具体的值需要在实际调用时传入。
另外,如果需要进行大小写敏感的模糊查询,你可以根据数据库的特性来使用相应的函数或操作符,如 UPPER
函数将关键字和数据库字段都转换为大写,以实现不区分大小写的匹配。具体的语法和函数可能会因数据库类型而有所不同,你可以根据使用的数据库进行相应的调整。
通常一个XML映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗?
在 MyBatis 中,Dao 接口与 XML 映射文件相互对应,主要负责定义数据库操作的方法。Dao 接口的工作原理是通过 MyBatis 的动态代理机制,将接口的方法调用转化为对应的 SQL 语句执行。
当你定义一个 Dao 接口时,MyBatis 会根据接口的方法名和参数来查找对应的 XML 映射文件中的 SQL 语句进行执行。这样,你可以通过调用 Dao 接口的方法,来实现对数据库的增、删、改、查等操作。
下面是一个示例的 Dao 接口和对应的 XML 映射文件的示例:
public interface UserDao {User getUserById(int id);List<User> getUsersByKeyword(String keyword);void insertUser(User user);void updateUser(User user);void deleteUser(int id);
}
<!-- UserDao.xml -->
<mapper namespace="com.example.dao.UserDao"><select id="getUserById" resultType="User">SELECT * FROM user WHERE id = #{id}</select><select id="getUsersByKeyword" resultType="User">SELECT * FROM user WHERE user_name LIKE CONCAT('%', #{keyword}, '%')</select><insert id="insertUser">INSERT INTO user (user_name, user_age) VALUES (#{userName}, #{userAge})</insert><update id="updateUser">UPDATE user SET user_name = #{userName}, user_age = #{userAge} WHERE id = #{id}</update><delete id="deleteUser">DELETE FROM user WHERE id = #{id}</delete>
</mapper>
在上述示例中,Dao 接口中的方法与 XML 映射文件中定义的 SQL 语句相对应。当调用 getUserById
方法时,MyBatis 会查找 getUserById
对应的 SQL 语句进行执行。
关于方法重载的问题,Java 中的接口是支持方法重载的,因此在 Dao 接口中,方法名相同但参数不同是可以实现方法重载的。例如,你可以定义多个方法名为 getUserById
的方法,但参数列表不同:
public interface UserDao {User getUserById(int id);User getUserById(String id);
}
这样,在调用时根据传入的参数类型不同,会自动匹配相应的方法。但是需要注意的是,MyBatis 在执行 SQL 语句时是根据方法名进行匹配的,因此方法名必须是唯一的,不能出现重复的方法名。
总结来说,Dao 接口通过定义方法与 XML 映射文件中的 SQL 语句相对应,通过 MyBatis 的动态代理机制将方法调用转化为 SQL 语句的执行。可以根据需要在接口中定义不同的方法名和参数列表,实现对数据库的各种操作。
在 mybatis 中,resultType 和 ResultMap 的区别是什么?(必会)
在 MyBatis 中,resultType
和 resultMap
都用于指定查询结果的映射方式,但它们有一些关键的区别。
-
resultType
:resultType
用于指定查询结果的类型,即将查询结果映射到的 Java 对象的类型。它通常用于简单的映射情况,其中查询结果的列名会与目标对象的属性名一一对应。使用resultType
时,MyBatis 会使用默认的规则进行自动映射。例如,如果查询的结果是一个
User
对象,可以在 SQL 映射文件中这样指定:<select id="getUserById" resultType="User">SELECT * FROM user WHERE id = #{id} </select>
在这个例子中,查询结果会自动映射到
User
类型的对象。使用
resultType
的限制是,查询结果的列名必须和目标对象的属性名一一对应,否则无法进行自动映射。 -
resultMap
:resultMap
用于定义复杂的结果集映射关系。它提供了更灵活的映射方式,可以手动指定查询结果的列名和目标对象的属性名之间的对应关系。通过resultMap
,可以处理查询结果与目标对象属性名不一致的情况,以及进行关联查询、嵌套对象等复杂映射操作。通过
resultMap
,可以在 SQL 映射文件中自定义映射规则。下面是一个示例:<resultMap id="userResultMap" type="User"><id property="id" column="user_id"/><result property="userName" column="user_name"/><result property="userAge" column="user_age"/> </resultMap><select id="getUserById" resultMap="userResultMap">SELECT user_id, user_name, user_age FROM user WHERE id = #{id} </select>
在这个例子中,
resultMap
定义了User
类型的映射规则,指定了查询结果中的列名与User
对象的属性名之间的对应关系。使用
resultMap
可以处理更复杂的映射情况,灵活性更高,但需要手动编写映射规则。
总结来说,resultType
适用于简单的结果集映射,通过自动映射规则将查询结果映射到指定类型的对象;resultMap
则适用于复杂的结果集映射,可以手动定义映射规则,处理更灵活的映射需求。
在 Mybatis 中你知道的动态 SQL 的标签有哪些?作用分别是什么?
MyBatis 提供了一些动态 SQL 的标签,用于在 SQL 映射文件中编写灵活的 SQL 语句。以下是一些常用的动态 SQL 标签及其作用:
-
<if>
标签:用于条件判断,根据条件动态生成 SQL 语句的一部分。<select id="getUser" resultType="User">SELECT * FROM userWHERE<if test="id != null">id = #{id}</if><if test="username != null">AND username = #{username}</if> </select>
在这个例子中,根据传入的参数动态生成了不同的 SQL 语句,如果
id
不为 null,则生成id = #{id}
的条件;如果username
不为 null,则生成AND username = #{username}
的条件。 -
<choose>、<when>、<otherwise>
标签:用于实现条件选择,类似于 Java 的switch
语句。<select id="getUser" resultType="User">SELECT * FROM user<choose><when test="id != null">WHERE id = #{id}</when><when test="username != null">WHERE username = #{username}</when><otherwise>WHERE 1=1</otherwise></choose> </select>
在这个例子中,根据不同的条件选择生成不同的 SQL 语句,如果
id
不为 null,则生成WHERE id = #{id}
的条件;如果username
不为 null,则生成WHERE username = #{username}
的条件;如果id
和username
都为 null,则生成WHERE 1=1
的条件。 -
<foreach>
标签:用于遍历集合或数组,并在 SQL 语句中生成相应的部分。<select id="getUsersByIds" resultType="User">SELECT * FROM userWHERE id IN<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach> </select>
在这个例子中,
ids
是一个集合或数组,通过<foreach>
标签将其中的元素逐个取出,并生成id IN (id1, id2, id3)
的条件。 -
<trim>
、<set>
、<where>
标签:用于处理 SQL 语句中的前缀、后缀以及条件的动态拼接。<update id="updateUser" parameterType="User">UPDATE user<set><if test="username != null">username = #{username},</if><if test="password != null">password = #{password},</if></set>WHERE id = #{id} </update>
在这个例子中,
<set>
标签用于动态拼接SET
子句,根据条件拼接不同的字段更新语句。
这些动态 SQL 标签提供了灵活的编写 SQL 语句的方式,可以根据不同的条件动态生成 SQL 的部分,使 SQL 映射文件更具可读性和可维护性。
Mybatis是如何进行分页的?分页插件的原理是什么?
在 MyBatis 中进行分页查询通常有两种方式:使用数据库的分页查询语句或者使用分页插件。
-
数据库的分页查询语句:可以使用数据库特定的分页查询语句(如 MySQL 的
LIMIT
关键字或 Oracle 的ROWNUM
)来实现分页查询。在 SQL 语句中通过指定起始行和每页显示的记录数来实现分页效果。-- MySQL SELECT * FROM table LIMIT 0, 10;-- Oracle SELECT * FROM (SELECT ROWNUM as rowno, t.* FROM table t) WHERE rowno BETWEEN 0 AND 10;
这种方式的优点是简单直接,但不同数据库的分页语句略有差异,需要根据具体的数据库进行调整。
-
分页插件:MyBatis 还提供了一些分页插件,例如 PageHelper、PaginationInterceptor 等,它们通过拦截 SQL 执行过程,在查询语句中自动添加分页的逻辑。分页插件的原理大致如下:
-
拦截 SQL 执行过程:分页插件会拦截 MyBatis 的 SQL 执行过程,通常是通过拦截 Executor 对象的相关方法实现的。
-
解析分页参数:插件会解析传入的分页参数,包括页码和每页显示的记录数。
-
修改 SQL 语句:根据分页参数,插件会修改原始的 SQL 语句,添加分页的逻辑,例如在查询语句中添加 LIMIT 关键字或者改写为数据库特定的分页查询语句。
-
执行分页查询:修改后的 SQL 语句会被执行,获取到分页结果集。
-
封装分页结果:插件会将分页结果封装为特定的数据结构,通常是一个包含分页信息和数据列表的对象。
分页插件的优点是使用方便,可以在不修改原始 SQL 语句的情况下实现分页效果,且对不同数据库的分页语句进行了封装,使用时无需关心具体的数据库差异。
-
需要注意的是,使用分页插件可能会对性能产生一定的影响,特别是在处理大数据量的分页查询时,因为插件需要对整个结果集进行处理。因此,在使用分页插件时,需要合理配置和使用,根据实际情况进行性能优化。
Mybatis中的Mapper接口和XML文件里的SQL是如何建立关系的?
在 MyBatis 中,Mapper 接口和 XML 文件里的 SQL 语句通过一定的约定进行关联,这样可以实现接口方法与对应的 SQL 语句的映射。下面是建立 Mapper 接口和 XML 文件关系的一般步骤:
-
创建 Mapper 接口:首先创建一个 Java 接口,该接口定义了需要执行的 SQL 操作,其中的方法名和参数与对应的 SQL 语句相关联。
public interface UserMapper {User getUserById(int id);void insertUser(User user);void updateUser(User user);void deleteUser(int id); }
-
创建 Mapper XML 文件:在 MyBatis 的配置文件中,通过
<mapper>
标签指定 Mapper XML 文件的路径,并在该 XML 文件中编写与接口方法相关的 SQL 语句。<!-- userMapper.xml --> <mapper namespace="com.example.UserMapper"><select id="getUserById" resultType="User">SELECT * FROM user WHERE id = #{id}</select><insert id="insertUser">INSERT INTO user (id, username, password) VALUES (#{id}, #{username}, #{password})</insert><!-- 其他方法的 SQL 语句 --> </mapper>
-
配置 MyBatis 映射文件:在 MyBatis 的配置文件中,通过
<mappers>
标签配置 Mapper 映射文件的路径,将 Mapper 接口和对应的 XML 文件关联起来。<!-- mybatis-config.xml --> <configuration><mappers><mapper resource="com/example/userMapper.xml"/></mappers> </configuration>
或者可以使用注解的方式进行配置:
<mapper class="com.example.UserMapper"/>
-
使用 Mapper 接口:在应用程序中,可以通过依赖注入或者获取 SqlSession 对象的方式获得 Mapper 接口的实例,然后调用接口方法执行 SQL 操作。
// 获取 Mapper 接口实例 UserMapper userMapper = sqlSession.getMapper(UserMapper.class);// 调用接口方法执行 SQL 操作 User user = userMapper.getUserById(1);
MyBatis 根据接口方法的名称和参数,通过动态代理的方式,将调用转发给对应的 XML 文件中定义的 SQL 语句。
通过以上的步骤,Mapper 接口与 XML 文件里的 SQL 语句建立了关联,实现了接口方法与对应的 SQL 操作的映射关系。这种方式使得 SQL 语句与 Java 代码分离,提升了代码的可维护性和可读性。
Mybatis用过哪些标签?
MyBatis 使用了多个标签来实现与数据库的交互和映射操作。下面列举了一些常用的 MyBatis 标签:
-
<configuration>
:MyBatis 的配置文件根元素,用于配置全局设置和属性。 -
<settings>
:用于配置 MyBatis 的全局设置选项,例如开启缓存、启用延迟加载等。 -
<typeAliases>
:用于配置类型别名,将 Java 类型与 XML 中的类型名称进行映射,简化映射配置。 -
<dataSource>
:用于配置数据源信息,指定数据库连接的相关参数。 -
<environments>
:用于配置 MyBatis 的运行环境,包括事务管理器和数据源。 -
<transactionManager>
:用于配置事务管理器,指定事务管理的方式,例如 JDBC 或者 Spring 事务管理。 -
<mappers>
:用于配置 Mapper 映射文件的路径或者 Mapper 接口的类名,将 Mapper 接口与对应的 SQL 映射文件进行关联。 -
<mapper>
:用于指定 Mapper 映射文件的路径或者 Mapper 接口的类名,建立 Mapper 接口与对应的 SQL 映射文件的关系。 -
<resultMap>
:用于定义结果集的映射关系,将查询结果映射为 Java 对象。 -
<select>
:用于定义查询操作的 SQL 语句。 -
<insert>
:用于定义插入操作的 SQL 语句。 -
<update>
:用于定义更新操作的 SQL 语句。 -
<delete>
:用于定义删除操作的 SQL 语句。 -
<sql>
:用于定义可重用的 SQL 片段,可以在其他 SQL 语句中引用。 -
<if>
、<choose>
、<when>
、<otherwise>
:用于在 SQL 语句中进行条件判断和分支选择。 -
<include>
:用于引入外部的 SQL 片段,增强 SQL 的可重用性。 -
<foreach>
:用于循环遍历集合或数组,并在 SQL 语句中生成对应的参数。
这些标签涵盖了 MyBatis 中常见的配置和映射操作,通过它们可以进行灵活的 SQL 编写和与数据库的交互。
Mybatis执行流程?
MyBatis 的执行流程可以大致分为以下几个步骤:
-
加载配置文件:MyBatis 在启动时会加载配置文件(通常是
mybatis-config.xml
),该配置文件包含了 MyBatis 的全局配置信息,如数据库连接信息、类型别名、映射文件等。 -
创建 SqlSessionFactory:通过配置文件,MyBatis 创建一个 SqlSessionFactory 对象,SqlSessionFactory 是 MyBatis 的核心对象,负责创建 SqlSession。
-
创建 SqlSession:通过 SqlSessionFactory 创建一个 SqlSession 对象,SqlSession 提供了与数据库交互的方法,包括执行 SQL 语句、获取映射器等。
-
获取映射器(Mapper):通过 SqlSession 获取映射器(Mapper)接口的实例,映射器接口定义了要执行的 SQL 操作。
-
执行 SQL 操作:通过映射器接口的方法执行 SQL 操作,可以执行查询、插入、更新、删除等操作。
-
SQL 解析与执行:在执行 SQL 操作时,MyBatis 会解析映射器接口的方法名,并根据方法名找到对应的 SQL 语句。MyBatis 支持使用 XML 文件或注解的方式来定义 SQL 语句,根据配置的方式不同,解析的方式也会略有不同。
-
XML 方式:MyBatis 会根据映射器接口的名称和方法名,找到对应的 XML 映射文件,并解析其中定义的 SQL 语句。
-
注解方式:MyBatis 会通过 Java 反射机制获取映射器接口上的注解信息,从而得到对应的 SQL 语句。
-
-
参数处理与绑定:MyBatis 会将方法参数与 SQL 语句中的参数进行绑定,将参数传递给 SQL 语句中的占位符。
-
SQL 执行与结果映射:MyBatis 执行 SQL 语句,并将数据库返回的结果映射为 Java 对象,可以通过配置的 ResultMap 进行对象属性与结果集的映射。
-
事务管理:根据配置的事务管理方式,MyBatis 可能会在适当的时机开启、提交或回滚事务。
-
关闭 SqlSession:在完成数据库操作后,需要关闭 SqlSession,释放资源。
这是一个基本的 MyBatis 执行流程,具体的执行细节和步骤可能会受到配置和使用方式的影响。通过以上的流程,MyBatis 实现了将 Java 对象与数据库之间的映射和交互,简化了与数据库的编程工作。
都看到这了,点个赞吧🚀
相关文章:
【后端高频面试题--Mybatis篇】
🚀 作者 :“码上有前” 🚀 文章简介 :后端高频面试题 🚀 欢迎小伙伴们 点赞👍、收藏⭐、留言💬 后端高频面试题--Mybatis篇 什么是Mybatis?Mybatis的优缺点?Mybatis的特点…...
【笔记】Helm-5 Chart模板指南-12 .helmignore文件
.helmignore文件 .helmignore文件用来指定您不想包含在您的helm chart中的文件。 如果该文件存在,helm package命令会在打包应用时忽略所有在.helmignore文件中匹配的文件。 有助于避免不需要的或敏感文件及目录添加到您的helm chart中。 .helmignore文件支持Uni…...
【MySQL】表的增删改查(基础)
MySQL表的增删改查(基础) 1. CRUD2. 新增(Create)2.1 单行数据全列插入2.2 多行数据 指定列插入 3. 查询(Retrieve)3.1 全列查询3.2 指定列查询3.3 查询字段为表达式3.4 别名3.5 去重:DISTINCT…...
Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin
Android矩阵Matrix动画缩放Bitmap移动手指触点到ImageView中心位置,Kotlin 借鉴 Android双指缩放ScaleGestureDetector检测放大因子大图移动到双指中心点ImageView区域中心,Kotlin(2)-CSDN博客 在此基础上实现手指在屏幕上点击后&…...
C语言:表达式求值
引言:在笔试中,有一类的题目,题目给出代码,要求分析得出输出结果。这类题目更加考察我们对于运算顺序和运算类型转换的理解。文章介绍了隐式类型转换和操作符注意点,希望增加读者对于表达式求值的理解。 1.隐式类型转…...
GO 的 Web 开发系列(五)—— 使用 Swagger 生成一份好看的接口文档
经过前面的文章,已经完成了 Web 系统基础功能的搭建,也实现了 API 接口、HTML 模板渲染等功能。接下来要做的就是使用 Swagger 工具,为这些 Api 接口生成一份好看的接口文档。 一、写注释 注释是 Swagger 的灵魂,Swagger 是通过…...
【极数系列】Flink集成KafkaSink 实时输出数据(11)
文章目录 01 引言02 连接器依赖2.1 kafka连接器依赖2.2 base基础依赖 03 使用方法04 序列化器05 指标监控06 项目源码实战6.1 包结构6.2 pom.xml依赖6.3 配置文件6.4 创建sink作业 01 引言 KafkaSink 可将数据流写入一个或多个 Kafka topic 实战源码地址,一键下载可用…...
我为什么选择Xamarin开发ios app安卓app
临岁之寒简书作者,转载 Xamarin是一项跨平台开发技术,之前是收费的,而且据说收费不菲,所以使用的人数比较少,在国内几乎无人问津。后来Xamarin被微软收购,现已免费开放,相信今后国内的使用人群会大幅地增长…...
安全基础~通用漏洞4
文章目录 知识补充XSS跨站脚本**原理****攻击类型**XSS-后台植入Cookie&表单劫持XSS-Flash钓鱼配合MSF捆绑上线ctfshow XSS靶场练习 知识补充 SQL注入小迪讲解 文件上传小迪讲解 文件上传中间件解析 XSS跨站脚本 xss平台: https://xss.pt/ 原理 恶意攻击者…...
2024/2/12 图的基础知识 2
目录 查找文献 P5318 【深基18.例3】查找文献 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 有向图的拓扑序列 848. 有向图的拓扑序列 - AcWing题库 最大食物链计数 P4017 最大食物链计数 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 查找文献 P5318 【深基18.例3】…...
无人机飞行原理,多旋翼无人机飞行原理详解
多旋翼无人机升空飞行的首要条件是动力,有了动力才能驱动旋粪旋转,才能产生克服重力所必需的升力。使旋翼产生升力,进而推动多旋翼无人机升空飞行的一套设备装置称为动力装置,包括多旋翼无人机的发动机以及保证发动机正常工作所必…...
docker本地目录挂载
小命令 1、查看容器详情 docker inspect 容器名称 还是以nginx为例,上篇文章我们制作了nginx静态目录的数据卷,此时查看nginx容器时会展示出来(docker inspect nginx 展示信息太多,这里只截图数据卷挂载信息)&#…...
使用C++从零开始,自己写一个MiniWeb
第一步:新建项目 1、打开VS点击创建新项目 2、选择空项目并点下一步(切记不能选错项目类型) 3、填写项目名称和路径,点击创建即可 新建好后项目是这样的比较干净 4、右击源文件,点击添加,新建http.cpp文件…...
Android Graphics 图像显示系统 - 开篇
“ 随着学习的不断深入和工作经验的积累,欲将之前在博客中整理的Android Graphics知识做进一步整理,并纠正一些理解上的错误,故开设Graphics主题系列文章 ” 序言 由于工作需要,也源于个人兴趣,终于下决心花时间整理一…...
机器学习在各个行业的应用介绍
随着科技的飞速发展,机器学习已经从实验室走向了现实世界,逐渐成为各行各业不可或缺的工具。从金融领域到医疗健康,从零售市场到制造业,机器学习正在改变着我们的工作方式和生活质量。 本文将深入探讨机器学习在以下几个领域的应用…...
【生产实测有效】Windows命令行查看激活状态脚本
Windows查看激活状态关键代码 通过windows server 自带的PowerShell来执行 Get-WmiObject SoftwareLicensingProduct | Select-Object -Property Description, LicenseStatus | findstr "Operating System"|findstr "1$"Get-WmiObject SoftwareLicensingPr…...
简单的Udp服务器
目录 简单的UDP网络程序1.1 UdpServer.hpp1.2 UdpClient.cc1.3 main.cc1.4 makefile1.5 log.hpp 简单的UDP网络程序 1.1 UdpServer.hpp #pragma once#include <iostream> using namespace std;#include <unistd.h> #include <sys/types.h> #include <sy…...
【Linux进程间通信】用管道实现简单的进程池、命名管道
【Linux进程间通信】用管道实现简单的进程池、命名管道 目录 【Linux进程间通信】用管道实现简单的进程池、命名管道为什么要实现进程池?代码实现命名管道创建一个命名管道 理解命名管道匿名管道与命名管道的区别命名管道的打开规则 作者:爱写代码的刚子…...
Linux操作系统基础(九):Linux用户与权限
文章目录 Linux用户与权限 一、文件权限概述 二、终端命令:组管理 三、终端命令:用户管理 1、创建用户 、 设置密码 、删除用户 2、查看用户信息 3、su切换用户 4、sudo 4.1、给指定用户授予权限 4.2、使用 用户 zhangsan登录, 操作管理员命令…...
蓝桥杯——第 5 场 小白入门赛(c++详解!!!)
文章目录 1 十二生肖基本思路: 2 欢迎参加福建省大学生程序设计竞赛基本思路:代码: 3 匹配二元组的数量基本思路:代码: 4 元素交换基本思路:代码: 5 下棋的贝贝基本思路:代码: 6 方程…...
Codeforces Round 303 (Div. 2)C. Kefa and Park(DFS、实现)
文章目录 题面链接题意题解代码总结 题面 链接 C. Kefa and Park 题意 求叶节点数量,叶节点满足,从根节点到叶节点的路径上最长连续1的长度小于m 题解 这道题目主要是实现,当不满足条件时直接返回。 到达叶节点后统计答案,用…...
797. 差分
Problem: 797. 差分 文章目录 思路解题方法复杂度Code 思路 这是一个差分数组的问题。差分数组的主要适用场景是频繁对原始数组的某一个区间进行增减操作。这种操作是区间修改操作,在这种操作下,差分数组只需要对区间的两个端点进行操作,时间…...
2024.2.5 vscode连不上虚拟机,始终waiting for server log
昨天还好好的,吃着火锅,做着毕设,突然就被vscode给劫了。 起初,哥们跟着网上教程有模有样地删除了安装包缓存,还删除了.vscode-server,发现没卵用,之前都是搜那个弹窗报错。 后来发现原来是vsco…...
CSS基础---新手入门级详解
CSS:层叠样式表 CSS(Cascading Style Sheets,层叠样式表),是一种用来为结构化文档添加样式(字体、间距和颜色)的计算机语言,css扩展名为.css。 实例: <!DOCTYPE html><html> <head><…...
Python中Pymysql库的常见用法和代码示例
关注B站可以观看更多实战教学视频:肆十二-的个人空间-肆十二-个人主页-哔哩哔哩视频 (bilibili.com) pymysql是一个用于连接MySQL数据库的Python库,它允许你执行SQL查询并处理返回的结果。以下是pymysql库的一些常见用法和代码示例: 1. 安装…...
使用 WPF + Chrome 内核实现高稳定性的在线客服系统复合应用程序
对于在线客服与营销系统,客服端指的是后台提供服务的客服或营销人员,他们使用客服程序在后台观察网站的被访情况,开展营销活动或提供客户服务。在本篇文章中,我将详细介绍如何通过 WPF Chrome 内核的方式实现复合客服端应用程序。…...
fastapi mysql 开发restful 3
pip install mysql-connector-python pymysql 数据库链接 创建src目录,里面创建db.py 代码如下: # 导入mysql.connector模块,该模块提供了与MySQL数据库进行连接和交互的功能。 import mysql.connector # 定义一个函数get_db_connectio…...
【Uniapp uni-app学习与快速上手——详细讲解】
Uniapp uni-app学习与快速上手——详细讲解 1. 介绍2. Uni-app 学习资源3. 快速上手4. 开始第一个项目5. 调试和发布 1. 介绍 Uni-app 是一个使用 Vue.js 编写多端应用的前端框架。开发者可以编写一份代码,然后发布到iOS、Android、网页(响应式…...
剑指offer——旋转数组的最小数字
目录 1. 题目描述2. 分析思路2.1 示例分析 3. 更完美的做法 1. 题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转。输入一个递增排序的数组的一个旋转,输出旋转数组的最小元素。例如数组{3.4,5,1.2}为{1.2,3,4,5}的一个旋转&a…...
盘点数据可视化大屏焦点图十种样式
所谓焦点图就是大屏中居于中心位置的图,是视觉的中心,本位列举了十种焦点图样式供大家参考。 地球作为焦点图 图片来自网络 地图作为焦点图 图片来自网络 城市作为焦点图 图片来自网络 园区做焦点图 图片来自网络 建筑做焦点图 图片来自网络 生产线…...
问题 G: 老鼠和猫的交易
题目描述 小老鼠准备了M磅的猫粮,准备去和看守仓库的猫做交易,因为仓库里有小老鼠喜欢吃的五香豆。 仓库有N个房间; 第i个房间有J[i] 磅的五香豆,并且需要用F[i]磅的猫粮去交换; 老鼠不必交换该房间所有的五香豆&…...
HiveSQL——借助聚合函数与case when行转列
一、条件函数 if 条件函数 if函数是最常用到的条件函数,其写法是if(xn,a,b), xn代表判断条件,如果xn时,那么结果返回a ,否则返回b。 selectif(age < 25 or age is null, 25岁以下, 25岁以上) as age_cnt,count(1) as number from table…...
冒泡排序,判断回文,以及12-24小时制
6-7 定义函数,完成冒泡排序算法。 本题定义一个冒泡排序算法的函数,调用函数后实现数组的升序排序,其数组长度为任意长度。 函数接口定义: 在这里描述函数接口。例如: void sort(int arr[],int n); 在这里解释接口…...
【Vue】computed与watch
📝个人主页:五敷有你 🔥系列专栏:Vue⛺️稳重求进,晒太阳 计算属性 概念:基于现有的数据,计算出来新的属性,依赖的数据变化,自动重新计算 语法: 声明…...
探索设计模式的魅力:捕捉变化的风-用观察者模式提升用户体验
设计模式专栏:http://t.csdnimg.cn/U54zu 目录 一、引言 核心概念 应用场景 可以解决的问题 二、场景案例 2.1 不用设计模式实现 2.2 存在问题 2.3 使用设计模式实现 2.4 成功克服 三、工作原理 3.1 结构图和说明 3.2 工作原理详解 3.3 实现步骤 四、 优…...
SpringCloud-高级篇(十九)
我们已经学过使用 SpringAMQP去收和发消息,但是发和收消息是只是MQ最基本的功能了,在收发消息的过程中,会有很多的问题需要去解决,下面需要学习rabbitMQ的高级特性去解决 死信交换机:这个可以帮助我们实现消息的延迟的…...
Junit常用断言
0.断言简介 断言:assert Q:断言的作用 更方便的对结果进行判定 "有针对性"的if判断 针对两个变量值是否相同 使用assertEquals针对两个对象是否相同 使用assertSame针对返回值是否为True 使用assertTrue 1.断言的参数 assertXXX(”断言失败时提升的信息“&#x…...
docker 实现 mysql:8.3.0 主从复制(2024年2月13日最新版本)
环境为 CentOS 7.6, 具体操作请看MySQL主从复制01-主从复制概述及原理_哔哩哔哩_bilibili 1、配置主服务器 # 启动主服务器 docker run -p 3306:3306 --name mysql_master -e MYSQL_ROOT_PASSWORDnmnmnm67890890 -v /docker/mysql_master/conf:/etc/mysql/conf.d…...
STM32 + ESP8266,连接阿里云 上报/订阅数据
(文章正在编辑中,一点点地截图操作过程,估计要拖拉两三天) 一、烧录MQTT固件 ESP8266出厂时,默认是AT固件。连接阿里云,需要使用MQTT固件。 1、独立EPS8266模块的烧录方法 2、魔女开发板,板载…...
如何利用chatgpt提升工作效率?
在数字化和信息化的时代,人工智能技术已经深入到了我们生活的方方面面。其中,ChatGPT作为当前热门的人工智能技术,以其强大的自然语言处理能力和广泛的应用场景,正逐渐改变着我们的工作方式,为我们提高工作效率提供了全…...
MongoDB聚合:$geoNear
$geoNear根据指定的点按照距离以由近到远的顺序输出文档。 从4.2版本开始,MongoDB移除了limit和num选项以及100个文档的限制,如果要限制结果文档的数量可以使用$limit阶段。 语法 { $geoNear: { <geoNear options> } }$geoNear操作接受一个包含…...
Docker-CE 国内源国内镜像
Docker-CE 就是 Docker Community Edition 的意思 docker-ce由docker官方维护 , docker.io由Debian维护 Docker官文 – Install Docker Engine on CentOS Docker官文 – Install Docker Engine on Fedora Docker官文 – Install Docker Engine on Debian Docker官文 – In…...
【Tauri】(3):使用Tauri1.5版本,进行桌面应用开发,在windows上搭建环境,安装node,rust环境,可以打包成功,使用vite创建应用
1,视频地址: https://www.bilibili.com/video/BV1Ny421a7nA/ 【Tauri】(3):使用Tauri1.5版本,进行桌面应用开发,在windows上搭建环境,安装node,rust环境,可以…...
C++ 堆排序
C 堆排序 堆排序是一种基于二叉堆数据结构的排序算法,其原理如下: 构建最大堆:将待排序的数组看作一个完全二叉树,并通过调整节点的位置构建一个最大堆。最大堆满足每个父节点的值都大于或等于其子节点的值。构建最大堆的过程可以…...
U3D记录之FBX纹理丢失问题
今天费老大劲从blender建了个模型,然后导出进去unity 发现贴图丢失 上网查了一下 首先blender导出要改设置 这个path mode要copy 然后unity加载纹理也要改设置 这里这个模型的纹理load要改成external那个模式 然后就有了,另外这个导出还有好多选项可…...
监测Nginx访问日志502情况后并做相应动作
今天带大家写一个比较实用的脚本哈 原理: 假设服务器环境为lnmp,近期访问经常出现502现象,且502错误在重启php-fpm服务后消失,因此需要编写监控脚本,一旦出现502,则自动重启php-fpm服务 场景: 1…...
【数据分享】1929-2023年全球站点的逐年平均风速(Shp\Excel\免费获取)
气象数据是在各项研究中都经常使用的数据,气象指标包括气温、风速、降水、能见度等指标,说到气象数据,最详细的气象数据是具体到气象监测站点的数据! 有关气象指标的监测站点数据,之前我们分享过1929-2023年全球气象站…...
Android性能调优 - 应用安全问题
Android应用安全 1.组件暴露: 像比如ContentProvider,BroadcastReceiver,Activity等组件有android:exported属性; 如果是私有组件 android:exported “false”; 如果是公有组件 android:exported “true” 且进行权限控制&…...
C#的Char 结构的像IsLetterOrDigit(Char)等常见的方法
目录 一、Char 结构的方法 二、Char.IsLetterOrDigit 方法 1.Char.IsLetterOrDigit(Char)用法 2.IsLetterOrDigit(String, Int32)方法 三、Char.IsLetter 方法 1.IsLetter(Char) 2.IsLetter(String, Int32) 四、Char.IsDigit 方法 1. IsDigit(String, Int32) 2.IsDig…...
部分意图分类【LLM+RAG】
在生成人工智能领域工作最有价值的事情之一就是发现新兴技术如何融入新的解决方案。 举个例子:在为北美顶级金融服务公司之一设计对话式人工智能助手时,WillowTree 的数据和人工智能研究团队 (DART) 发现,将意图分类与大型语言模型 (LLM) 结合…...