数据库几乎是所有 Web 服务不可或缺的一部分,在所有类型的数据库中,关系型数据库是我们在想要持久存储数据时的首要选择。因为关系型数据库的种类繁多,所以 Go 语言的标准库 database/sql 仅为访问关系型数据提供了通用的接口,这样不同数据库只要实现标准库中的接口,应用程序就可以通过标准库中的方法读写数据库中的数据。
9.3.1 设计原理
结构化查询语言(Structured Query Language、SQL)是在关系型数据库系统中使用的领域特定语言(Domain-Specific Language、DSL),它主要用于处理结构化的数据1。作为一门领域特定语言,它有更加强大的表达能力,与传统的命令式 API 相比,它能够提供两个优点:
1.可以使用单个命令在数据库中访问多条数据;
2.不需要在查询中指定获取数据的方法;
所有的关系型数据库都会提供 SQL 作为查询语言,应用程序可以使用相同的 SQL 查询在不同数据库中查询数据,当然不同的数据库在实现细节和接口上还略有一些不同,这些不兼容的特性在不同数据库中仍然无法通用,例如:PostgreSQL 中的几何类型,不过它们基本都会兼容标准的 SQL 查询以方便应用程序接入:
![](data:image/png;base64,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)
图 9-12 SQL 和数据库
如上图所示,SQL 是应用程序和数据库之间的中间层,应用程序在多数情况下都不需要关心底层数据库的实现,它们只关心 SQL 查询返回的数据。
Go 语言的 database/sql 就建立在上述前提下,我们可以使用相同的 SQL 语言查询关系型数据库,所有关系型数据库的客户端都需要实现如下所示的驱动接口:
type Driver interface {
Open(name string)(Conn, error)
}
type Conn interface {
Prepare(query string)(Stmt, error)
Close() error
Begin()(Tx, error)
}
database/sql/driver.Driver 接口中只包含一个 Open 方法,该方法接收一个数据库连接串作为输入参数并返回一个特定数据库的连接,作为参数的数据库连接串是数据库特定的格式,这个返回的连接仍然是一个接口,整个标准库中的全部接口可以构成如下所示的树形结构:
![](data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAr0AAAGICAYAAABMe1hbAAAgAElEQVR4nOzdZ3Rj553n+e+9yIEBzKmSKieVKkrlUs7BlizbbbeDnNp2u3Of3j7Te3pnT+++mNmdPjvTadrT7XYOsmTLQbZlW5asnCvnXCzmTIIBGbh3X6CIKhbJCqwAEPx9zuEpEnhw8efFLfCH5z73eYyh4VEbEREREZEiZua7ABERERGRa02hV0RERESKnkKviIiIiBQ9hV4RERERKXoKvSIiIiJS9BR6RURERKToKfSKiIiISNFT6BURERGRoqfQKyIiIiJFT6FXRERERIqeQq+IiIiIFD2FXhEREREpegq9IiIiIlL0FHpFREREpOgp9IqIiIhI0VPoFREREZGip9ArIiIiIkVPoVdEREREip4z3wWISP5kMhbhcBjbtgHweNwEg0EMw7joY8PhYdLpNKZhUFFZMeE+27YZDg+TzmQuup2qqspJtw0NDZHJWLhcLsrKSifdn06nGQ6PYJOt28DA5/fi8/kuWLtt2wwODmHbNn6/H7/fd8Haenv6GBoK4/N5qamtxuv1TmoTjUaJRmPTbiMQCODzTX7c5RgeHqG/b4CMlaG2pprSstJpf890Ok13Vw/RaIy6+lpKS0umbBceCpPOZCgpCeLxeK6ovnONjo6RSCQAMAyDsrJSnM6p/9RYlsXQYHjC6+j2uAkGA1P+fuPH3HRKS0txu11EIhFisThOh5Oy8sn7KhqNEY1GcTmdlJWXARCPxxkbi0y7bZ/PRyDgByAWixOJnG1rGgY+vw+f78LHk4jkl0KvyBw2PDzMv/7zvxOPJ3K3eb0e5s2fx0MP309tXfWU4SOVSvPVf/sm4aEwAH/7n/+aYEkwd386nebb33ySnp7eCz6/YRj8l//37ybcFovG+P/+2z9j2zahinL++j/9xaQa+nr7+cr//A8y54Vqj8/LvffcwZZbNuFyuSY9X29PL//0D/8LgCVLF/P5LzwxZV0DA4M886Of0dLcmrvNNE1uv3Mbt92+bUKIfeuNd3npd69O+zs+9Mj93Hb7+6a9/0LS6TQvv/w6L784cfuLbljIh3/vMUKh8ty+sW2bE8dP8q1vfh/bsnNtN2/ZwMPvf2BSsP3m179HX18/H/v4h1l309oZ1TeVX/3yN+zdcyD3s2EY1NbWcOddt7Fi1TLcbnfuvmg0xj/9w1cmBVnDMLj19q3cfsc2AoEAkA3I3//u03S0d0773J/53CdYvmIZzadaePJ7PyQUKufP/uLLeM/70PH0D37M8WMnWLN2NZ/41O8BsGfXPn7+7K+m3fZtt2/joUfuA2DH9p38+rkXJrUJlgZ58IF7Wbd+LQ6HY9ptiUh+KPSKCABLly9hbHSMnu5ejh87QVtrG1u33cx99989qW1Pdw/D4WF8Ph+xWIyW1jZWr16Zu98wDKqrKzHNsyOourq6AaioCOUC2FSB+ujR49i2TSDgJzw0TGtLGwsWzp+yZpfLyZJlS7Ati8GBIXp7+3jul8/T2dnNRz76wUnbf+l3rwHZXruTJ04xMjxC6Xk9yfF4nG9943sM9A/i8bhZvHgRY5EInR3dvPryGwSDQd637eZJtfj9PsrKyibdHgwGpqz9YizL4qc//gW7d+3FMAzmz2/C7/fR0tJO86nTfO87T/HlP/6DXIjctWM3P//5r7Etm7r6WiorKzhy+Bjb39tFT08fn//CExMC57VWHiqjqqqCjo5uurt7eOoHzzBvXiNf/PLnJvX8jr+O2DajI6N0dnbz+qtvcezICb745c/i9/sxDIOqqkqsjAXAwMAAyWSKisoKPG43GOA50xO/avUK/H4/IyOjRGOxCaE3Fotx8sQpANatnxz2vV4PoVBo0u2lZZN7zIPBAPMWzCOTyTA0MERfXz8/fuZZmptbePzDH5hw/ItI/in0iggAn/3cJzEMg1g0xu9+9yrvvr2dd9/ewcZN66momBgCXn75dWzb5rY7tvHC87/j5PHmCaHX6XTyiSc+NuExf/s3/xcA73/sIVasWDZtHcePn8TlcnHPfXfx8589x6uvvMGnP/uJKdsGAgGe+PTv537et/cATz35DG2t7aRSqQkhLxKJcvDAYSoqQqxZu4rXXn2T1tZ21qxdNWGbB/YdYqB/EJfLxV//zV/kehrD4TDb393Fho3rpqxl9ZqVPP7hR6f9vS5XNBrjxPGTmKbJl//kD2hqagSyPbrvvrOdxqbG3O+XSqV44413SCVTbLllE+//wEM4nQ7a2zr4zreepKO9k5bTbSxdtviq1XcxK1cu5wOPPQzA4UNH+fEzz9LW1sFzv3ieRz/48IQPJD6/n0898bHcbUNDYb7+1W/T29tHb08fCxctwDAMPvbxD+ce82//+jVaW9t5/EMfYPGSRROe2zRNGhvrOX78JIcOHuHW27bm7uvp6cOyLHx+H8uXL5lU96IbFvLEZz5+Sb9jQ2ND7vizbZuDBw7z1JPPcPjQUe574C5KSycPzRGR/NHHUBGZwOf38cj7H2D+/Cai0SjP/eI3E+4fG4tw+OARAgE/625ag8Pp4Mjho7lxwVeqpbkVv9/HjevW4PV6aD7VcsGxludavWYlpmliWRbnl9PW2o5lWSxbvoQbFi/CMAxOHD81aRtD4aEz39kThgSUl5dz3wN3Tzmu91pIp9OkUtnT/pUVZ8dMG4bBLVu3MG9eY+62wcEherp7CQYDPPbBR3A6s6fWm+Y1smbtKjKZDK+88vp1qXsqK1ct50Mfyn4g2LfvAKMjoxdsHwqVs2DhfGzbprOze0bPuXBR9uzAju27Jtze1dGVrWnlsmnHGs+EYRisWbuK0tISkskksWj8qm1bRK4OhV4RmcQwDJad6Y1tOd0y4b621jYAVqxcTllZKaWlpYTDw5w6efqKn7e1tY2hoTCVVZX4fF4W3rCQVCpFX1//RR8bHhrmB9//0ZlguxS3e+KY3pMnT2EYBkuWLqaysgKHw8GRw8cmhfVVq1ZimgapVJqvf/U77N93EMuyLvr8lmWRSqUmfF3K46bj9/soLSvBsiz+6R++wksvvjpt+O9szwa56ppqDCYO6Zg3vwmAnq6eGddyNaxas4Ly8jIS8QTJZOqi7cdf85JzxopfjpWrVgDZixEHBwZztx8/fhKA5cuXTvm4qV7H88eOT2c4PMLYWASHw5H74CEihUPDG0RkSpWV2SEN0WicaDSWm+ngxIlmAJYtX4JpmmzatJ7fPv87tr+7gxsWL7ykmR+m8+rLb2DbNutuWoNhGCxatIAjh45y9PBRFi1aMKn98PAIf/d//hcsyyKTzgaTTZs38P5HH5xQh23bHDl8HIfDQXVNFeWhMvx+HyMjI5w4fpKly86e5m5sauC+B+7hdy+8QktLKy0trVRWVXLbbVtZuXo5JSVTz4awc8cedu7YM+G2Bx68lzvuunVG+8LtdvP4hx7lRz/8CYMDQ7z4wsu8/tpbbN6ygfUbb6K+vjbXdrw31Ov1cl7mzY0pjkZjxGPxSRd1XU/BkiDh8DD9/YNUVZ+dtSOTTtN86jRgEI/H2bVzL+1tHfj9vtywjstVV19LdXUVfX39tJxuo6KyglQqRfOp0xiGQX1j/ZSPO3rkOH/3n//LhNu2bruZDzz60KS2sWiUU6dOY1s2oyMjvPjCK6TT6eysGVOM7xaR/FJPr4hM6dyrz8/tsTx86ChOp4Pa2hoAbnnfZgzDoK29g8Q5s0BcrkgkwqlTpzFNMzebQNOZU/i7du6d8jGmaVJdXU1NbXUu3O3ZvY8fPf3TCb1zba3tDPQP4PG4c728GzatB+Cdt7ZP2u7td2zjb/72r1h6ZsznQP8Az/7sOf7lH/+N/r6BKWsxDAPTNCd8XUH+B2DBwnn8+V/+Efc9cA8ut4tEIsEbr7/NV/7lq7zy8tnhCslkMluDOfkJz72YKpW+eA/rtWQa2Voy583WEIlE+cbXvsPXv/Ztvv/dpzh08DBut5snPvNxQhXlM36+zTdvBKClJXt24vixUyQSScrLS6msnDxVXq7O815Hc5oXsq2tg2/8x7f5xte+ww+f/imDg0PU1dfyhS99BpdLfUoihUb/K0VkSkPh7HRkHo8nNz9p86kWwkNhTNPkl7/4Dc4zwdg0TUZGRgkPD1M3w57Evt5+UskUDoeDp77/DADJVDakjY1FOH78JEuXTrwQq6QkyJ/++ZfO1jwU5vvffZp9ew+wYuWyXHh+550dZ1oYfO/bTwEQiWaHCnR19xCLxSbMsWoYBoGAn899/lN0d/dwYP9h3nnrPcbGIjz5vR/yJ3/+hzgcE/sMNm1ef1UvZBvndru56+7b2LxlPUcOH+fNN96mp7uXV156ndVrVlJdXUX1mV7TZGLyh47xOYRN08xdlJcvkWgE0zQn9PJCdsaEO++6jYxl8dKLr5LJZHj0sYennbXjUi1ZcgNOp5P2tnYADh06DMCdd98x7QeSlauWX/KFbNXVVWzctJ7enl527dqLaZp88omPXddZMkTk0qmnV0Sm1HxmjO78BU25oQLvvZPtFfV6PfT09NLR2UVHZxdOp5NMOsPe3ftn/HxHjxzHsiycTkduu319/bnT8fv3HbzoNkKhcubNb8K2bQ4fOgpAIp6gtaUt2xPrMHPbDodHcDqdjI6MMhwemXabdXW13HvfnTz2+PsB6O7uIXzmA8H1FAwG2bR5PX/+l39EVXUVyWSSjrbsnLX1DXUYhpFdsOO8McrjY2OrqqvyOoVWb08vQ4NhPB43Xu/EOYPdHg+33bGNu+6+nW1nZlrYsWP3FY2JBigvL8Mf8NPd3cvIyChdHV243W42brrpirY7LlQR4vY7t/HBDz9KRUUIy7LYvXPPxR8oInmhnl4RmeT4sRMcO3oCp9PJQw8/AGTnr21r6wDgi1/+LIHA2QuMDu4/xLM/e4733t3BvfffddkT89u2za5d2SEMj3/4URaeM363p6eXr3/127S3dWBZ1kWD20B/dvhBbV12+MXo2BgjwyNUVVfyxT/83IS2v/z5r9m39wC7du7h4fdnf89IJMIrL7/BI2d+HldSevb3vZormE0nk8nw3C9+w81bN+eGksCZXmi/n37Af6YHvrGpkbKyUvr7Bzjd3MKiGxbm2h88cARgwrRd11tkLMJ3vvUDLMuicV4jJdOsEgdwyy2b2P7uDlpOt/Leuzu4ZeuWGT+v1+dl4aIF7Nuzn7ffeo/h4RHqG+quevh3Oh08+sFH+M63nuStN99j67ZbcmdHRKRwKPSKCADvvPUe8USCrs5uDuw/BMCGjeuoqa0Cslemj4yMUlVVSW1t7YTHrli5jJ8/+ytisTinm1snzZt6MadONjM6MoppmtyweCF+/9nA4HI1EAwG6O8bYGwsMmFZ3UQiyXvvbMcG4rE4zc2tnDzRnJ3y7MY1AOzbu590Ok1TU8OkhSIWL17Evr0H2LljD/fefzcOh8kPn/opx4+d4OiRY6xYuZzqqkrSmQw73stOfbVm7aopF5zo6uzmlZcmTwtWXVvN6tUrLmt/ABw+fJT33t3J3j37Wb1mJbV1tbg9bk43t9La2kawJEh9Qx2QXT563U1refWVN/jm17/H/Q/eQ3l5GTu276Krs4vy8jKWTTEnLcChg0cZGpzcc71x8/oZz5wA0N3Vw5tvvsvQ4CBHDh1jcHCIsrJSPvj4+y8YOstD5WzddjMvvfgqL734GmvWrCJYEsx+MNq5h9GRMQBGzkx7tmf3Ptpas8MX1q5bTeV5S2K/731b2LdnP+++vZ14PM78BU0XrLu/f2DK17GktOSCPcQLF82ntraGrq5ufvzDn/LJT/++VmUTKTAKvSICwC9+/msMw8DhcOD1erjnvrvYdustufv37T1AOp2msalh0mPLystoamqkra2d48dOXHbo3bc3O3Rh6bLFEwIvgMvlorKygpaWNt564x0efPi+3H2xWIyf/fQ5gFztpaUlPPrYw1RWVWDbNm+/mR2SsXDRQs63eOkNGEZ2Oy2nW1i6bAmPf/hRvv/dp+ju6uGN197KtXU4TBoa6nLDHM7X3t5J+xRL5N64bs2MQu+KFcvZtHkDe3bvZeeOPROGLQQCfj7ye4/lQqlhGDzw0L3EYjF27dzLr375fK5tsCTIH3zx0xM+LJxr/74D7N93YNLtS5cvvqLQ29zcQnNzCw6HicPhpKGxgU9/9uPT1nGue++7i317DtDfP8D293Zx1z23Y9s277y9fdIyxDt37M59X99QOyn0zl8wj1ConKEzS2avWnXh16Kvt5/fPv+7SbfPm9d4wdDrdrv58Ecf4yv/8h+cONFMV1cPTVP8XxGR/DGGhkevzozyIjLrpFIpWlvasazsTAcOhwOfz4c/4Ke0tGTCtF/tbR3EYjFCFSGqqiZf+d7b28dweJhg8GwP5LmOHzsBZFexOv/Ub0d7J9FolKqqSkIVk5eA7ersZmxsDI/Hw/wF80gkErS1tk8Igk6nE4/HQ2VlBZ4zY0bTuamwsjNBnHux2rgTJ05hWxbV1dWUh7LTTCWTSfp6+wmHh+np6aOsrISammrqG+onzb86MDA4YR7Y85WUlFBXXzvt/RfT19fPyHB2aV7TMKipq6a+rpbgFIE0k8nQ09PLT3/8CzraO6mtq+HzX/j0lOG15XRrbtaHqcybP2/S2NtL0d3Vw+jo+OITBh6vh4DfR6giNKmHN5PJ0HzqNA6HY8KQDMgOaxkZHsHlcuWGu7S2tpOIT7/ow1THFpw9vgAWL7lhyp7mcHiYvt6+abft9Xpzcx4PDYXp7+vHHwjQeN7UZ6dPt5JKJqmorJgUwEUkvxR6RUSKzJEjx3jyuz8knU5z8y2bWLFyOYZhsHjJIp1yF5E5S6FXRKQIHdh/iKeefCY3A4JhwB//6ZemHJ4iIjIXKPSKiBSpvr5+WppbGRoK4/a4uWn9jZSVlea7LBGRvFDoFREREZGip8UpRERERKToKfSKiIiISNHTPL0iIteIbUM0FsMwwO1y4XTqLVdEJF/U0ysico1kMmlee3cHx5pbePWdHaQzmXyXJCIyZ6nbQUTkGvJ43KxbuZwd+w7S0tGJy+mkt38Ay7KpqaqkobaaA0eOkc5k8Ho8rF62hN0HD7PpxjWcON2K0+mgrrqKvYeOYtkWodIyli9eyG9ff4uaygpGRiNs23QTfUNDNLe2Y5omCxobqK6sYPve/bhdLjxuN6uWLqa5vZPhkRGwbVYvW4LHc/mLT4iIzFbq6RURuQ58Pg/JZJKMlcEGtty0loVNDbhdLhbMa8LhcNDZ04tl22Qsm7FolFOtbTTUVHPidAu2ZRPw+zh0/ATpdJpMJsOaZUuprgzR2dvH4eOncLvcBP1+2rq6wYah8AgZy2J+YwOmaRKPxxkeGaW+tkaBV0TmHIVeEZFryLYsBobCdPf201BbA0DwnOWQ+wYHOXDkOIvnz8PldIIN8+pr2XPwCHU11bjdbkqCQRxOk3n1dWzdeNOEVdVMwwDLxuvx4PG4mddQx/IbFmFjs3XjOhbPn8c7u/YSicaor6lmw9rVtLR3crKl7brvCxGRfFLoFRG5RgzDwO12c7y5hdXLl1JWUoLP6yXg9+falAQCmIbB8dOt1NXUYJgGddVVGAYsmtcIwPyGejxuN/uPHGMsGsUwDKoqQhimQcDvx+v1smHNSmKxOPsOHSWRSGBbNs1tHRw8doK66kq8Xg+D4TB7Dx3GMAwa62rytVtERPJCi1OIiMwStm1jGMYVPca2s0sSi4jMNerpFRGZJS438E71GAVeEZmrFHpFREREpOgp9IqIiIhI0VPoFREREZGip9ArIiIiIkVPoVdEREREip5Cr4iIiIgUPYVeERERESl6Cr0iIiIiUvQUekVERESk6Cn0ioiIiEjRc+a7ABGRy2Xb9pTfS/E4d/nkmSy/LCJyPoVeEZlVLMvCsiwSiQSJeIJ0Oo1t2wq/RcIwDAzDwOl04vF68Hg8mKaJaerEpIhcGYVeEZkVbNvGsiySySQH9x/i7be2MzQYJpFIKPAWGcMw8Hg8hCrK2fq+zaxeuwq3241pmur1FZEZM4aGR/XXQkQKmm3bZDIZEokEL734Km+/+V6+S5LraOu2Ldx97x14PB4cDoeCr4jMiM4XiUjBs22bZDLJ3t37FHjnoLfffI+9u/eRTCbVqy8iM6bQKyIFzbZt0uk0g4ODvPjbV/JdjuTJi799hcHBwdwYbhGRy6XQKyIFzbZtUqkUnR3dJBLJfJcjeZJIJOns6CaVSin0isiMKPSKSEHLht4kIyPDCjtzmG3bjIwMk0ppiIOIzIxCr4gUtOzwhgxJ9fLOeclEknQ6o9ArIjOi0CsiBW18qjLLsvJdiuTZ+HGg0CsiM6HQKyIFT4tPCOg4EJEro9ArIiIiIkVPoVdEREREip5Cr4iIiIgUPYVeERERESl6Cr0iIiIiUvQUekVERESk6Cn0iogUINM0cTgc+S5DRKRoOPNdgIiITGQYBp/7whMEAn6++60fMDQUzndJIiKznkKviMgVaGpq4JZtWwBIJlMM9A/S1tpOa0vbjLcZCAZYuHA+DqeD6poqhV4RkatAoVdE5AqUh8rZsPEmUqk0lmXhcDhwOh28+fo7/OqXz89oBbGx0TH++9//M8FggPb2zmtQtYjI3KPQKyJyFfz8Z8+xd/d+KipDfODRh9i6bQtHDx/jxIlTAAQCAYIlAfp6+7Esi9KyUhYums9A/yAdZ4JtXV0Nhnn2UouMZeF0Okmn0wB4vB4qKkIMD48QjURz7UzTpKa2mmg0xsjwSO52n8/LvPlNmKZJa2v7hMcAhCrKcTgc9PcNAFBTW01jYz2nT7cyNKjeZREpLgq9IiJXSTqdprenj5dfep3FS29g8y0bc6F3/cYbufueO/jXf/kqd99zB+s3rgPg1MnTfO3fvwXAF//oc/h8vgnb/Kf/8RV6unsBKC8v44//7Ivs3rWPn/zo2VybxYsX8bkvPsEPf/Bj9uzen32+Det49PFHcDhMbMvGxubZnzzH7l17c4/7wAceorKmkm989Tt86jO/T2NTAwCvvvQGz//mxWu0l0RE8kOhV0TkKuvp7gGgprZmwu1ut5vPf+HTpFIpnnryGU6dOE0g4M/d//f/9R/ByH7/oQ8/ytp1qyc8vrenj/6+fm68cRXP/uQXZDIWAA8+ch+RSJR9ew8CsGz5Uj7ysQ/S0tLK00/+hFQyxSee+Cgf+ODDHNh/iFQqldtmWVkpX/7TL9DX28/Xvvpt+nqyPdEiIsVGU5aJiFxl46HS75/Ya2s6TOKJOF/792+xb88BxsbG6Onpzd2fSCRIxLNfmSmCp21ne2vdHg83b90MQH1DHfUNdbz5xtu5sLpx802k0xneeuNdgkE/oYoy9u7Zj9frYdXqFRO26Xa7aWtt5zvffJJTJ5oZHR0lEolc1f0hIlII1NMrInKVBQIBAAb6Byfd95tfvcjY2MxD5enTrfR097Bx83ree2cHy5YvJZVKc+TgsVyb0tJSnE4HH/rIY8DZC+ni8TihivLJNT33Qm7csIhIsVLoFRG5ym5YvAiAltOtk+6zr8LQgSOHj3PL1s0Eg0FWrlrG8PAwfX39ufujkSjRaIxv/Md3iEVjEx4bi8Unbc+yLn+GCRGR2UbDG0REroKS0iBN8xq5eetm7n/wbpLJJDu277omz7Vn117cHjebtmygaV4jv/vty2Qymdz9hw8fxe/3sWnzeizbZnh4hIxlEaoIkUgkrklNIiKFTj29IiJXwf0P3MN9999NJpNheHiEb/zHd6cc3nA19PT0cfzoCe6+9w7C4WH27jkw4f4d7+2ioaGOzTdvZOu2m0mnMzgcJsPhEf7+//mHa1KTiEihM4aGR3VeS0QKViqVYnBwkPfe2c7bb+7IdzmTBEuC1NfXAtlhAtFolHB4eNKwglConKrqSjrau4hGo1NtaoK6+lpKSoK0tLSRTCQn3V9eXkZ1TRXRSJSOjq5J95umSV19LVXVlZSUltDX00dPdy/D58zj29BQTyDo53RzC6lU4Y/p3bptE1tu2UxFRQUulyvf5YjILKOeXhGRKzA2Osbx0bGLthsaCl/WcsLdXT10d/VMe384PEw4PDzt/ZZl0dnRRecUgXhcZ+f094mIFBuN6RURERGRoqfQKyIiIiJFT6FXRERERIqeQq+IiIiIFD2FXhEREREpegq9IiIiIlL0FHpFREREpOgp9IqIiIhI0VPoFREREZGip9ArIgXPMAwcDke+y5A8czgcGIaR7zJEZJZS6BWRgmYYBqZp4vP7FHjmMMMw8Pl9mKap40BEZkShV0QKWraX16SishyP15PvciRPPF4PFZXlOBwKvSIyMwq9IlLQDMPA5XITDJawfuNqXC5nvkuS68zlcrJ+42qCwRJcLrdCr4jMiEKviBS0bOh1UVISpGleI0uWL8LpVPCdK5xOJ0uWL6JpXiMlJUFcLpdCr4jMiP5yiEhBMwwDp9NJIBCkqqqa5StSBAI+2ts6GRoYJplMY9t2vsuUq8gwDNxuJ6HKMprmNdA0r5GqqmoCgSBOp1OhV0RmRKFXRAqeaZp4PB5C5eUYBng8HioqQ4yNjpFMJshYFhR58B0dHQOgpCSY50quMcPAYZq43R6CJUFCoRCVlZWUl5Xj8XgwTZ2gFJGZUegVkYI3PmWZ1+ejwuHA5/MRKg8Ri8dIJVNkMpl8l3jNvf7aWwBs3Lgxz5Vcew6HA5fbhc/rIxAM4PP5cbvdmrJMRK6IQq+IzAq54Ov14nQ68fn8ZDIZMplM0Q9vSKfTjISzPb0NjY1FP6Z5/LV2OBw4nc7ckAYFXhG5EsX9zikiRWU8+LhcLlwuF7ZtF33gBWhtaWNsLALA2GiE+Qvm5bmia+/ckKuwKyJXg0KviMw6cy0M/fynvwKM3Pd/8b/9cX4LEhGZhXRFgIhIAWtv66Cnpzf3c09PL+1tHXmsSERkdlLoFREpYEcOHb2k20RE5Bj9xdMAACAASURBVMIUekVECtjOnXsv6TYREbkwhV4RkQK1a+cehsPDuD3u3G0+n4/h8DC7FXxFRC6LQq+ISAGyMhb79hzkQx95lLU3rs7dfvd9t/OhjzzK3j0HsDJWHisUEZldNHuDiEgBMkyDT33m93E6HbS2tE+4b9OWDdy0YR2GOTdmrxARuRqMoeHR4p/kUkRkFuto7yQ8FAagrr6OyqqKPFckIjL7KPSKiIiISNHTmF4RERERKXoa0ysiUuB27dhD86nTANy4bg1Lly/Jc0UiIrOPQq+ISIFraWll5449ANTW1Sr0iojMgIY3iIgUvLOzNNi2LsMQEZkJhV4RkQJnaGYyEZErptArIlLgzs286ucVEZkZhV4RERERKXq6kE1EpMCtWLWcktJSABYumJ/nakREZictTiEiIiIiRU89vSIy61iWhW3buX+l+BiGgWmauX9FRK6UQq+IzBqWZWFZFqlUEjN2jEBqO26rB4NUvkuTq8jGRdKsJeLajOVbhsvlxjRNhV8RuSIa3iAis0I27KawYm2Uxn+N12pBcxkUO4O4uYAR70OYvnm4XC4FXxGZMb17iEjBsyyLdDpNPBqmPPo0Xus0CrxzgY3XOk159Gni0TDpdBrLsvJdlIjMUgq9IlLwLMsiFotSHn0KN4P5LkeuMzeDlEefIhaLKvSKyIwp9IpIQRsf1pCJdRAw2vNdjuRJwGgnE+vIDnFR8BWRGVDoFZGCl0qlsOK9GCjszFUGFla8l1RKFy2KyMwo9IpIQcuO502RSUfzXYrkWSYdJZ1WT6+IzIymLBORgmbbNpmMRSadyXcpkmeZdAYzo7mZRWRm1NMrIgUvuwiFevfmOtu21MsrIjOm0Csis4L69kTHgIhcCYVeERERESl6Cr0iIiIiUvQUekVERESk6Cn0ioiIiEjRU+gVERERkaKn0CsiIiIiRU+hV0RERESKnlZkExG5jkZjBh19DpIpWFSfocSv2WdFRK4HhV4RkesglYYdR9386GUPqTQYRvb2j9yR4PabkvktTkRkDlDoFRG5Dl7d4+bnb3qoKrP55H0xSvw2z73tIRI38l2aiMicoNArInIdvL7PRXnQ5q8+GiF4ZkjD5x6OYZ0zusGyYP8pF3uOOwlHDKrKLN63JsWi+kyuzTOveAiV2KxfluL1PW7a+02CXpv7tySpr7QAePeQi44+k/u3JHlrv4tTXQ4cBrxvbYrVi9LX9fcWESkUCr0iItfYwLDJ4IjJ1jWpXOAdZ57T0fvOIRdP/c5LWcCiJmSz76ST7Udc/KePR2ioygbaPSecYBu8uMONywmWDcNjBr1hk7/+/SiGAae7Td477GbnUReGCQ4TwmMGbX0O/u/Pj+WGVoiIzCUKvSIi19ixdgcAjVWZaduExwx+8qqHsoDN//6pKAGvzeCIyX/7vp//9TMf/8eno3jd2cA8EjX4/CMx1ixKk0ob/I+n/bT2OBiJmJQFs+E4mYKHbkly69oUDgd873kvu4456R0yqa2wrv0vLSJSYDRlmYjINebzZMNqPDn9W25rj4NEyuDWG1MEvNn2FaUWy+ZnGIuZDEfOds86TJublqRxOrLbbqjOhunR2Nk2pgEbl6Xwum1cjrNtBkb0ti8ic5Pe/URErrFlTdme1eYuE3uaGcqS6WxgdbsmNnA6sj9nMtOPSTDH38kvMPuZaWTvnO75RUSKnUKviMg15vdazKuxONXpoLnLkbs9Ejc4fmbow4KabE/su4dcZM6MPkilDU52OHCYdm7YgoiIzIzG9IqIXAf3b07w5Ite/vFHfrasTFEasNl+2IXPY/O3T0SoDlnctSHFK7tdfOc3XlYtyvDaXhejUZOP3p3IDXkQEZGZUegVEbkO1i1JU18Z5Vu/8fHuIReGkb2w7TMPxnNtHt0WpzRg8au3Pew65sLrtvnsQzHWLdE0YyIiV8oYGh5V94GIFKxUKsXg4CCpwbdZWfZ6vsu5KmIJA9sG/zS9t+kMjMVMSgPWhCnN5rrDw7fhqthKRUUFLpcr3+WIyCyjnl4RketsfDaH6TgdUK4xvCIiV5UuZBMRERGRoqfQKyIiIiJFT6FXRERERIqeQq+IiIiIFD2FXhEREREpegq9IiIiIlL0FHpFREREpOgp9IqIiIhI0VPoFZHZwdbSZHOejgERuQIKvSJS8EzTJGW7sVHomatsDFK2G9PUny0RmRm9e4hIQTMMA9M0iWXKsCyF3rnKsgximTJM08QwdByIyOVT6BWRgmYYBi6nE8NVzoHuG/JdjuTJge4bMFzl2WNBoVdEZkChV0QKmmEYuNxuSoIldMXX0txfne+S5Dpr7q+mK76WkmAJLrdboVdEZkShV0QKmmmauFwuAsEgVdVV7OndwDsnm7B0UVPRs2yDd042sad3A1XVVQSCQVwul8b1isiMGEPDo3a+ixARuRDLskilUoyNjtLb10dvbw/JSDcBZxi3mQAsoHjeyizbBtu+aLizLAsMA7Ooej4NwCRpeYiky3EH6qipqaWmuppgSYlCr4jMmDPfBYiIXIxhGLne3lrTxOfzMTxcTjQSZSyZIJPJ5LvEq6qzs5NweIRVq1dcsN2hI0coLy+lobHhOlV2fTgcDjxuDzUBP2Vl5ZSWluL3+3G5XBraICIzptArIgXPMAwMw8DtdmcDkcdDaWkpyWSSdDqNbVlF1M8Lp4630t8zxKJHbsDpmvptOp1K89pLb+N1+1m6dNl1rvDaMQDDNHE6nbjdbjweT+51Vw+viFwJhV4RmTXGp6saD76WZWVP8QO2XRyxN51O09XVQyqVwcCgunrqC/e6O7tJpTJ0dfUQCoVwOovj7Xy8J9c0zdzX+IceEZErURzvkiIyZ4wHoGLt9Xvz9beJxxIA7Nt7kEWLF03Zbt/egwDEYwn27TnAttu2XrcaRURmo+L8qyEiMgslEgneeO3t3M87d+xhZHhkUruR4RF27tiT+/mN194mkUhclxpFRGYrhV4RkQLR1dnN2Fgk93M6nWbP7n2T2u3ZvY90Op37eWwsQldn93WpUURktlLoFREpEDu375k0E8Whg0cntTv/tkwmw87teya1ExGRsxR6RUQKQDg8zN69+yfd3tHeSU93X+7nnu5eOto7J7Xbu3c/w+Hha1qjiMhsptArIlIAdm7fTVlpKfUNdbnb5i9oorq6il/98nls28a2bX71y99SXV3F/AVNuXb1DXWUlZayY/vufJQuIjIraPYGEZECcOO6Ndx2x/t4/lcv5sbnLl22hNvvvJWhwSFSqRQAj3zgAUIVIV575Q1aW9oBWLhwPg88fC/D4ckXvYmISJZCr4hIAaiuqQKgqrqKZSuWkkqmqKquxOVyUlN7dq7e8e+rqitZdMNCXG4XVdVVuN3u3DZERGQyY2h4tDhmdBcRERERmYbG9IqIFIBTJ0/zy2d/PaOV5Wzb5pfP/ppTJ09fg8pERIqDhjeISEGLxeJ0tHUwMjJKIpEEbBYvuSF3mv90cytdnV2THlffUM/CRfMB6O3p4+SJU5PalIfKWblqOQCjI6Mc2H9oUhuPx8ONN63F6XSQTqfZt+fAlAtBrLlxNSUlQQAOHzpKeCg8qc25dZ88fore3j6i0RgtLW2cOtGMy+Viy9ZN1NRMvfTwdPr6+tm5Yw/vvL2dG5YsYsGCefj9Pmpqqlm89IZL3wejYxzYd3CafbAGp9NJOp1h3579U++DtasoKS255H1wea+dgcfjprS0hMZ5jfh83kvcOyIiWQq9IlKQbNvm+V+/yGuvvDnpvsc/8mguOB06eHjCKmbjbr1tay44tba08Ytnfz2pzbLlS3KBb3BwaMo25aFyVq1ZgdPpIJVM8cJvX55yarDGpoZc6H337e0cO3rignXv2b1vwqpqkF2R7Zmnf8Yf/9kXJz32Qp55+me5EHri2ElOHDsJwMZNN+VCb8sl7IOhafZBWXkZK1ctPxN6U7z4witTBtqGxvpc6J1uH3zo3NfuwGHeeH2K1+72s6/ddHXffuc2HnjoXgzDmGKPiIhMpuENIlKwjp8Jb8Xo/KhmmibrblrLY48/cllDHGzb5rHHH2HdTWsxzYlv6cUcB4v52BCRa0M9vSJSkAzDYP2GdXR39RCqKKeysgKX2wVAKFSea1dbV8uqNSsmPb62vib3/Xhv7fkaGupz3/v9/inbBAMBTNMBgMPhYNmyJUSikUntfH5f7vv5C+bhdE1+ez237vqmBlbF4wQCAaqqKlmzdiWhitCkx1yMYRg0NjXwsU98mPsfvJsD+w/T3z9AJBKhvqlhwnNfbB/4/L4p2wT8ARyO7D4wTQfLli1mLDJ5H/j9/tz30+2D8nNfu/qaqV+7utop604lUwwMDDI0GGb9hnXq5RWRy6LZG0SkYI2OjNHd1c2ixQtxOBwKOXOcbdtkMhmaT56mrr6OktJgvksSkVlEoVdECoZlWbz68htUVVdSXV1N3Tm9tSLn6+7qpa+vj/6+Ae6469ZJwztERM6l4Q0iUjC6u3t54fmXACgrL+Vv/vav8lyRFLJvf/N7uVXoVqxcNmEJZxGR8+ljsYgUjO4zy+8CNM1rzGMlMhuce4x0nXPsiIhMRaFXRArGuRdHBQKBPFYis8G5x8hUF9aJiJxLoVdECsc5VxjokjW5mAnHiK5OEZGLUOgVERERkaKnC9lEpGCUlpYwb34TwIzmrJW5JVQRyh0vpWdWghMRmY6mLBORgnLuamSal1cuRMeKiFwO9fSKSEFReJFLpWNFRC6HQq+IFIxYNEYkEgXA6/MSDGoGB5ne2FiEeCwOQCDgn7AUtIjI+RR6RaRg7Nq5lxd/m12cYtPmDTzy6IN5rkgK2asvvc6O7bsAuPf+u9l22y15rkhECplCr0iBsm2bTCaDZVnYtp0bv3juOMZiE4tFcz290ViUWCyW54qujfHT8oZhYJpm7utKT9fbto1lWbmvYj9mouccL7EiPl5g4jEzftw4HA4N8RC5DLqQTaTAjAeXRCrFQDLGrtgorVaKGFa+S5OryAB8mCx0uNngLSHk9uJ2uWYUfsePmWQqxVAyzq74KKczSWJYmr62yPgwmW+62OArodLtwzPDY0ZkLlLoFSkg4727sViMl2JDnMgkyOS7KLnmHBisdHi43R/C6/VeVg/e+DETj8d5LTrE4UyCjKJu0XMASxwe7vaF8Pl86vUVuQRanEKkgGQyGSKxGC+MDXBUgXfOyGBzIBPnlbEBYvE4mcylv/KZTIZYPPvYA5m4Au8ckQGOZhK8MDZAJBa7rGNGZK5S6BUpEJZlkUwmaY+McopUvsuRPDhqJ+mLjJJKpbCsiw9nsSyLVCpFX2SUo3byOlQoheYUKdojoySTyUs6ZkTmMoVekQIwPiYzHo+zPxnR6N05KgPsSowSj8cvOfTG43F2JUZ1VmCOsoD9yUjumCnWixZFrgaFXpECkR3LG6Xb1B+tuazDhPglnq7OZDLEYzE69E4+p3WbNrFYVEMcRC5Cb5UiBSKTyZBIJEk6dDHKXJZwGCTOnKq+UK9dbpaPZJKEjpk5LekwSCSSCr0iF6HQK1IgbNsmk07nuwwpAJl0+pJOU+uYkXGXesyIzGUKvSIFYnxBARHrTC/uRdtZFpaCjqD3D5FLodArIiIiIkVPoVdEREREip5Cr4iIiIgUPYVeERERESl6Cr0iIiIiUvQUekVERESk6Cn0ioiIiEjRU+gVERERkaLnzHcBIjK3mIBpTL9sblqLLcxZTsMg5HQzmkkTt7SkrohcXQq9InJd3VdWwzp/2ZT3ZWyb/9594jpXJPlmAjeXVLDZH8JrZk9AdqcSvD7aT3MimmtX4XTz8cpGvtHXQmyGq48t8Ph5f3ktTw900J9OXo3yRWSWUOgVkevqrbFB9kSHAbijpIr5Hh8/HOwkYWWwyfbymhgYRnY53vF+3/HbMuoJLjqNbh+3BSs5Eh/l1ZEBfKbJ7SVVuV5/AzAwKHe4CJhOnJg4jOx948eIwzCwbBvTMDDInjFwnPO9QfYMQ8B04jedOA0Tx5kzDuceZyJSvBR6ReS6Gs2kGc2kAbJB14a+VILYOaeza11e7iurYmckzMHYKA7D4EOhBpK2xc+HuhRQiozPdABwMh5lOJNiOAPPDHZinXmla10e7iutwefItvtIRQPj/byvjPTTkozysYpGjsUjLPMG8ZgG744NsTkQwgB+OtSJx3TwQFkNftOBATxSXpsL1S+P9NGajF3n31pErjddyCYiBacvHSduWdxaUonPdLAtWEm9y8urI/0KvEWoP50kYVvcV1bN3aVVNLi8nDvsO25ZtCSjDKVTALQkYzQnIjQnIoxZ2Q9QNU4Pd5RWEs6kqHJ6uL2kip5UnCqXm3luPwnLoiURJXzmA1dHMp7bRkTjh0XmBIVeESk4advmp0OduAyTj1U0ss5fyt5omHAmle/S5BoYTCf5au9phtMpNgVCfLJqHh+vbMoNPwhnUrw2OsCJxBgA74wN8troAK+NDjBwzrjcjmSc54d7sGybfdER3hobImnZhJwuhs9sozkRwQZ2RcNTbkNEipdCr4gUpJRtsysSpsblIW5bvDU2lO+S5BqKWRm+3d/G9wfa2BMZps7p4ZOVTTgvMNPHVOzcvzonICITKfSKSEHymQ7W+EvpTMYpczhZ5PHnuyS5RhyGgd90YGHTkYzzwkgvpxJRyhwuPIYj1y5jZYNs0DHzy1HGL4S83DAtIrOfQq+IFBzTMHg0VIdl2zw92E5rIsY9pdUKKkXqJn8Zn69ewOZAOSGHi2XeIA1uL3HLImGfHW/bn8kOQ9gWrMDEwMTAbVzen7HRTBoDWOQJANljzWPqT6HIXKDZG0Sk4Kz0Bmly+Xgu3EPKtvnNcA8fr2zioxWNPDPYSdKe2RytUpg6knG6U3FuLanirtJqANqSMV4Y7p2wWElnMs6uSJj1gXL+sm4xYPPG6CDvRS596EtrMsrxeIT3BUNsCZTjMAyeD/eyPzZytX8tESkwxtDwqAY+ieSZbduMjY3R2dHBs2WOiz9AitrjY1BfX08gEMCYpnfbtm0ikQhdXV38NHidC7xGTAxCThejmfQFP9g4DZOQw0XEyhA9M3vD5fKaJmUOF+FMisQMF7ooJI8NZ2hobCQYDE57zIjMderpFRGRgmBhX9JMCmnboi+duKLnilsWcevKtiEis4sGMomIiIhI0VPoFREREZGip9ArIiIiIkVPoVdEREREip5Cr4iIiIgUPYVeERERESl6Cr0iIiIiUvQUekVERESk6Cn0ioiIiEjRU+gVKRDjS4c6LK0MPpeNv/6XspSsjhmByztmROYyhV6RAmEYBqZp4otffBlWKV7+WALTNC859JqmiT+m5XTnMl88ecnHjMhcptArUiBM08TpclEzEs13KZIvtk19OILT6bzk0Ot0OqkPR8BWb+9cVTMSxelyYZr6ky5yIfofIlIgTNPE6/FQm7JwpdL5LkfywBtPUmsZeNxuHA7HBYOvYRg4HA48bje1loFXZwjmJFcqTW3KwuvxKPSKXIT+h4gUgPEA4/X5qAyWsrC5C6dOWc8prkiMhe19hErL8Pp8OByOiz5m/JgJlZaxsL0PVyR2HSqVQuGMJVjY3EVlsDR3zGiIg8j0nPkuQESyTNPE6/USCoWYF43A8TbaG6tIBANYLgeoF6f4WBZmKo1nNML8zgGaqmsoLy/H6/Ve8vAGr9dLeXk5TdEI9skOWhsqSZQEsFxOHTPFyLIwUxk8YxGaOvqZV1lFKBTC6/Wqp1fkIhR6RQqEaZq4XC5KS0qw6upxOp0EO/sIxzuJWWkyloWtcZtFwzAMnKYDr8NJyOujuq6e6uoaSkpKcF3i+MzxY6akpIS6unocDgeB7j6GTncTz6RJW5miOGYsy7qk/XGp7WYrwzBwmCY+00m510d1bR3VVdWUXsYxIzKXKfSKFBCHw4HH66U8FMLldhEMljA2Oko8HiedThdFgJGs8YvQfD4fwZISSkpKCAaDeC5zbOb4GYLx7QWDJVSPjhKLxYrmmNm39xA3rlt1wTbpTJpDB45dtN1sNv4ae71egiUllJaUEDhzzFzKcBiRuU6hV6SA5Mb2er24XC58Pj8VFSHS6QyZTHH02knW+GvtdDpxu924z1y8drlTT41PW+bxeHA6nfj9fkKhEOl0uiiOmb7efjrautly8yYamxqmbXfq5Gk62rq5487bqKgMXccKr5+zx4wDl8udC7uarkzk0ij0ihSY8T9spmnicDiwbR+2bc/68CKTGYaR+7qS4HL+MeP1eovimLFtmxeffwWA1155iz/+sy/hcEzuBc9kMrz52lMAHD1ygvc/+mDRhsCrdcyIzEUKvSIFajzIiFyqYjtmIpEoHe2dAAwNhhkaHKKhsX5Su1MnmhkeHgHg9KkWXE4X5hThWETmNr0riIhIQTpx7CSjo2NA9iK1I4eOTtnu4IHDue8HBgY5dfL0dalPRGYXhV4RESk4mXSG3/7mdxNue/edHaRSqQm3pZIp9u09MOG2Z3/2SzKZzDWvUURmF4VeEREpOCdOnGJoKDzhttHRMXbv2jfhtrffeo9IZOLS3QP9g7S3dV7zGkVkdlHoFRGRgrN/38Epb9+9cy9WxgIgmUyyY/vuKdsdPnjkmtUmIrOTQq+IiBSUZCJJV0c3m7ZswOv1AGCaBltu3kgymWR0LDvOt79vAJfLyeabN+YeGwgG2HLLJo4fO0kqmZpy+yIyN2n2BhERKSixeJwv/+kfkIgncj22hmFy5923UVJawuhINvQGAn7+5M+/xED/ANvf3QmAy+nkA489RCaTIZ5I4HK78vZ7iEhhUegVEZGCUlZWCmRnbNi0ZSOjo6Mkkyk83uxiDOWhsmy78uy/Pp+P1WtW4vV6KCsvwzCM3IIfIiLjjKHh0dk9e7mIiBQd27avaOGFK328iBQfjekVEZGCYds2yWSS73zjScLnzd5wqQYHBnnq+8+QSqVm/ap0InL1qKdXRGSWyKQzNDefpvlkCyMjI6QzGaqqKrnnvjsBGA4P8/yvX+T8N3W3280DD92D3+/Htm2e//WLuRXMznXHnbdSV18LwFtvvktba/ukNjetv5HlK5YCcHD/YQ4cODSpzQ03LMxdXNbW2s5bb747qc25dQ8ODvHi8y+RyVhEIhHa2ztJJpLMX9DEF/7wszidlz4SL5FI8j//6d8Y6B/E6/PS2NiAP+DD43Zz/4P3ECwJYtuc2QfDkx5/+523Un8Z++DA/kMTFsfI7YPFi9i8ZcMl74Ph4ZHsa3deSHe5XDzw0L0EAv4JdTudTsrKSlm8ZBELFs7HNNWHJXIxGtMrIjIL7Nt7gN/86sVJvZ8LFs7PBadYPM7ePQcmBSef38fd99wO/mxP6tEjx+np7p30HOs3rMuF3pbm1imnDWtsbMgFvu7uHvbu3j+pjcvlyoXecHh4yjYT6o7Gpqy7u6uXgf5Bautqpt4pU+js6GRoMLuP4rE4J0+cAsDj8XDHXbcRLAGwOXbkON3dPZMev37DulzonXYfNJ3dBz3dvVP+fm6XKxd6p9sH8xfMy+2DeCzOvj0HsCxrQhuv18td99xOIOCfsu6XXnyVyqoK3v/oQ7maRGRq+mgoIjILJOLJGZ/un40aGuv54pc/Q3VN1WU9bv6CeXzpjz5HdU31Naqs8Az0D5LU9GwiF6WeXhGRWeCm9Wt5+XevkkqnWb5iKZWVFTgcJqVnZjoAKCkJ8sBD98J5AxycThdenxcAwzDYdttWopHIpOeoqq485/lupLGpflKbhYvm575fsvQGXK7Jf0bq6uvOfl9Xy4MP3zupzbl1l5aV8sBD92I6TILBAFVVVTQ01s3olL3D4WD+gnn8xV/9Ee1tnQwMDBAZi2IYBv6AHxjfB7cQmek+WLgg9/0V7YPSs/sgWBLkgYfumdTb7XQ68fl8k+pOpy36+/s5duQEXp+HlSuXTbtPRCRLY3pFRGaJnq5eqmurNH5TclKpFEMDQ9RcxhAQkblKoVdEpEA9+9PncDocNM1vYtmyxfj8vnyXJAVqdHSME8dP0d7ajs/v497778p3SSIFR8MbREQKUCqV4tTJZvp6+zEMg89/8QkWL7kh32VJgTp1spkfPfUTABYuWoBlWTojIHIe/Y8QESlA6VSa1JmLk0zz/2/vzp/jOO/8jr+f7pnBnABmQBw8APAQSZESJVGiSFGnV5JXtsubPbSJHddWtvLL1lYqruyPSX7Kv5HaxOXddSpOXFmn1t6VV+u1JYoiFd0kJV4SDxAkCJDA4MYcPd1PfmgCJARSAkUQM+j5vKqmAEz3DL4gvhI+/fTTTzukM5k6VySN7Nb5weVyResTi9yGQq+ISAMKrF1YvsoYiLlunSuSRnbrWsa+X0OZV2QphV4RkYak1CJ3Yckdl9U/Il+k0CsiIiIikacL2UREGlAsFuOhPbsozZVwXJeWZEu9S5IGlkmneWzvHgByra26iE3kNrRkmYiIiIhEng4FRURERCTyNL1BRKQB+b7PxQuXqNVqGGPYvKWPRCJR77KkQZVLZQYGBgFIJBJs3tKHMUuubhNpagq9IiINqFwq87Of/i1TU9O4MZcf/sWf09XVWe+ypEFdvz7KX/3ofwDQ2bWOH/7Fny9axkxEFHpFZA2wN9as9X2fIAiw1i48omquNEfV8/A8D2sDSqUSs7Oz9S7rvjDGLDxc18VxHBzHuaeRyvmeme+bqPdMqVTC88KbmXjVKnNzc7gRXtv5fvSMRJ8uZBORhjUfXGq1GkFxlNjAALHREZxyCXPjxg0SDdZx8NMZat3rqfX1E2vLL4SZuwkytx4g+eNjuJcGiF0bxi3NqWcixjoOfipNrasHv68fN9/xtXpGmodCr4g0pPnwUq1WCc6dJXfqE3SbqSZhDFN79xPb1EsikVgY0fsqi3pm4AK5Ex+pZ5qFMUzv2YvTv4VEIqHg5PdBMAAAFW1JREFUK7el1RtEpCFZa6lWq1QvXyJ75qTCSzOxlsyJjyiPDN+Y3rG83721Fs/zqAwPkTl5Qj3TTKwlc/IEleGhu+oZaS4KvSLScKy1+L5PaWaa3CfHML5f75JklblelcynxynNzhIsc1pC2DMz5I5/hFPz7nOF0micmkfu+EeUZmbw9f8MuQ2FXhFpOPOjvMG1YWJetd7lSJ3ES7NUJ8bxPO8rg28QBHieR21slFi1skoVSqOJVSvUxkaX1TPSfBR6RaThBEGAV61ip6brXYrUkfEDqjPTeMs48AmnNlTxZ6YxOrXdtIy1+Dd6RlMc5IsUekWkIXm1GoFGeZuaweJVqtRq/lcGGGsttZpPraJR3mZXq1SW1TPSfBR6RaThLKyx6uv0ZLPz/drC2sxfZn4euE5py61rM4vcSqFXRBrOwo0E0B+tZnc3N5SI8s0nZPnUB3InCr0iIiIiEnkKvSIiIiISeQq9IiIiIhJ5Cr0iIiIiEnkKvSIiIiISeQq9IiIiIhJ5Cr0iIiIiEnmxehcgIiL3KJVa/HW5DFqnVERkEYVeEZGvy3Uhngg/txZ8H4IAAn9Vawi++0fh58YA4Pz9/4XZmaX7GhPW7PsKxY0sectBjF+DwIY9pd+ZyD1R6BUR+Zps32bskwdvPuH7MDeL+eQYZnBgdYoIAsyh34Sfb9uO3dR35317NhAceAbnN/8IU5OrU5/cFRuLYf/Fq7c8YaFSwQxexHz0fv0KE4kAhV4RkXvk/POvYHYGW+jAPrYP+9CjS0NvOg1uDEpzUKstfZNkChIJ8DyolMMRYwhHZ1uSUPNuvi4WCx+VCliLGbkKgF2/4fYFGgPxBDabhXg8fL9kNdxWra7uyLQsz5VBnPeOYrM52L4Tu30n5txZmJq6uU88Aclk2DPl0s3nW5JhWK5WFr+nMZBoCXvJv/E7T6XDnvCqmhYjkafQKyJyrzwPymXM0BXo7sFu3XFzWyKBffoFbMc6MEDNxzn8BoxeW9jFPr4fu3krOAYsmKlJePcIZnICcq0E3/w25uQJzKlPw/23bsfu3oPz63+AmdtMY/gC29mFffZ3wHHAGILnXwTCcOO8fQiGh1byX0NWgAl8qFYxxTE4eQLbvxXbvQEzH3o3bCLY/xTE4uGBz7nPMB9/AEDwzAuYlgTmtV9API5NZ8JeSrQQfOf3Me8ewVwZxO47gO3fGoZha2FmEufwodtPjRGJAIVeEZGV4LpQWAc9G2FuNnzOGOz+Z7DrOjEfvgdzs9iduwgOPI351S8wvg9dPdgHdmDOnsIMDmATCehaj7l1NNiNgbllsR3nxtxczLJKM1OTmPfeIdjYC7194fSLublw4+T4yvz8cn/kWrE7doXB9vpI+FxnF8HTz2GGLmMunMe257EPPQKBxRz/EDM1gd26HRNPYHfuwu7eg/nHX2KTSYjHwwBc6MBueeBm3yVT0N2jkV6JNIVeEZF7FHzr925+USrhfPhu+Hl7HrthYzgKNx9YzpzCPv8idKyDayPhNAZrob0AVwYxk5MwMnxzesNKKJdh8CImm8X29mGGh2ByYuXeX1ac7d2M7d0cfuH7mM/OwER4gBKeFXAxp07C+Bjm6hXYuAm7fQfmzEkojsHW7dhMBtvZBV4V256HXGt4VmJmGtrzYC22sA5zeRAzUQxH/Fey70QajEKviMg9Mu8fBTeG3fskZuACXBkEwLa1hx83b8Vu3rL4RelM+HHsOuat38DeJwm+8c0wlExNYt47gpmeXs0fQxqIuTYCpz7BPvVsOMp74qObG9vy4cepWw5cimPhgVNLSxhqrQ33y7ZiRkfDkJvvwBRHw/0nxjHvHoE9ewle/N1wTu/0NM6RN6F0y/xgkQhR6BURuUdmdBSmp6B7fXjB0cB5mJzATE5gAXPsQ8ylC4tfdMv0BTN8FV77O0yuFdvVjX3oEezB5zC//tXNkbdU+uZrY/HbF+Lf2Nd177D9xveM3+H10jgqpfACxfeOYp9+Hrv9QczpG3O6JyfD6QmtbZjxYvhcvgNsEK70YC3WBrB+fXjR2sjVsDfzhXDE+AZz6SIMDmBaW7Hd67GPPoF9bB/m6Ft1+ZFF7jfdkU1EZCVYG15IZC1210Phc+NFzPBV7ONPYjf2hvNy4/Hw8xth1vb1E7zwUjgqV62EF8MFAWAWlqsiCGBTX7gcWf8W7AM7b1/DbDgybDf1QSYDra1f2D4bzjPe1Bde4Z9Kh1f/S8MyI1cxk+PYB3aEFyICzsXPIQiwO3ZDKoXdvhM61mEuXghX/iiXILDY7g1QLmEGL2ELHeHBzviNkd6t27FPPw/ZXDj9ZfR6eEGbpjdIhGmkV0RkpczOwNXL2I19mPzpcL7lu0fg4UexTxzAPm7BmMWjbRMT4HkEL78SLqjguphrI5gP3glDr1fFvHsEu+8pOPgcdryIc+wDgsf3L/n25sog9G3BPvwo9qFHMFcuY468eXP78FA4p3j7zjA4G4Pz7lEYOL8a/zrydfg+HP8YXngJu++psJ9GRzHvHMbu3RfemMRazKlPMZ8eC1/jeeGqHu3t4TSJ0izG97FBgJm7MXVhogjrNxL87nfCm1+4LmboCubEx/X7WUXuMzM+Oa1LNUWkoVSrVYrFIsGpT9h0fbje5awM1w1HVmdnbn+FvDHh0lJeNVw794vi8XBt3uXMt0ylw4Ud5krML022SCwergtcvsOawQ3kTO8W2h/YQT6fJxa78ziN53kUi0XKZ0+z5ergKlZYR8Zg02lMqfz111o2TnhWoFIOw3IEXFjfS3LHgxQKBeKayiO30EiviMhq8P3wAqM7sRbzZeujet7yQ0lp7su31zyYiUbAaWrWYmZn7/E9gi/vS5EI0ZxeEREREYk8hV4RERERiTyFXhERERGJPIVeEREREYk8hV4RERERiTyFXhERERGJPIVeEREREYk8hV4RERERiTyFXhERERGJPIVeEWlYAabeJUgdWcDeZQ8E96cUWUPUA3InCr0i0nCMMRhjqMR0p/RmFhhD4Lo4zvL+VDmOQy0Ww97nuqRxWaAWiy27Z6S5qCtEpOEYY4jFXOZSaaoa7W1ac46Ln0ziOA7GfHkfOI6D67pUkikqRn/amlXFOFSSKdy7OFiS5qGOEJGGY4whHosTz2Y5kcrqdGUT8oFTmRwt6QzxePwrQ2/YMzESmQzH01n81SlTGogPHE9nSWQyxGOxr+wZaT4KvSLScIwxxBMJWnOtVDu7OOXE612SrLKP40lY10Uul11+6E0kyOVyBJ3dfBJrWaVKpVF8Emsh6Owml8sRTyQUemUJTZgTkYbjOA7xeJxMNsu6zk4uV6pMjI6wuVohbyDpGB2xR0wAzAWWMQwXEkncrh42rusknc4QW8aonTEm7JlMls7OTi5XKhy6PsKWaoUClpR6JnICoBRYihguJFqwnd1s6uwkk1negZI0H4VeEWlIjuOQSqXo6FgHGEZbWvi4WGRmdgavWsX3dQI7KowxOI5DoiVJLpuj0FGgs7OTQj5P8sac3uVwHIdkMklHoQOA6y0tnBgrMjMzQ7VaaYqeqdVqAMSa4CJQ13VJJJJks9mFnukodNxVz0hzif5/FSKyJjmOQywWI51O4xhDKpUin88zV5rDq3r4gY8u048IMx9gEqTTGXK5LJlMlmQyieu6yx6xCy+AjJFKp+kwhmQyRXt7nrm5ufBAqQl65qMPjwGw9/Hdda7kPjPgOi7xRIJ0Ok0ulyOTyZBKpe6qZ6S5KPSKSMOan+YQjgK2kMtm8Wo1fN/HWou1EU8wTWJ+ibpYzCUeixOLxxd+73cbXuZfk8lkSCQSZLNZPM9rip4JgoA3f3sEgP7NmyM92jnfM67rEr/RL1+3Z6R5KPSKSEObH72bHwmMenBpZvNBZv5xL+8zv2RVM/XM5MQkkxPTACTiCdra2+pc0f23Uj0jzUGhV0TWBP1Rk7vVbD3z2t//06LP/+RPv1/HakQaT3TPfYiIiDSJsdEiJz89vfD1yU9PMzZarGNFIo1HoVdERGSNO3P67LKeE2lmCr0iIiJr3IcfHF/WcyLNTKFXRERkDTt/7iJDV4YWzV92HIehK0NcOHexjpWJNBZdyCYiIrJGBUHAoTfe5sDBJ5manOLUyTMAHHx2PzXP58033qZ/S1+kly8TWS6FXhERkTXs+z94lWQqyd/+7O8Wnmtvb+OZZw9SLpXrWJlIY1HoFRERWaMcxyGZSgLw4O4dtLblAOjt3QSwsE1EwIxPTkd/xW4RERERaWqa5CMiIiIikafpDSIiIhFw7vPzjAxfA2Dzln42bFxf54pEGotCr4iISAQcP/YJ7/2/DwH4zndfUegV+QJNbxAREYkYa3W5jsgXaaRXREQiyVq7EP6aIQRaawmCAIDAD/B9v84V3X/zN+Qwxiy6OYfI7Sj0iohIpMyHP9/3GS+OMzx8jbnZOfwggAiH36tXRxZC74WLA7ixCJ/MNQbXcUhn0vT0dJEv5HFdF8dxFH7ljrRkmYiIRIa1Ft/3qZQrvH34KIfeOLIQBCWaHMfh+W88zTPPHqQl2YLrugq+clsKvSIiEgnWWmq1GuVymZ//n19w+uTZepckq+jB3Tv4w1d/j2QySSwWU/CVJSJ87kNERJpJEARUKhUOvXFYgbcJnT55lkNvHKZSqWh0X25LoVdERNa8+VHe69ev887R9+tdjtTJO0ff5/r169Rqtaa4eFHujkKviIisedZaPM9j+OoIga9RvmYV+AHDV0fwPE+hV5ZQ6BURkTUvDL1VpqdnFHaamLWW6ekZPK+qPpAlFHpFRGTNC6c3+HhVr96lSJ15VY9azVfolSUUekVEZM2bvxGFLmCSIAgW3ZhEZJ5Cr4iIREIYchR0RIFXbk+hV0REREQiT6FXRERERCJPoVdEREREIk+hV0REREQiT6FXRERERCJPoVdEREREIk+hV0REREQiL1bvAkRERJqN67oYx+B/4c5hxhjcmIu1Fr/mL+u9vvmtF+nq6lr4+vLgFd787VsrXrPIWqfQKyIissoe3buHZ587yOG3jvDh+8cWnu9Z38O//N4fcPLT0/z69d8u671isRgtiTiO47B5az+OuV9Vi6xtmt4gIiKyys59foHOrk4OPn0AY26m1O07ttHd08WF8wPLfq/Xfvk6P/pvf8Nf//h/UqvV7ke5IpGgkV4REZFVNjkxydCVIbq6u8jlskxNTQPQ39/L7OwcI8Mji/YvdBTYuXMbjhvj7OnPuH599K6+XzaXpaeni5Hha0xPzwCQyWZYv76b0dExJsYnF/Y1xtDX38uWrf1cG7nO6VNnCYLgHn9ikfpT6BUREamDs2c+Z+OmDeQL+YXQ27O+m2JxnFKpBEB7exv/5t/+gO6eLqYmp0mlU7zyrZc49Obby57+ALBt2xa+94NX+dlPf85HH4bTKfr7e/mTP/0+//DL1zl86AgAhY483/vXr9Lbt4mJiUlaW3NMTU7xv3/6cy5eWP7os0gjUugVERGpg4sXBsJ5uFv6Gbh4iUJHgXyhnXffeQ/fD0dW5+ZKnPz0ND/5q59SLI6TTqf59//hz3jx5Rf46INjjI0VV6we13X543/1h/T0dPOX//XHXDw/QMe6Av/uh3/Giy8/z4/+8m9W7HuJ1IPm9IqIiNTB4KUrBEHAw3t2AXDw6Sex1vL++x8v7FOtVvn167+lXC7zxL7H+J2XnicIwtUe2vPtK1pPOp2iu7uT4ZFrJJMJHty9nc6udQwNXaWvr3dFv5dIPWikV0REpA6q1SofvPcx+/bvJV9o59HHHuHihUvMzswu7JNOp/j9P/ouW7dt5srlq4yNjjE2VqTQkScWd1e0nlgsRjwRZ926Dr79nVcWbZucmsJxHM3tlTVNoVdERKRO3n7rKPv27+Wpg/tJZ1KcPnR20fannz3Inkce4sf//SecPfM5AC9841m279gGdun7BUGA47oYYxat/zsfVpPJxMJz8Xh80Ws9z6NSrjBw8RI/+ev/tVI/okjDUOgVERGpk4mJCSbGJ3jywBM4jsOlgcFF2/OFNiBcacF1XR7b+wgHnz0QbvzCerxBEDA3V2LDhh76N/dRqVQolcpMjE8wNTkFwMFnDjA1PYvjOLzy7ZcXvX5ursSF8wPs3LWdl15+gcOH3yHwfR7ctYPp6VldyCZrnvsf/9N//i/1LkJEROReBEFAqVTiyuUhLg8O1bucZQsCy7YHttCzvptqtcprv3wd3795J7bx4gQP7trB40+E83nzhXY+P3uOjZs2cOzjE4yNFm95r4B4PMH2ndvYf+AJDjy1j1qtxrnPzzM9M8OGDT1s6uvl0cceZvPmXn7zz2+ya/dOPjt7jksDg1hr+eyzc3QUCjz51BO8+NILfOPF53hg+zaKxSKXBi7X45/orvX2bWDjpo2kUilcd2WngMjaZsYnp29zgkRERGTt8DyPYrHIu++8x9G33693OSvKGMP69T0Ui+OUy+Wv3D+eiNPbu5Hx4gTj4xOLtrW1tdLSkuData9e53fDhh4qlQpjY+Nfu/Z6OPjMPvY/9SSFQmHJFA5pbpreICIi0sCstQwNXV32/l7V4/y5i7fdNnljmsNyDA0NL3tfkbVAS5aJiIiISOQp9IqIiIhI5Cn0ioiIiEjkKfSKiIiISOQp9IqIiIhI5Cn0ioiIiEjkKfSKiIiISOQp9IqIiIhI5Cn0iohIZBhj6l2C1Jl6QO5EoVdERCLBGIPruvUuQ+rMdV0FX7kthV4REVnzjDE4jkMmm1HgaWLGGDLZDI7jqA9kCYVeERFZ84wxxGIuhUI7be2t9S5H6qStvZVCoZ1YTKO9spRCr4iIrHnGGOLxBJlslsf3PUwy2VLvkmSVJZMtPL7vYTLZLPF4QqFXllDoFRGRNS8MvXFyuSzdPd3s3rODbDZd77JklWSzaXbv2UF3Tze5XJZ4PK7QK0vE6l2AiIjIvQqnN8TIZLJ0dKxj2wM1MtkUly9d4fq1caqVKkFg612mrCDHMSRaEnR25dnUt5Genh46OtaRyWSJxWIKvbKEQq+IiETC/GhvW1sbjmNItiRpa2tjdmaWarVCzffrXaKsoJjrkki0kMlmyLfnyRfy5HKtGuWVO1LoFRGRSJhfsiyZTC58bGtvp1wuU/M8giBAY73RYADHcYjF4ySTSdLpFMlking8rpUb5I4UekVEJDLmg+/8dIdUKo3v+1hrFx6y9hljFh6u6+K6Lo7j4Di6VEnuTKFXREQiZz4Azd+sQmE3muZHdDWyK8uh0CsiIpGlUCQi83QeQEREREQiT6FXRERERCJPoVdEREREIk+hV0REREQi7/8DP9Y72eQUIJ0AAAAASUVORK5CYII=)
图 9-13 数据库驱动树形结构
MySQL 的驱动 go-sql-driver/mysql 就实现了上图中的树形结构,我们可以使用语言原生的接口在 MySQL 中查询或者管理数据。
9.3.2 驱动接口
我们在这里从 database/sql 标准库提供的几个方法为入口分析这个中间层的实现原理,其中包括数据库驱动的注册、获取数据库连接和查询数据,这些方法都是我们在与数据库打交道时的最常用接口。
database/sql 中提供的 database/sql.Register 方法可以注册自定义的数据库驱动,这个 package 的内部包含两个变量,分别是 drivers 哈希以及 driversMu 互斥锁,所有的数据库驱动都会存储在这个哈希中:
func Register(name string, driver driver.Driver) {
driversMu.Lock()
defer driversMu.Unlock()
if driver == nil {
panic("sql: Register driver is nil")
}
if _, dup: = drivers[name];
dup {
panic("sql: Register called twice for driver " + name)
}
drivers[name] = driver
}
MySQL 驱动会在 go-sql-driver/mysql/mysql.init 中调用上述方法将实现 database/sql/driver.Driver 接口的结构体注册到全局的驱动列表中:
func init() {
sql.Register("mysql", & MySQLDriver {})
}
当我们在全局变量中注册了驱动之后,就可以使用 database/sql.Open 方法获取特定数据库的连接。在如下所示的方法中,我们通过传入的驱动名获取 database/sql/driver.Driver 组成 database/sql.dsnConnector 结构体后调用 database/sql.OpenDB:
func Open(driverName, dataSourceName string)( * DB, error) {
driversMu.RLock()
driveri, ok: = drivers[driverName]
driversMu.RUnlock()
if !ok {
return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)
}
...
return OpenDB(dsnConnector {
dsn: dataSourceName,
driver: driveri
}), nil
}
database/sql.OpenDB 会返回一个 database/sql.DB 结构,这是标准库包为我们提供的关键结构体,无论是我们直接使用标准库查询数据库,还是使用 GORM 等 ORM 框架都会用到它:
func OpenDB(c driver.Connector) * DB {
ctx, cancel: = context.WithCancel(context.Background())
db: = & DB {
connector: c,
openerCh: make(chan struct {}, connectionRequestQueueSize),
lastPut: make(map[ * driverConn] string),
connRequests: make(map[uint64] chan connRequest),
stop: cancel,
}
go db.connectionOpener(ctx)
return db
}
结构体 database/sql.DB 在刚刚初始化时不会包含任何的数据库连接,它持有的数据库连接池会在真正应用程序申请连接时在单独的 Goroutine 中获取。database/sql.DB.connectionOpener 方法中包含一个不会退出的循环,每当该 Goroutine 收到了请求时都会调用 database/sql.DB.openNewConnection:
func(db * DB) openNewConnection(ctx context.Context) {
ci, _: = db.connector.Connect(ctx)
...
dc: = & driverConn {
db: db,
createdAt: nowFunc(),
returnedAt: nowFunc(),
ci: ci,
}
if db.putConnDBLocked(dc, err) {
db.addDepLocked(dc, dc)
} else {
db.numOpen--
ci.Close()
}
}
数据库结构体 database/sql.DB 中的链接器是实现了 database/sql/driver.Connector 类型的接口,我们可以使用该接口创建任意数量完全等价的连接,创建的所有连接都会被加入连接池中,MySQL 的驱动在 go-sql-driver/mysql/mysql.connector.Connect 方法实现了连接数据库的逻辑。
无论是使用 ORM 框架还是直接使用标准库,当我们在查询数据库时都会调用 database/sql.DB.Query 方法,该方法的入参就是 SQL 语句和 SQL 语句中的参数,它会初始化新的上下文并调用 database/sql.DB.QueryContext:
func(db * DB) QueryContext(ctx context.Context, query string, args...interface {})( * Rows, error) {
var rows * Rows
var err error
for i: = 0;
i < maxBadConnRetries;
i++{
rows, err = db.query(ctx, query, args, cachedOrNewConn)
if err != driver.ErrBadConn {
break
}
}
if err == driver.ErrBadConn {
return db.query(ctx, query, args, alwaysNewConn)
}
return rows, err
}
database/sql.DB.query 的执行过程可以分成两个部分,首先调用私有方法 database/sql.DB.conn 获取底层数据库的连接,数据库连接既可能是刚刚通过连接器创建的,也可能是之前缓存的连接;获取连接之后调用 database/sql.DB.queryDC 在特定的数据库连接上执行查询:
func(db * DB) queryDC(ctx, txctx context.Context, dc * driverConn, releaseConn func(error), query string, args[] interface {})( * Rows, error) {
queryerCtx, ok: = dc.ci.(driver.QueryerContext)
var queryer driver.Queryer
if !ok {
queryer, ok = dc.ci.(driver.Queryer)
}
if ok {
var nvdargs[] driver.NamedValue
var rowsi driver.Rows
var err error
withLock(dc, func() {
nvdargs, err = driverArgsConnLocked(dc.ci, nil, args)
if err != nil {
return
}
rowsi, err = ctxDriverQuery(ctx, queryerCtx, queryer, query, nvdargs)
})
if err != driver.ErrSkip {
if err != nil {
releaseConn(err)
return nil, err
}
rows: = & Rows {
dc: dc,
releaseConn: releaseConn,
rowsi: rowsi,
}
rows.initContextClose(ctx, txctx)
return rows, nil
}
}
...
}
上述方法在准备了 SQL 查询所需的参数之后,会调用 database/sql.ctxDriverQuery 完成 SQL 查询,我们会判断当前的查询上下文究竟实现了哪个接口,然后调用对应接口的 Query 或者 QueryContext:
func ctxDriverQuery(ctx context.Context, queryerCtx driver.QueryerContext, queryer driver.Queryer, query string, nvdargs[] driver.NamedValue)(driver.Rows, error) {
if queryerCtx != nil {
return queryerCtx.QueryContext(ctx, query, nvdargs)
}
dargs, err: = namedValueToValue(nvdargs)
if err != nil {
return nil, err
}
...
return queryer.Query(query, dargs)
}
对应的数据库驱动会真正负责执行调用方输入的 SQL 查询,作为中间层的标准库可以不在乎具体的实现,抹平不同关系型数据库的差异,为用户程序提供统一的接口。
9.3.3 总结
Go 语言的标准库 database/sql 是一个抽象层的经典例子,虽然关系型数据库的功能相对比较复杂,但是我们仍然可以通过定义一系列构成树形结构的接口提供合理的抽象,这也是我们在编写框架和中间层时应该注意的,即面向接口编程 —— 只依赖抽象的接口,不要依赖具体的实现。