当前位置: 首页 > news >正文

晋城市网站建设_网站建设公司_服务器维护_seo优化

国内出名网站建设设计公司,wordpress如何设置伪静态,公司官网建设多少钱,秀网站模板JavaEE平台技术——MyBatis 1. 对象关系映射框架——Hibernate、MyBatis2. 对象关系模型映射3. MyBatis的实现机制4. MyBatis的XML定义5. Spring事务 在观看这个之前#xff0c;大家请查阅前序内容。 #x1f600;JavaEE的渊源 #x1f600;#x1f600;JavaEE平台技术——… JavaEE平台技术——MyBatis 1. 对象关系映射框架——Hibernate、MyBatis2. 对象关系模型映射3. MyBatis的实现机制4. MyBatis的XML定义5. Spring事务 在观看这个之前大家请查阅前序内容。 JavaEE的渊源 JavaEE平台技术——预备知识Web、Sevlet、Tomcat JavaEE平台技术——预备知识Maven、Docker JavaEE平台技术——Spring和Spring Boot 1. 对象关系映射框架——Hibernate、MyBatis MyBatis这样的一个框架主要是用来做面向对象和面向关系的映射的。 它的起源可以追溯到后端系统设计过程中的面向对象方法。 在软件设计领域面向对象的设计方式是经过多个阶段的演变发展的。 在需求分析阶段中我们会确定主要操作者并定义其操作目标。随后我们将根据需求分析的结果进行领域模型建模。 面向对象设计的目的不仅仅是实现已知功能而更重要的是捕捉这些功能背后的概念和属性。通过理解这些概念我们不仅能够完成当前已知的功能而且能够在不违背基本模型的前提下扩展和发展未来的功能。 因此这一阶段是面向对象模型设计中的一个关键步骤我们从需求分析到领域建模一直都在贯彻这一思想。在这之后我们会进行面向对象的详细设计过程。 在面向对象的详细设计过程中第一步是构建对象模型。这一步并非关乎功能的实现而是从领域模型中推导出对象模型。对象模型与领域模型有着相似之处但在构建对象模型时我们通常会做出一些折中考虑。这包括根据具体技术要求明确对象之间的关系定义对象的属性以及判断属性是否应具有一定的冗余等。无论考虑了哪些因素最终的结果是我们在面向对象设计中处理的是对象而不是数据。对象意味着这些实体具有属性和方法它们之间存在关联关系和继承关系。在处理对象时我们并不是像处理数据那样孤立地获取一个个单独的数据而是获得一系列关联的对象。 举个例子当我们获得一个商品时我们也能够获取与之关联的其他商品。我们获得一个商品同时了解其当前的有效价格以及可能的促销活动。因此对象并非孤立存在而是相互关联的实体。 在内存中存储有关联关系的对象确实没有问题但是当前我们面临的挑战是我们需要处理的对象数量非常庞大。举例来说就我们电子商城而言仅商品一项就可能达到成千上万甚至几十万的数量。而针对每个商品的历史价格以及每个商品可能产生的众多订单需要乘以更大的系数。因此在我们的系统中要将所有对象都加载到内存中并建立它们的关联关系供我们使用是不可能的。 唯一可行的解决办法就是将这些对象存储到外部存储器中。当然有许多种外部存储方式可供选择。最成熟的存储方式众所周知就是关系数据库因为它已经存在了几十年并且在工业应用中已经得到了广泛验证。对于关系数据库的性能我们已经非常清楚它能够实现什么以及它的局限性。此外关系数据库提供了强大的搜索能力。 AAAAA 关系数据库有其自身的限制。其中最主要的限制之一是必须符合关系数据库的范式定义。 在定义关系数据库时必须遵循关系数据库的范式。因为众所周知如果不符合关系数据库范式你的程序在运行时会出现数据问题。与对象模型相比关系数据库的这些限制存在着明显差异。因为在对象模型中我们从不考虑范式问题对象模型的设计方式是根据实用性来进行设计和组织的。因此它的设计方式与组织方式与关系数据库完全不同。 这就需要一个工具即对象关系映射框架。该框架的作用是将我们存储在关系数据库中的数据转换成对象供我们使用。当我们使用完这些对象后如果我们不再需要它们我们仍然需要将它们存回数据库中。这是因为我们可能已经对它们的值、关系以及许多其他特性进行了更改需要将这些更改存回数据库。 这就是对象关系映射工具要做的事情它负责维护关系数据库中的数据与内存中对象模型之间的对应关系。我们需要从数据库中提取对象模型使用完毕后将其存回数据库。在需要时可以再次提取出来。 这样的一个对象模型的一种框架其实市面上主要就是两种: 全自动就是我们只要定义好这个对象有什么类类的关系是什么类的属性是什么然后由这个框架自己把它存到数据库里去我们甚至都不知道它数据表长什么样我们也不知道那个数据表之间的关系是什么什么都不用管我们只要找这个框架跟它说我要什么样对象它就从数据库里给它捞出来注意不是捞出来是一个对象是捞出来一系列有联系的对象然后我们就可以去用它用完了以后如果改变了这个对象的属性或者改变了对象的关系告诉它你再存回去它就把它存回去所以这就是一个全自动的框架。 通常来说Hibernate是一种最常用的全自动框架。对于开发人员来说这种全自动框架肯定非常简便因为我们完全不必担心它在数据库方面的实现。我们所看到的仅仅是一个对象模型我们使用的这个对象模型由框架负责完成对象模型与关系模型之间的转换。然而这种全自动框架的副作用是如果一切都自动完成的话那它一定不可能是最优的结果。 对于我们的应用来说99%的事情自动完成是没有问题的。因为大家也相信Hibernate是一个非常成熟的框架并且被广泛使用99%的事情在Hibernate上都可以自动完成。然而有1%的事情自动完成并不一定是最佳的结果而这1%可能会成为我们的瓶颈。 我们的系统就像一个木桶它遵循着短板原则那个最脆弱的地方往往是最频繁使用的地方。如果卡住你脖子的地方并不是经常用的话它的危害性并不是很大因为即便速度慢一些由于使用频率不高影响也不会很大。然而如果这个瓶颈正好出现在你最常用的地方并且你又想将其存储到关系数据库中你就必须进行手工优化。 手工优化的结果肯定比自动处理的结果要更优。但在Hibernate中进行手工优化相对有些麻烦因为一开始我们完全不了解它是如何映射的一直把它当作一个对象模型来使用。突然有一天你想要进行手工优化就必须先理解Hibernate的默认映射方式然后通过编写原生的SQL语句来改变它的默认映射方式以进行优化。如果发现默认映射方式无法解决问题必须修改默认映射方式的话问题就会变得更加复杂。因为不仅仅需要修改这个特定的点所有使用到这个地方的点都需要进行修改。 虽然Hibernate能解决99%的问题但如果恰好碰到这1%的问题成为瓶颈又必须解决的话使用Hibernate就会变得有些棘手。这就是Hibernate所存在的问题。 -MyBatis是一种半自动化的框架与Hibernate相比它同样能够完成对象模型和关系模型之间的映射 。两者的不同之处在于Hibernate不让你知道它的内部运作方式而MyBatis将所有细节都公之于众毫无保留地展示给你。你能清楚地了解它的每一个细节无需查看相关文档或了解默认行为因为MyBatis将所有细节都清晰地展示出来。 这种特性使得如果你不想对其进行更改它会保持不变因为你也不需要去修改它。然而如果你想进行修改你就可以轻松地进行调整因为你清楚地知道所有的工作原理以及对其进行更改可能产生的影响。如果需要进行修改就好像修理一台机器一样MyBatis将所有细节都呈现在外面这使得修理变得更加容易。 在中国由于市场的特殊性流量是至关重要的。无论是大公司还是小公司都希望尽可能地获得收益。因此对于互联网公司来说如何以最小的资源来承载最大的流量是一个至关重要的问题。MyBatis在国内得到广泛应用因为所有的公司都希望通过最有效的方式来获得最大的收益。对于我们来说在MyBatis上进行优化可能会很困难因为改动可能会变得相当复杂和繁琐。但是考虑到流量的重要性解决这些困难带来的收益是非常巨大的。因此特别是在国内的互联网公司中MyBatis是一个非常常见的框架几乎占据了90%以上的应用。 2. 对象关系模型映射 对象模型和关系模型之所以能映射是因为它存在着一定的相似性。 面向对象模型关系模型类表对象记录属性列对象ID主键关联关系外键继承关系不支持方法不支持 面向对象的类可以派生出很多的对象类中间定义的属性在不同对象上面的值是不一样的表可以塞很多记录表的字段每一个记录都可以是不同的值所以你会发现类跟表记录跟对象对象跟记录属性跟表的列天然就有这样的一个对应关系所以前三者是非常好对应到一起去的。 在面向对象和关系数据库的映射框架中存在着一个特殊的问题我们无法将所有对象都放入内存中。如果将所有对象都放入内存那么用于标识对象唯一性的是什么呢 大家都知道在面向对象中比较两个对象是否相等通常不是比较它们的属性是否相等而是比较它们在内存中的地址是否相等。由于我们无法将所有对象都放入内存因此我们如何判断一个对象和另一个对象是相等的特别是在判断对象与数据库中的某条记录是否对应时我们依赖于一个特定的属性通常称为ID。 在数据库中这个ID通常是主键。在类中它是一个普通的属性通常是一个长整型属性。我们使用这个属性来标识面向对象模型中的一个对象和数据库中的一条记录之间的对应关系。由于对象并不全部在内存中当我们需要一个对象时我们会告诉OR Mapping框架使用ID来获取它。如果我们对从面向对象模型中获取的某个对象进行操作修改它的属性或关系最终我们需要将这个对象存入数据库中。由于无法让对象永远待在内存中因为内存容量有限我们需要使用ID来确定该对象对应数据库中的哪条记录。 因此在面向对象模型中为了实现映射我们引入了一个特别的属性称为ID长整型。我们在数据库中为该属性定义了一个名为ID的字段也是一个长整型。在关系数据库中主键具有特殊的含义因为整个表中的数据都是按照主键进行存储的。通过主键可以快速定位到存储的数据。因此使用主键来访问数据库中的记录是最快的方式没有比它更快的方式了。因此我们使用主键作为条件来查找数据库中的记录。我们将对象中的属性作为唯一标识对象的方式不再是比较它们的内存地址是否相同而是比较它们的属性ID是否相同。如果属性ID相同我们就认为这两个对象是相同的。如果该对象存在于数据库中我们就去查找具有相同ID值的记录并确保其与我们的对象模型中的属性保持一致。这就是我们使用属性ID在数据库中作为主键来维持它们之间映射关系的方式。 在对象模型中最有趣的部分通常涉及对象之间的关联关系和继承关系。简而言之对象关系的设计源泉在于对象模型中的关系。如果我们仅仅将对象定义为属性、方法和类它将缺乏趣味性而所有的精彩之处都存在于对象之间的关系包括关联关系和继承关系。 关联关系可以使用外键来自然表示。数据库中的外键用于表述两条记录之间的关系类似地两个对象之间的关联关系无论是一对一、一对多还是多对多都可以使用外键来表示。 然而继承关系更为复杂因为它不像关联关系那样直接映射而且在面向对象编程中继承关系具有多态性多态性是面向对象编程的一个显著特点。 多种设计原则如Liskov替代原则等都建立在多态性的基础上。如果无法实现多态性面向对象模型的价值就会大打折扣。因此在关系数据库中我们必须使用一种妥协的方式来支持继承关系以使其成为真正的OR Mapping工具。 需要注意的是对象模型中的方法不需要存储在数据库中因为方法是在类的定义中声明的对象的方法都是一样的只是对象的行为。不同的对象具有相同的方法因为它们属于同一类所以方法的定义通常在代码中。对象的定义存在于类的代码中而对象的数据则是从数据库中获取的。对象之间的关系包括关联关系和继承关系都需要进行映射而不需要映射方法。 方法就在那个Java的代码的类的定义里头。所以我们类的定义是在代码中间对象是由类产生的对象的值是从数据库里给它捞出来的无论是关联关系还是继承关系这是我们的这样的一个映射关系。 面向对象模型关系模型类表对象记录属性列对象ID主键关联关系外键继承关系不支持方法不支持 那我们最头疼的就是这个继承关系继承关系在数据库里头是没有关系数据库里是没有直接的映射的。 另一种方式是使用多张表将父类和子类的属性分别存储在不同的表中。在这种情况下每个子类会有一个独立的表其中包含它自己的属性同时也会包含从父类继承的属性。这种方式能够更好地保持数据库的结构整洁同时也有利于提高数据库的查询效率。 对于任何一类对象例如RoadVehicle它在数据库表中的记录实际上只有四个属性具有值其他属性都是空的。对于Car这类对象它除了自身的属性之外还会继承RoadVehicle的四个属性其他属性仍然是空的。为了实现这样的继承关系存储方案我们需要一个特殊的属性来描述对象所属的类别。在此方案中我们首先使用ID来建立对象与数据记录之间的一对一关系然后使用一个属性来标识它属于哪个类别。除此之外所有属性都是这些对象的属性。 在这种继承关系的存储方案中我们如何实现继承关系的特性呢 比如说当我们获取一个Car对象时我们需要得到一个具有5个属性的Car对象。因此当我们从数据库中进行查询时我们会选择检索一条记录而这条记录的类型是Car类型。然后我们会使用Java的反射机制来实例化这个Car对象。通过反射机制我们可以读取Car对象的属性并将数据库中检索到的字段值对应到Car对象的属性上。尽管Car对象本身只有5个属性但实际上从数据库中检索出的可能是更多的属性但我们只需要这些对应的属性。通过确保匹配我们可以实例化Car对象即使所有的属性都存储在同一张表中我们也可以根据DISC类型来正确地实例化该对象。 我们在关系和对象模型映射中它怎样来实现的呢 在使用单表来实现继承关系时我们可以通过执行不带条件的select语句来将所有对象的属性都检索出来。这将返回数据库中的多条记录每条记录都包含对象的所有属性。接着我们根据每条记录中的DISC属性使用Java的反射机制来实例化相应的子类对象。这些实例化后的子类对象将被放入一个集合中而这个集合的元素类型被定义为RoadVehicle对象。实际上这些元素是具体的子类型。通过这种方式返回的集合对象是父类对象但实际上却是子类对象因此可以展现出多态的特征。如果希望实现多态可以将其强制转换为父类型并将其放入集合中。 AAAAA 使用单表来实现继承关系的另一种方式是每个类对应一张表。在这种情况下实例化对象可能会稍微复杂一些因为需要对每张表进行单独的检索。 在多表的模式下实例化一个对象比如Car对象需要在多张表之间进行查询并将多张表的记录合并为最终结果。这种方式的实现在关系数据库中较为常见尤其在处理继承关系时会采用这种方式。举例来说假设我们有一个RoadVehicle表其中包含了Motorcycle的一条记录而Motorcycle表中也有一条记录。通过使用它们的ID进行关联我们可以在Motorcycle表中找到与之相关的记录并将两张表的属性合并从而得到最终的Motorcycle对象。 然而这种方法存在一个问题即在实例化对象时需要进行多次连表查询特别是当对象的实例化需要多个连表操作时查询的成本会更高。与单表模式相比多表模式需要进行更多的查询操作因此查询速度会受到较大的影响。需要注意的是尽管在存储继承关系时Hibernate和MyBatis等框架默认采用多表模式但在面对大量数据或高负载系统时开发人员可能需要手动优化查询性能以减少查询成本和提高系统的整体性能。 这是继承关系我们可以看到用关系数据表用一种特定的方式我们能够把继承关系的完整的特性能够把它存下来然后把它实际化出对象来要能把它表现出它的完整特性关联关系呢我们分为一对一一对多多对一。 一对一的话。 订单和快递单之间的关系通常是一对一的。当我们需要考虑这种关系时有一个重要的方向问题需要注意即是从订单到快递单的访问频率通常比从快递单到订单的访问频率要高。出于提高查询速度的考虑我们可以在订单表中将快递单的ID作为外键进行存储。这种做法的好处在于利用主键访问的速度较快。通过查找订单记录我们可以快速找到与之对应的快递单的主键ID然后使用该主键ID在快递单表中找到对应的记录最终我们可以得到订单对象和快递单对象两者之间形成了关联。这样实例化出来的对象既包含订单对象又包含快递单对象通过这种方式我们可以迅速地了解订单所对应的快递轨迹。 在面向对象模型中当我们获取一个订单对象时它并不是一个孤立的对象而是一个与其他对象相关联的对象。这意味着我们的逻辑应该基于有联系的对象来构建而不是通过获取一个订单对象后再去查询数据库以获取其他对象。这种面向对象的方式要求我们建立具有关联性的对象并在这些关联对象上进行业务逻辑的处理。 我们已经讨论了从订单到快递单的方向那么从快递单到订单呢实际上我们的对象模型可以实现双向关联。当我们获取一个快递单对象时我们可以通过查询数据库得到与之相关的订单。这种双向关联的实现是可行的。然而需要注意的是由于查询过程中涉及到外键的查询相对于主键查询而言会更加耗时。在这种情况下索引的加入是必不可少的。索引的加入可以提高查询速度但即使使用了索引由于查询过程的复杂性仍然会比直接使用主键查询要慢一些。在实际应用中我们应该根据不同的业务需求和性能要求来选择合适的查询方向。 一对多和多对一的关系实际上正好是相互对应的两种关系。在关系数据库中存储这种关系时都具备这样的特征只要存储了其中一种关系就能够通过这种关系找到另外一种关系。无论是存储一对多还是多对一都可以通过已知的一端找到与之关联的多端或者通过多端找到与之关联的一端。这种对应关系可以方便地实现数据的检索和查询。上一到多下多对一 一对多和多对一的关系存储方式的选择通常取决于查询的方向和性能需求。 对于一对多关系如果你经常需要从一的一端查找多的多个对象那么使用一对多方式存储可能更有效因为可以通过一次非主键查询找到多端的对象然后做主键查询。反之多对一的方式则可以通过一次非主键查询直接找到一端的对象更加高效。 无论是Hibernate还是MyBatis它们通常默认使用一对多和多对一的方式来存储关联关系因为无论查询方向是哪一端这两种方式都提供了较好的性能。 但对于多对多的关系必须使用中间表来存储关联关系因为多对多关系不具备上述一对多和多对一的性能优势。 3. MyBatis的实现机制 使用Spring Boot和MyBatis来实现面向对象和关系的映射是一种常见的开发方式。当使用Spring Boot时通常可以通过引入适当的Starter包来轻松配置和使用MyBatis。 Spring Boot的Starter包是用于快速启动和配置特定功能的依赖项。通过引入MyBatis Starter包你可以在项目中轻松配置和使用MyBatis框架而无需手动引入和配置相关的Jar包和XML文件。 在Spring Boot项目中通常建议使用Spring Boot的自动配置来配置MyBatis。你只需提供MyBatis的Mapper接口和相应的SQL语句Spring Boot会自动配置数据源和MyBatis的SqlSessionFactory以及自动扫描并注册Mapper接口。这简化了配置过程使开发更加高效。 因此使用MyBatis Starter包是一个常见的实践可以帮助你更容易地集成MyBatis到Spring Boot项目中从而实现面向对象和关系的映射。不再需要手动引入和配置相关的Jar包和XML文件而是通过Starter包来完成自动化配置。 Starter包的好处在于它能够方便地引入一系列必要的依赖项。以MyBatis为例MyBatis是一个需要与数据库交互的OR Mapping工具。因此使用MyBatis时必然会涉及到与数据库的交互这就需要使用JDBC。此外如果要使用事务管理也需要引入事务支持。 如果没有Starter包那么这些依赖项就需要手动逐一引入。比如你想使用MyBatis但缺少了JDBCMyBatis将无法正常工作。如果需要使用事务管理你还需要额外引入事务管理的相关配置。这样的操作非常繁琐。 因此Spring Boot的Starter包在其中的作用非常明显。它将MyBatis相关的依赖一并引入包括JDBC和事务管理等。这样一来你只需引入MyBatis的Starter包就能自动获取所有相关的依赖项不需要手动一一引入和配置。这也是Spring Boot的革命性变化之一它能够方便地将相关的配置和依赖项一并引入使整个开发过程更加简单高效。 那我们看一下MyBatis的结构。 MyBatis的基本结构包括Mapper和配置文件。 在使用MyBatis时Mapper是主要的组件它是一系列方法的集合。每个Mapper都是一个接口定义了一些操作方法。通过这些Mapper提供的方法我们可以对对象模型进行操作。相比之下如果你熟悉Hibernate你会发现Hibernate根本就没有Mapper这一概念。 Hibernate会自动管理对象的更新如果你从Hibernate获取对象并修改了它的属性它会自动将修改更新到数据库中。但是MyBatis没有这种自动分配的功能它是半自动的。所有的操作都必须通过Mapper的方法来完成。 Mapper的方法针对关系数据库执行一些操作但它将传入和传出的数据都转换成了对象模型。这种映射是在Mapper的方法中完成的。 Mapper的方法的具体实现依赖于配置文件MyBatis有两种配置文件的写法 XML注解 虽然注解的写法出现得比XML晚但是目前来看大多数人还是更习惯使用XML。这是因为配置文件的编写通常会比较复杂如果使用注解的方式进行配置尤其是对于新手来说可能会感到有些困惑。 MyBatis在国内已经使用了十几到二十年因此很多老一辈的开发者都习惯使用XML配置。尽管大量的业界项目目前仍然采用XML配置但这并不意味着XML就是一个更好的选择。技术的整体趋势是朝向Annotation发展的。这是因为Annotation与代码一起编写你可以在方法的定义之前直接使用Annotation来描述它的映射关系使得映射关系和方法的使用更紧密地结合在一起。这样看起来更加方便。相比之下如果你选择使用XML来配置映射关系就会面临与最初所有使用XML的方式所面临的相同问题。你需要遵循默认的定义规范如果不符合默认规范就会导致找不到对应的XML或方法从而导致错误的发生。因此默认规范越多你在使用时就会感到越烦恼。 老一辈的开发者可能已经熟悉了这些默认规范所以更喜欢使用XML。而对于新手来说可能更喜欢使用Annotation。 无论使用XML还是Annotation都不影响我们使用自动生成的方式来完成映射。 因此MyBatis可以使用Annotation和XML来编写配置信息然后通过Mapper的方式向其他程序提供操作关系数据库的接口。Mapper是我们在MyBatis中定义的接口它的方法传入和传出的都是对象。 这些对象是如何映射到关系数据库中的以及我们如何操作数据库都在XML和Annotation中得到了明确定义。 因此MyBatis是一个半自动的框架它的工作原理和具体操作都是可以清楚地看到的。如果需要进行调优你可以根据实际情况选择使用Annotation或XML来编写配置以实现最优的结果。 Hibernate是一个完全自动化的框架你只需要从Hibernate中获取对象然后进行更改并将其存回去它会自动处理整个过程。你压根不需要关心它的具体实现细节。相比之下MyBatis需要连接数据库因此它的数据库设置是来自于Spring框架的。在Spring框架中我们会设置一个DataSource这是通常用来连接数据库的设置包括使用的数据库类型如MySQL、数据库驱动程序如MySQL的JDBC驱动程序、数据库的地址和IP、使用的数据库等等。 MyBatis框架实际上是从Spring框架中获取这个DataSource然后创建一个叫做SqlSessionFactory的对象。为什么叫做SqlSessionFactory呢 这是因为数据库的连接并不会在整个应用启动后立即建立。数据库连接实际上是有限的比如说我的数据库同时只能连接100个客户端。一般情况下我们的应用程序需要连接300个客户端但是当你的应用程序启动时并不是立即去连接数据库的。数据库连接是在需要的时候才去建立的使用完毕后会将其释放掉。这样对于数据库服务器来说更加友好你可以使用尽可能少的max connection来服务更多的客户端。 因此当MyBatis启动后它会创建一个SqlSessionFactory并将从Spring框架中获取的DataSource放入其中。这样就建立了一个连接数据库的过程使得数据库连接在需要时建立用完后释放提高了数据库服务器的使用效率。 **每当一个事务开始时MyBatis会通过SqlSessionFactory实例化出一个SqlSession来连接数据库。**它会使用DataSource中配置的信息来连接特定的数据库。在使用过程中我们实际上并不直接使用SqlSession我们使用的是由MyBatis框架实例化出来的Mapper对象。 Mapper对象实际上包含了我们在代码中定义的一些方法。你可以将Mapper对象视为一些Bean对象但实际上当你仔细研究MyBatis的原理时你会发现它不完全是Bean对象。这是因为你可能会定义非常多的Mapper对象这可能会让你对MyBatis是如何根据你的定义来实例化出这么多不同的Mapper对象感到好奇。如果你对此感兴趣你可以深入阅读MyBatis的内部工作原理它其实相当复杂。 这些Mapper对象通过实例化的SqlSession来实现对数据库的操作。SqlSession是一个固定的操作集它使用你在MyBatis中编写的标签和特定的Annotation来工作。MyBatis的Mapper中使用这些标签来描述Mapper应该如何工作。因此你的描述将使Mapper调用SqlSession中对应的方法并访问数据库以完成相应的操作。这就是MyBatis内部工作的原理。 Mapper对象是由Spring框架实例化出来的根据我们的定义来实例化出我们想要的Mapper对象。然后我们通过这个Mapper对象去调用SqlSession的方法来访问数据库。在Mapper中编写的内容实际上是调用SqlSession不同方法的描述。Mapper对象的实现是通过XML和Annotation的配置来完成的。 Mapper通常是一个接口我们需要在接口前面加上MyBatis的注解。在Spring的应用中我们可以使用各种注解包括来自MyBatis的注解。当我们写了这些注解之后MyBatis框架会根据这些信息来实例化Mapper对象并告诉它要完成什么样的操作。 Mapper接口的定义通常包含了一些方法的定义但是并没有具体的实现。具体的实现是通过XML或者Annotation的配置来完成的。在这里我们展示的是XML的例子。如果使用Annotation那么这些配置会写在方法前面通过一些复杂的Annotation标签来描述这个方法具体要完成的操作。 因此在MyBatis中Mapper的作用就是通过传入对象和返回对象来完成对象模型和关系模型之间的映射。具体的操作则是通过我们自己编写的SQL语句来实现的。 实际上在大多数情况下我们希望能够自动生成大部分的映射除非性能要求无法满足我们才会手动编写映射。 XML的一个问题在于它有一些默认的对应规则。比如我们在Mapper接口中定义了一个方法但是方法名本身是不能唯一标识一个方法的因为可以进行方法重载。因此在XML中ID、parameterType和resultType这三者结合起来才能唯一标识一个方法。如果其中有任何一处出错它就无法正确对应从而导致报错。这是XML的一个讨厌之处。 相比之下如果我们使用Annotation情况就会简单得多。Annotation只需要写在方法前面告诉它这个方法应该做什么。因此它不需要遵循那些默认规则。这就是为什么Annotation可能会成为替代XML的一种做法因为它避免了那些默认规则而且更加直观。 然而Annotation的缺点在于对于一些复杂的情况它可能变得更加复杂。相比之下XML至少是格式化的可以进行缩进而Annotation可能没有这些格式化的选项。因此如果使用Annotation来编写一段复杂的内容可能会显得很难看。 所以我不排斥大家使用Annotation只要你能够熟练使用它。但是很多老手们仍然喜欢使用XML。对于XML部分我不打算过多深入讲解我只想让大家理解在Mapper中的每个方法中传入对象和传出对象是如何工作的可以通过使用Annotation和XML来完成这些工作。 4. MyBatis的XML定义 数据库操作通常涉及四种基本操作即增删改查INSERT、UPDATE、DELETE、SELECT。这些操作对应了SqlSession中的一些操作。在这些操作中使用不同的标记来指明操作类型如SELECT、INSERT等。 SELECT操作SELECT用于从数据库中检索数据。它通常伴随着一个ResultMap这是一个复杂的映射规则将数据库表和对象模型之间的关系互相映射。SELECT操作的ID对应了在Mapper中定义的方法名参数是需要传递给SQL的值返回值是SQL查询的结果对象。 INSERT操作INSERT用于向数据库中插入新数据。参数通常对应了插入数据的字段值。特别之处在于如果有自增字段需要将这个字段的值返回因此在Mapper接口中的方法参数中会有一个对象其属性对应了插入数据的字段但ID属性的值通常为空因为数据库会自动生成。 DELETE操作DELETE用于从数据库中删除数据。DELETE的SQL语句需要你手动编写以及与Mapper接口方法的映射关系。与其他操作不同DELETE不会自动生成返回值。 这些操作中的SQL语句可以使用动态SQL来处理特殊情况例如在WHERE子句中添加条件时需要对参数进行判断。此时可以使用动态SQL来动态构建SQL语句以避免不必要的条件。在动态SQL中你可以使用IF、TRIM等标签来处理特定条件和构建SQL查询。 此外还有一种复杂的情况涉及多个关联对象和继承关系。在这种情况下使用ResultMap和特定的映射规则可以帮助你正确映射数据库表和对象模型之间的复杂关系。 总之MyBatis提供了强大的数据库操作工具可以用于执行各种数据库操作从基本的增删改查到复杂的条件构建和对象关系映射。虽然你可以手动编写SQL语句和映射规则但MyBatis还提供了很多便捷的方式来处理这些问题使数据库操作更高效和易于维护。 5. Spring事务 AAAAA 在工程开发中配置文件通常都存放在application.yaml中。让我们来看一些具体的例子来解释。最后我们来讨论一个问题即XML和注解都难以编写。 实际上我们有工具可以生成简单的XML和注解。如果你对对象模型没有特别要求比如你不关心它们之间的关联关系而是将所有对象视为孤立的表和对象则可以直接使用工具来生成。因为这不需要费脑子手动编写会显得有些浪费通常我们使用一些半自动化的工具。 在这些工具中有些是非常自动化的有些则不太自动化。我们选择了中间的方式因为很多事情我们还需要自己手动编写。我们希望能够通过工具将表映射为类将记录映射为对象以及在XML中描述如何将表映射为PO对象。此外我们还提供了一个Mapper用于针对单个对象的增删改查。这就是我们所说的工具。 这里引出了另一个问题即对象模型的构建是在Mapper层完成还是在DAO层完成。如果我们计划在DAO层完成对象模型的构建那么Mapper就只负责将表变为对象。对象之间的关系由DAO层处理。那么到底应该选择哪种方案呢是由Mapper层完成所有的映射关系还是只将对象拿出来然后在DAO层建立关系呢 这两种方式的选择取决于性能是否有差异。如果性能没有差异我们会选择使用Java代码来编写因为Java代码是可以进行错误验证的。我们可以使用测试工具来验证通过Java代码编写的部分是否经过测试从而确定编码是否没有问题。然而XML和注解却无法做到这一点。 因此如果两者性能相同我们会选择使用Java代码来完成这一过程。如果使用Java代码来完成MyBatis就变成了一个最简单的工具它只负责将对象变为记录而不会产生对象为两条记录、继承关系和关联关系等复杂性。这些都由DAO层来完成。因此我们可以使用生成器工具来生成这些内容。如果你这样做实际上使用MyBatis和Hibernate就没有差别了因为你也不会使用它们复杂的功能你只是希望每个类对应一张表每个对象对应一条记录而没有其他关联。这就是我们引入MyBatis生成器插件的原因。 这个插件并不是我们程序中要使用的它只是用来生成代码的。因此我们在plugins中将这个插件与我们的任何一个phase没有关联。它只是一个独立的插件你可以在plugins中运行它。它的配置文件在configurationFile中。关于这个插件的使用方法我在视频中也不打算讲解因为关于这个东西的用法我已经写得非常繁琐了。 基本上你可以理解注释的意思都有中文注释。大家可以自己看。最后让我们来谈谈事务。 我们知道在处理高并发时一定需要使用事务。事务解决的问题是当多人同时访问同一条数据时它要保证数据的一致性。数据库中的ACID是这种解决问题的最简单和直接的方式。它意味着只要你的操作都在一个事务中要么都成功要么都失败。如果两个人同时访问同一条数据各自在各自的事务中它们彼此是完全独立的不会相互影响。因此在MySQL中我们将对事务进行深入讨论。这不仅仅是讲解大家所了解的ACID而是要讲解在MySQL上如何实现这些ACID。我们之所以要讨论这个是因为我们的系统既有高负载部分又有高并发部分。因此你需要知道你使用的每个东西在高并发条件下是如何工作的。这样你就会知道它的高并发特性是否能满足你的要求或者说如果它在产生巨大的高并发时是否会产生很大的副作用。 因此在MySQL中我们会对事务进行更深入的讨论。在这里我们主要使用了一种基于注解的方式来标记事务。这个注解叫做Transaction。通常我们会将它标记在服务层即控制器层的目的。大家应该知道控制器层的目的是用来处理界面的因此它与事务无关。但凡要处理的业务都从服务层开始。因此服务层是我们整个后端逻辑的起点。因此我们从起点开始就标记一个Transaction。这就意味着整个后面处理的逻辑都符合ACID。当我们标记一个Transaction时它会带来一些问题。首先一个问题是它会具有传播性。什么是传播性呢因为我们服务层的代码是相互调用的所以我们服务层的代码不能够独立调用它可能会相互调用。如果两个方法都标记了Transaction它的事务会是怎样的呢 默认情况下它是REQUIRED。这是什么意思呢比如一个方法调用另一个方法如果另一个方法在进来的时候已经开启了事务那么它就会在这个事务中继续执行。这会带来什么样的结果呢事务在出错后会回滚所以如果这个方法出错它会将前面的东西也回滚。另外一种情况是如果我调用它但是我这边没有事务它会怎样呢它会在这里开启一个事务只在这个范围内有事务。因此如果抛出异常会有什么结果呢它会滚到它最开始的状态而这边的东西不会回滚。这是默认情况。还有一种可能会使用的是REQUIRES_NEW。这个名字很直接不管前面有没有我都会开启一个新的事务。在这种情况下如果前面已经有一个事务那么第二个事务产生的结果会怎样呢在回滚的时候它首先会将第二个事务回滚然后再看我们前面设置的是否要带着它回滚。如果要带着它回滚那么两个都会回滚如果不带着它回滚它可以控制只回滚一小部分。因此事务具有灵活性它既可以滚自己也可以滚别人。为什么不将它设置成默认的方式呢大家觉得它挺灵活的可以根据情况滚自己也可以滚别人。为什么不将它设置成默认的呢因为大家知道事务嵌套对数据库的压力很大因为它们可以相互调用所以它们有可能相互嵌套很多层。事务嵌套太多对数据库的压力很大。因此通常我们默认是不嵌套的。说到底在事务上大家还可以看到我们会使用另外两个值即rollbackFor和noRollbackFor。在出现异常时会回滚事务但是哪些异常会导致事务回滚哪些异常不会导致事务回滚你可以在这里指定。
http://www.ihoyoo.com/news/60656.html

