找项目网找项目网  2023-05-21 00:07 找项目网 隐藏边栏 |   抢沙发
导语: 代码和手动设置参数以及获取结果集。解决:Mybatis自动将java对象映射至sql语句。解决:Mybatis自动将sql执行结果映射至java对象。Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

mybatis主键生成策略_mybatis uuid主键_mybatis获取自动生成的主键

@$MyBatis是什么?

MyBatis 是一款优秀的持久层框架,一个半 ORM(对象关系映射)框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。

为什么说Mybatis是半自动ORM映射工具?它与全自动的区别在哪里?

ORM(Object Relational Mapping),对象关系映射,是一种为了解决关系型数据库数据与简单Java对象(POJO)的映射关系的技术。

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。

Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具。

JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的?

1、频繁创建、释放数据库连接对象,容易造成系统资源浪费,影响系统性能。可以使用连接池解决这个问题。

解决:在mybatis-config.xml中配置数据库连接池,使用连接池管理数据库连接。

2、Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

解决:将Sql语句配置在XXXXmapper.xml文件中,与java代码分离。

3、向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。

解决:Mybatis自动将java对象映射至sql语句。

4、对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

解决:Mybatis自动将sql执行结果映射至java对象。

Mybatis优缺点

优点

与传统的数据库访问技术相比,ORM有以下优点:

缺点

MyBatis框架适用场景

@$Hibernate 和 MyBatis 的区别

相同点

都是对jdbc的封装,都是持久层的框架,都用于dao层的开发。

不同点

映射关系

SQL优化和移植性

开发难易程度和学习成本

总结

MyBatis 是一个小巧、方便、高效、简单、直接、半自动化的持久层框架,

Hibernate 是一个强大、方便、高效、复杂、间接、全自动化的持久层框架。

@$请说说MyBatis的工作原理

在学习 MyBatis 程序之前,需要了解一下 MyBatis 工作原理,以便于理解程序。MyBatis 的工作原理如下图

mybatis获取自动生成的主键_mybatis主键生成策略_mybatis uuid主键

1)读取 MyBatis 配置文件:mybatis-config.xml 为 MyBatis 的全局配置文件,包含了 MyBatis 行为的设置和属性信息,例如数据库连接信息和映射文件。

2)加载映射文件mapper.xml。映射文件即 SQL 映射文件,该文件中配置了操作数据库的 SQL 语句,需要在 MyBatis 配置文件 mybatis-config.xml 中加载。mybatis-config.xml 文件可以加载多个映射文件,每个文件对应数据库中的一张表。

3)构造会话工厂:通过 MyBatis 的环境等配置信息构建会话工厂 SqlSessionFactory。

4)创建会话对象:由会话工厂创建 SqlSession 对象,该对象中包含了执行 SQL 语句的所有方法。

5)Executor 执行器:MyBatis 底层定义了一个 Executor 接口来操作数据库,它将根据 SqlSession 传递的参数动态地生成需要执行的 SQL 语句,同时负责查询缓存的维护。

6)MappedStatement 对象:在 Executor 接口的执行方法中有一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的 SQL 语句的 id、参数等信息。

7)输入参数映射:输入参数类型可以是 Map、List 等集合类型,也可以是基本数据类型和 POJO 类型。输入参数映射过程类似于 JDBC 对 preparedStatement 对象设置参数的过程。

8)输出结果映射:输出结果类型可以是 Map、 List 等集合类型,也可以是基本数据类型和 POJO 类型。输出结果映射过程类似于 JDBC 对结果集的解析过程。

MyBatis的架构设计是怎样的

mybatis主键生成策略_mybatis uuid主键_mybatis获取自动生成的主键

我们把Mybatis的功能架构分为四层:

为什么需要预编译

SQL 预编译指的是数据库驱动在发送 SQL 语句和参数给 数据库 之前对 SQL 语句进行编译,这样 数据库 执行 SQL 时,就不需要重新编译。