相关文章:

  • 做我女朋友的表白句的网站成都网站制作公司电话
  • 无锡网站制作建设内网访问wordpress很慢
  • 内容网站设计范例wordpress安装包下载失败
  • 永久免费网站建设网站制作素材
  • 免费自助建网站软件用照片做的ppt模板下载网站好
  • 搜索引擎网站提交入口北京有哪些软件公司
  • html网站的直播怎么做封面上的网站怎么做
  • 郑州做花店网站wordpress轻博客模板
  • 网站做友链有什么用企业公示信息查询系统四川
  • 重庆长寿网站建设三网合一网站 东莞
  • 宁乡网站开发友情链接的形式
  • 哪个网站可以做1040网站流量分析软件
  • 怎么构建网站网站内链有什么用
  • 惠州品牌网站建设价格网站建设运营公司排行
  • 做网站作业什么主题淘宝网网页版入口
  • 昆明网站建设一条龙服务网站建设合同司法解释
  • 商业网站的建设与维护国内 上市网站建设公司排名
  • 安卓做视频网站好物流公司网站建设系统规划
  • 抖音做我女朋友的网站全国行业名录搜索系统官网
  • 网站服务器租用协议网店代理货源网
  • 手机的网站建设目标是什么意思石家庄手机模板建站
  • 男女做那个网站动态图片四平网站公司
  • 海珠区住房和水务建设局网站ECMS做的网站
  • 做汽车网可参考网站本地购物平台有哪些
  • 安徽网站建设系统网页制作论坛
  • 计量检测网站平台建设方案专业网站设计的公司
  • 涟源网站seo资兴做网站公司
  • 公司网站做的一样算不算侵权网站代备案需要多少钱
  • 网络营销的基本特征有哪七个seo技术是干什么的
  • 游戏交易网站建设wordpress单栏主题