JDBC 中使用对象 PreparedStatement 来抽象预编译语句,使用预编译。预编译阶段可以优化 SQL 的执行。预编译之后的 SQL 多数情况下可以直接执行,数据库 不需要再次编译,Mybatis在默认情况下,将对所有的 SQL 进行预编译。

@$#{}和${}的区别

模糊查询like语句该怎么写

(1)'%${question}%' 可能引起SQL注入,不推荐

(2)"%"#{question}"%" 注意:因为#{...}解析成sql语句时候,会在变量外侧自动加单引号' ',所以这里 % 需要使用双引号" ",不能使用单引号 ' ',不然会查不到任何结果。

(3)CONCAT('%',#{question},'%') 使用CONCAT()函数,推荐

(4)使用bind标签

<span role="presentation" style="padding-right: 0.1px"><span><</span><span>select</span> <span>id</span>=<span>"listUserLikeUsername"</span> <span>resultType</span>=<span>"com.jourwon.pojo.User"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px">  <span><</span><span>bind</span> <span>name</span>=<span>"pattern"</span> <span>value</span>=<span>"'%' + username + '%'"</span> <span>/></span></span><br /><span role="presentation" style="padding-right: 0.1px">  select id,sex,age,username,password from person where username LIKE #{pattern}</span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>select</span><span>></span></span>

@$如何获取生成的主键

对于支持主键自增的数据库(MySQL)

<span role="presentation" style="padding-right: 0.1px"><span></span></span><br /><span role="presentation" style="padding-right: 0.1px"><span><</span><span>insert</span> <span>id</span>=<span>"insertUser"</span> <span>useGeneratedKeys</span>=<span>"true"</span> <span>keyProperty</span>=<span>"userId"</span> <span>></span></span><br /><span role="presentation" style="padding-right: 0.1px">    insert into user( </span><br /><span role="presentation" style="padding-right: 0.1px">    user_name, user_password, create_time) </span><br /><span role="presentation" style="padding-right: 0.1px">    values(#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})</span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>insert</span><span>></span></span>

parameterType 可以不写,Mybatis可以推断出传入的数据类型。如果想要访问主键,那么parameterType 应当是java实体或者Map。这样数据在插入之后可以通过java实体或者Map来获取主键值。

不支持主键自增的数据库(Oracle)

对于像Oracle这样的数据,没有提供主键自增的功能,而是使用序列的方式获取自增主键。

可以使用<selectKey>标签来获取主键的值,这种方式不仅适用于不提供主键自增功能的数据库,也适用于提供主键自增功能的数据库<selectKey>标签一般的用法

<span role="presentation" style="padding-right: 0.1px"><span><</span><span>insert</span> <span>id</span>=<span>"insertUser"</span> <span>></span></span><br /><span role="presentation" style="padding-right: 0.1px"><span role="presentation" style="font-family: var(--monospace)">    </span><span><</span><span>selectKey</span> <span>keyColumn</span>=<span>"id"</span> <span>resultType</span>=<span>"long"</span> <span>keyProperty</span>=<span>"userId"</span> <span>order</span>=<span>"BEFORE"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px"><span role="presentation" style="font-family: var(--monospace)">    </span><span role="presentation" style="font-family: var(--monospace)">    </span>SELECT USER_ID.nextval as id from dual </span><br /><span role="presentation" style="padding-right: 0.1px"><span role="presentation" style="font-family: var(--monospace)">    </span><span></</span><span>selectKey</span><span>></span> </span><br /><span role="presentation" style="padding-right: 0.1px">insert into user( </span><br /><span role="presentation" style="padding-right: 0.1px">user_id,user_name, user_password, create_time) </span><br /><span role="presentation" style="padding-right: 0.1px">values(#{userId},#{userName}, #{userPassword} , #{createTime, jdbcType= TIMESTAMP})</span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>insert</span><span>></span></span>

属性描述

keyProperty

selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

keyColumn

匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

resultType

结果的类型,MyBatis 通常可以推算出来。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。

order

值可为BEFORE 或 AFTER。如果是 BEFORE,那么它会先执行selectKey设置 keyProperty 然后执行插入语句。如果为AFTER则相反。

statementType

使用何种语句类型,默认PREPARED。有STATEMENT,PREPARED 和 CALLABLE 语句的映射类型。

此时会将Oracle生成的主键值赋予userId变量。这个userId 就是USER对象的属性,这样就可以将生成的主键值返回了。如果仅仅是在insert语句中使用但是不返回,此时keyProperty=“任意自定义变量名”,resultType 可以不写。Oracle 数据库中的值要设置为 BEFORE ,这是因为 Oracle中需要先从序列获取值,然后将值作为主键插入到数据库中。

扩展

如果Mysql 使用selectKey的方式获取主键,需要注意下面两点:

order :AFTER

获取递增主键值 :SELECT LAST_INSERT_ID()

@$当实体类中的属性名和表中的字段名不一样 ,怎么办

第1种:通过在查询的SQL语句中定义字段名的别名,让字段名的别名和实体类的属性名一致。

<span role="presentation" style="padding-right: 0.1px"><span><</span><span>select</span> <span>id</span>=<span>"getOrder"</span> <span>parameterType</span>=<span>"int"</span> <span>resultType</span>=<span>"com.jourwon.pojo.Order"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px">       select order_id id, order_no orderno ,order_price price form orders where order_id=#{id};</span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>select</span><span>></span></span>

第2种:通过来映射字段名和实体类属性名的一一对应关系。

<span role="presentation" style="padding-right: 0.1px"><span><</span><span>select</span> <span>id</span>=<span>"getOrder"</span> <span>parameterType</span>=<span>"int"</span> <span>resultMap</span>=<span>"orderResultMap"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px">select * from orders where order_id=#{id}</span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>select</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px"></span><br /><span role="presentation" style="padding-right: 0.1px"><span><</span><span>resultMap</span> <span>type</span>=<span>"com.jourwon.pojo.Order"</span> <span>id</span>=<span>"orderResultMap"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px">    </span><br /><span role="presentation" style="padding-right: 0.1px">    <span><</span><span>id</span> <span>property</span>=<span>"id"</span> <span>column</span>=<span>"order_id"</span><span>></span></span><br /><span role="presentation" style="padding-right: 0.1px"></span><br /><span role="presentation" style="padding-right: 0.1px">    </span><br /><span role="presentation" style="padding-right: 0.1px">    <span><</span><span>result</span> <span>property</span> =<span>"orderno"</span> <span>column</span> =<span>"order_no"</span><span>/></span></span><br /><span role="presentation" style="padding-right: 0.1px">    <span><</span><span>result</span> <span>property</span>=<span>"price"</span> <span>column</span>=<span>"order_price"</span> <span>/></span></span><br /><span role="presentation" style="padding-right: 0.1px"><span></</span><span>reslutMap</span><span>></span></span>

什么是MyBatis的接口绑定?有哪些实现方式?

接口绑定mybatis获取自动生成的主键,就是在MyBatis中任意定义接口,然后把接口里面的方法和SQL语句绑定,我们调用接口方法的时候,最终会执行绑定的SQL语句。

接口绑定有两种实现方式,当Sql语句比较简单时候,可以使用注解绑定,当SQL语句比较复杂时候,一般用xml绑定的比较多。

@$使用MyBatis的mapper接口调用时有哪些要求?

最佳实践中,通常一个Xml映射文件,都会写一个Dao接口与之对应,请问,这个Dao接口的工作原理是什么?Dao接口里的方法,参数不同时,方法能重载吗

Dao接口,就是人们常说的Mapper接口,接口的全限名,就是映射文件中的namespace的值,接口的方法名,就是映射文件中MappedStatement的id值,接口方法内的参数,就是传递给sql的参数。Mapper接口是没有实现类的,当调用接口方法时,接口全限名+方法名拼接字符串作为key值mybatis获取自动生成的主键,可唯一定位一个MappedStatement

举例:com.mybatis3.mappers.StudentDao.findStudentById,可以唯一找到namespace为com.mybatis3.mappers.StudentDao下面id = findStudentById的MappedStatement。在Mybatis中,每一个、、、标签,都会被解析为一个MappedStatement对象。

Dao接口里的方法,是不能重载的,因为是全限名+方法名的保存和寻找策略,需要保证全限名+方法名的唯一性。

Dao接口的工作原理是JDK动态代理,Mybatis运行时会使用JDK动态代理为Dao接口生成代理对象proxy,代理对象proxy会拦截接口方法调用,转而执行方法对应的sql语句,然后将sql执行结果返回。

MyBatis动态sql是做什么的?都有哪些动态sql?能简述一下动态sql的执行原理不?

Mybatis动态sql可以让我们在xml映射文件内,以标签的形式编写动态sql,完成逻辑判断和动态拼接sql的功能,Mybatis提供了9种动态sql标签trim|where|set|foreach|if|choose|when|otherwise|bind。

其执行原理为,使用OGNL从sql参数对象中计算表达式的值,根据表达式的值动态拼接sql,以此来完成动态sql的功能。

MyBatis是如何进行分页的?分页插件的原理是什么?

Mybatis使用RowBounds对象进行分页,它是针对ResultSet结果集执行的内存分页,而非物理分页,可以在sql内直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

分页插件的基本原理是使用Mybatis提供的插件接口,实现自定义插件,通过jdk动态代理在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和参数。

举例:select * from student,拦截sql后重写为:select t.* from (select * from student) t limit 0, 10

@$简述MyBatis的插件运行原理,以及如何编写一个插件。

Mybatis仅可以编写针对Executor、StatementHandler、ParameterHandler、ResultSetHandler这4种接口的插件,Mybatis使用JDK的动态代理,为需要拦截的接口生成代理对象以实现接口方法拦截功能,每当执行这4种接口对象的方法时,就会进入拦截方法,具体就是InvocationHandler的invoke()方法,当然,只会拦截那些你指定需要拦截的方法。

实现Mybatis的Interceptor接口并重写intercept()方法,然后在给插件编写注解,指定要拦截哪一个接口的哪些方法即可,最后在配置文件中配置你编写的插件。

@$MyBatis的一级、二级缓存

1)一级缓存: 基于 PerpetualCache 的 HashMap 本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该 Session 中的所有 Cache 就将清空,MyBatis默认打开一级缓存。

2)二级缓存与一级缓存机制相同,默认也是采用 PerpetualCache,HashMap 存储,不同之处在于其存储作用域为 Mapper(Namespace),并且可自定义存储源,如 Ehcache。默认不打开二级缓存,要开启二级缓存,使用二级缓存属性类需要实现Serializable序列化接口(可用来保存对象的状态),可在它的映射文件中配置 标签;

3)对于缓存数据更新机制,当某一个作用域(一级缓存 Session/二级缓存Namespaces)进行了C/U/D 操作后,默认该作用域下所有缓存将被清理掉。

mybatis uuid主键_mybatis主键生成策略_mybatis获取自动生成的主键

END

点个在看你最好看

———END———
限 时 特 惠:本站每日持续更新海量各大内部创业教程,一年会员只需128元,全站资源免费下载点击查看详情
站 长 微 信:jiumai99

1.本站内容观点不代表本站立场,并不代表本站赞同其观点和对其真实性负责 2.若作商业用途,请联系原作者授权,若本站侵犯了您的权益请 联系站长 进行删除处理 3.本站所有内容均来源于网络,仅供学习与参考,请勿商业运营,严禁从事违法、侵权等任何非法活动,否则后果自负
找项目网
找项目网 关注:0    粉丝:0
这个人很懒,什么都没写

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享