普通類創建獲取session 方式_猿蛻變11——一文搞懂mybatis花式使用方式

看過之前的蛻變系列文章,相信你對mybatis有了初步的認識。但是這些還不夠,我們今天進一步來了解下mybatis的一些用法。

猿蛻變同樣是一個原創系列文章,幫助你從一個普通的小白,開始掌握一些行業內通用的框架技術知識以及鍛煉你對系統設計能力的提升,完成屬于你的蛻變,更多精彩內容,還是私信我吧,黑機構太多,老是舉報我,大號都被封號了(由此可見對這些黑機構的傷害有多深)。

f4ec5749884195810db35e0e9699550f.png

86b8d90524ed88a9f7fac0d10f4254ae.png

d85f5231a060af992b705ed1b45bfadc.png

8a824a052f8f007d56e4658c795d025b.png

baa867476737b7f8670970ae383d4178.png

0bf857900267e446823e297615cfd1d4.png

我們第一個程序存在很多問題,每一次操作,都需要讀取配置文件、初始化mybati框架。這樣搞出來的程序上就一個字——渣!這讓我想起了多年以前,某個小伙伴告訴我spring的正確使用一樣,每次方法都讓spring框架重新初始化了一次。哈哈,知道你也在看的,又是一波回憶殺。

在第一個mybatis程序中,獲取SqlSession對象的方式也比較復雜,獲取SqlSession對象的操作比較復雜,由于SqlSessionFactory本身就是用來管理SqlSession對象的,應用中一般情況下有一個就足夠了!我們做一個小優化——使用單利模式來封裝下,讓一個SqlSessionFactory對象去管理SqlSession對象。

f9c665f9db68d42b89548df572342ee6.png

1.創建一個MyBatisUtil工具類:

package com.pz.route.util;import java.io.IOException;
import java.io.InputStream;import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;public class MyBatisUtil {private static SqlSessionFactory sqlSessionFactory;static{//讀取主配置文件InputStream input = null;if (sqlSessionFactory == null) {try {input = Resources.getResourceAsStream("mybatis.xml");} catch (IOException e) {// TODO Auto-generated catch blocke.printStackTrace();}synchronized (MyBatisUtil.class) {if (sqlSessionFactory == null){sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);}}}}publicstatic SqlSession getSqlSession() {returnsqlSessionFactory.openSession();}}

上面的例子使用了靜態代碼塊的方式創建了一個SqlSessionFactory對象,將SqlSession交給SqlSessionFactory進行管理。

2.修改TravelRouteDaoImpl類:

package com.pz.route.dao.impl;import org.apache.ibatis.session.SqlSession;import com.pz.route.dao.TravelRouteDao;
import com.pz.route.domain.TravelRoute;
import com.pz.route.util.MyBatisUtil;public class TravelRouteDaoImpl implements TravelRouteDao {private SqlSession sqlSession;@Overridepublic void add(TravelRoute travelRoute) {try {sqlSession = MyBatisUtil.getSqlSession();//新增數據操作sqlSession.insert("com.pz.route.dao.TravelRouteDao.add", travelRoute);//提交SqlSessionsqlSession.commit();//無需再做關閉,SqlSessionFactory會自動關閉sqlSession} catch (Exception e) {e.printStackTrace();}}}

SqlSession繼承了AutoCloseable接口,SqlSessionFactory會自動關閉SqlSession。

48c0662a72546ba8aa8394603122daba.png

數據庫的一些信息最好不要寫死在xml里,大家基本上都是通過配置的方式讀取數據庫相關信息。在resources目錄下創建db.properties配置文件,里面填寫下面內容:

jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/route?characterEncoding=utf8
jdbc.username=root
jdbc.password=123456

修改mybatis.xml文件,使用將數據庫連接信息修改為使用配置文件的方式:

<?xml version="1.0"encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><!-- 引入數據庫配置信息 --><properties resource="db.properties"/><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><property name="driver"value="${jdbc.driverClassName}"/><property name="url"value="${jdbc.url}"/><property name="username"value="${jdbc.username}"/><property name="password"value="${jdbc.password}"/></dataSource></environment></environments><mappers><!--注冊映射文件--><mapper resource="mapper/TravelRouteMapper.xml"/></mappers>
</configuration>

9188f15f951d79064acd93deabfd01f2.png

我們新建了Mybatis.xml作為使用Mytatis的主配置文件,那么這個主配置文件應該干些什么事情呢?

1.配置外部配置文件,方便程序使用(比如配置db.properties)

2.設置全局Domain類JavaBean的別名(每次使用類的名稱空間寫起來太麻煩了)

3.配置運行環境

4.配置mapper文件(有哪些數據操作使用了mybatis需要要告訴框架)

5. 設置全局的數據庫操作配置,比如事務超時時間等等信息


我們看看mybatis.xml中的內容:

<properties resource="db.properties"/

這樣配置以后,mybatis就可以從db.properties中獲取數據庫信息了。

我們看看這個配置我們在mapper文件中的寫法:

<insert id="add"parameterType="com.pz.route.domain.TravelRoute">

在mapper中的parameterType需要使用類的名稱空間:包名+類名的方式。每次這樣寫比較麻煩,也比較容易寫錯。MyBatis提供了<typeAliases>標簽用以定義別名。

     <typeAliases><typeAlias type="com.pz.route.domain.TravelRoute"alias="TravelRoute"/></typeAliases>

這樣子,在mapper中就可以直接使用TravelRoute來代替之前的 com.pz.route.domain.TravelRoute。

一個項目上線,需要經歷多個階段,一般來講一個項目需要經過開發,測試,上線的生命周期。那么不可避免的,一個項目會有多個運行環境。

比如在開發階段,應用往往運行在本地,測試階段,會運行在測試服務器,到了應用上線之后,應用自然運行在生產機器上。在不同的環境下,數據庫也會有多個,比如開發環境在A庫,測試時在B庫,項目上線以后在生產庫C,那么為了支持不同的環境,mybatis提供了<environments>標簽來支持多個環境的問題。

<environments default="development"><environment id="development"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver"value="${jdbc.driverClassName}" /><property name="url"value="${jdbc.url}" /><property name="username"value="${jdbc.username}" /><property name="password"value="${jdbc.password}" /></dataSource></environment><!--測試環境 --><environment id="test"><transactionManager type="JDBC" /><dataSource type="POOLED"><property name="driver"value="${jdbc.test.driver}" /><property name="url"value="${jdbc.test.url}" /><property name="username"value="${jdbc.test.user}" /><property name="password"value="${jdbc.test.password}" /></dataSource></environment></environments>

大家可以看到再environments標簽中有兩個environment子標簽,配置了兩個數據庫信息environments標簽中的default屬性,用于選擇到底使用的是哪個環境。

transactionManager標簽用于設置事務管理器用于MyBatis的事務管理。MyBatis 支持兩種事務管理器類型:

JDBC
需要再程序中使用通過SqlSession對象的commit()方法提交,通過rollback()方法回滾,默認情況下是需要手動提交的。

MANAGED
由Mybatis來管理事務的整個事務的生命周期,默認情況下,每次操作都會關閉數據庫連接。

dataSource標簽主要用于配置應用的數據源連接方式和數據庫連接信息,使用type屬性來設置數據源類型:

UNPOOLED
表示不使用數據庫連接池,每次數據庫操作Mybatis都需要創建一個Connection對象。

POOLED
使用Mybatis提供的數據庫連接池。

JNDI
使用JNDI數據源(JNDI的方式一般是配置在應用服務器中)

1971993f76783fa0f93018584a910509.png

Mapper標簽的作用就是通知Mybatis使用哪些mapper文件,一共有四種寫法:

第一種:使用mapper文件的相對路徑,這個路徑是相對于classpath而言的。

<!--注冊映射文件 --><mapper resource="mapper/TravelRouteMapper.xml" />

第二種:使用url

<!--注冊映射文件 --><mapper url="D://xxx/xxxMapper.xml" />

第三種:使用類的名稱空間,使用這種方式,需要滿足以下幾個規約:

1.Mapper文件名要與 Dao 接口名相同

2.Mapper文件要與接口在同一包中

3.Mapper文件中的 namespace 屬性值為 Dao 接口的類的名稱空間

<!--注冊映射文件 --><mapper class="com.pz.route.dao.TravelRouteDao" />

第四種:使用mybatis提供的動態代理實現(無需自己實現xxxDaoImpl)

使用這種方式,需要滿足以下幾個規約:

(1)dao 使用 mapper 的動態代理實現(后面再將)

(2)Mapper文件名與 Dao 接口名相同

(3)Mapper文件與接口放在同一包中

(4)Mapper文件中的 namespace 屬性值為 Dao接口的類的名稱空間

<!--注冊映射文件 -->
<mapper package="com.pz.route.dao" />

d7684cbfd12d6e6efc7c279c07a743c4.png

我們編寫的第一個MyBatis程序,實現了一個向route數據庫travel_route表中新增一條數據的功能,有一些比較值得注意的地方大家一起來看下:

<insert id="add"parameterType="com.pz.route.domain.TravelRoute">INSERTINTO travel_route(travel_route_name,travel_route_price,travel_route_introduce,travel_route_flag,travel_route_date,isThemeTour,travel_route_count,travel_route_cid,travel_route_image,travel_route_seller_id)values(#{travelRouteName},#{travelRoutePrice},#{travelRouteIntroduce},#{travelRouteFlag},#{travelRouteDate},#{isThemeTour},#{travelRouteCount},#{travelRouteCid},#{travelRouteImage},#{travelRouteSellerId})</insert>

id:需要執行的SQL語句的唯一標識,實際上它mybatix被識別的方式是namespace+id,一個id可被用代表一段需要執行的sql語句,在一個mapper文件中對id值的要求是不能重復出現的。

parameterType:sql語句中參數的類型,實際上MyBatis利用反射機制感知dao接口的參數類型,不寫這個配置也是可以的

#{ }:這個符號表示參數,支持el表達式,我們通過JavaBean的方式做參數傳遞,花括號里的值為JavaBean的屬性,如果屬性也是對象,支持對象名.方法名的形式。

Mybatis事務提交,我們看TravelRouteDaoImpl:

try {sqlSession = MyBatisUtil.getSqlSession();//新增數據操作sqlSession.insert("com.pz.route.dao.TravelRouteDao.add", travelRoute);//提交SqlSessionsqlSession.commit();//無需再做關閉,SqlSessionFactory會自動關閉sqlSession} catch (Exception e) {e.printStackTrace();}

默認情況下Mybatis的事務是不會自動提交的,如果想自動提交事務,可以在MyBatisUtil中修改openSession的方法,傳入參數true。如果不傳入任何參數或者傳入false,mybatis無法自動提交事務。

 public static SqlSession getSqlSession() {return sqlSessionFactory.openSession(true);}

如果不提交事務,數據是不會持久化到數據庫的。

travel_route表,我們設置的主鍵是自增長類型,所以在編寫SQL的時候,我們不用寫入主鍵travel_route_id,如果我們想在插入數據后獲取主鍵我們可以使用下面的方式:

  <selectKey resultType="Long"keyProperty="travelRouteId" order="AFTER">SELECT @@identity</selectKey>

這樣子在mybatis完成insert操作之后后,會將當前寫入數據的ID查詢出來,重寫Travle的toString方法,再編寫一段程序看下效果:

       @Testpublic void testAddTravelRoute(){TravelRouteDao travelRouteDao = new TravelRouteDaoImpl();TravelRoute travelRoute = new TravelRoute();travelRoute.setTravelRouteName("新增線路2");travelRoute.setTravelRoutePrice(999d);travelRoute.setTravelRouteDate("2019-10-26");travelRoute.setTravelRouteFlag(1);travelRoute.setIsThemeTour("1");travelRoute.setTravelRouteCount(0);travelRoute.setTravelRouteCid(1);travelRoute.setTravelRouteIntroduce("雙導游服務,免收服務小費,周全照顧貼心服務隨心出游!品嘗越南特色國寶美食,升級一餐越式炸雞火鍋宴!");travelRoute.setTravelRouteImage("img/product/small/m3db4d2277b5df3d98597f79082ef92d6d.jpg");travelRoute.setTravelRouteSellerId(1L);System.out.println("before insert===");System.out.println(travelRoute);travelRouteDao.add(travelRoute);System.out.println("after insert===");System.out.println(travelRoute);}

我們再在TravelRouteDaoImpl中commit打印增加兩行打印代碼

@Overridepublic void add(TravelRoute travelRoute) {try {sqlSession = MyBatisUtil.getSqlSession();//新增數據操作sqlSession.insert("com.pz.route.dao.TravelRouteDao.add", travelRoute);System.out.println("before commit===");System.out.println(travelRoute);//提交SqlSessionsqlSession.commit();//無需再做關閉,SqlSessionFactory會自動關閉sqlSession} catch (Exception e) {e.printStackTrace();}}

運行程序后,我們可以清晰地看到,在commit之前,id已經有值了,實際上,當insert語句執行后,commit之前,主鍵id已經返回了數據,這個事務不管是commit或者是rollback,travel_route的主鍵已經使用掉一個了,再做insert操作mysql只會分配一個新的主鍵。由此我們得出一個結論:數據庫主鍵的分配和是否提交無關,只要執行了insert操作,mysql就會分配一個主鍵。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/446169.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/446169.shtml
英文地址,請注明出處:http://en.pswp.cn/news/446169.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Ubuntu配置IPFS的環境

參考鏈接 Ubuntu上IPFS環境搭建 - 簡書 下載安裝包 下載地址&#xff1a;https://dist.ipfs.io/#go-ipfs頁面會自動根據你的操作系統提供適合的下載安裝包&#xff0c;所以需要在Ubuntu環境下點開上面那個鏈接&#xff0c;網頁自動識別當前的平臺并提供對應的版本&#xff0c…

composer升級_Composer-命令簡介

簡介Composer 是一個用于 PHP 依賴管理的工具。它實現了讓你聲明項目所依賴的庫&#xff0c;并幫你完成安裝/更新過程。以下命令來自 composer version 1.8.0。翻譯使用【百度翻譯】。通過在命令窗口執行&#xff1a;composer或者&#xff1a;composer list得到 composer 的全部…

Ubuntu搭建聯盟鏈,實現節點之間數據同步

安裝go環境 從參考鏈接選擇Linux版本的go的安裝包 使用命令 mv go&#xff08;Tab補全&#xff09;/usr/local 移動go安裝包到/usr/local目錄下使用命令解壓 sudo tar -xvzf go(Tab補全) 配置環境 sudo gedit ~/.profile export PATH$PATH:/usr/local/go/bin激活生效 sou…

關于python語言的編程模式、哪個說法正確_測驗1: Python基本語法元素 (第1周) 單選題+程序題...

第1章測驗&#xff0c;共10道單選題和2道編程題&#xff0c;限答1次 單選題 1.Guido van Rossum正式對外發布Python版本的年份是&#xff1a; A.2002 B.1998 C.2008 D.1991 正確答案&#xff1a; D Python成功了&#xff0c;所以早年的開發歷史也受到關注&#xff0c;以下是Gui…

火狐瀏覽器添加MetaMask錢包和本地開啟私有鏈開發

火狐瀏覽器添加MetaMask錢包 因為對其配置了代理工具&#xff0c;所以直接使用谷歌引擎搜索MetaMask錢包即可第一次使用&#xff0c;立即開始設置 點擊我同意&#xff0c;進行密碼的創建 牢記助記詞&#xff0c;助記詞及其關鍵&#xff0c;將其存儲在安全的地方 區塊鏈-開發 M…

python賦值01_python學習筆記1-賦值與字符串 | 學步園

閱讀本學習筆記需有一定語言基礎&#xff0c;閑話少說&#xff0c;我們開始 一、賦值與數字 【簡介】 python的賦值很簡單&#xff1a; number 1 # 數值 number 2 2 # 支持加減乘除運算 number (1 2j) * (1 - 1j) # 支持復數的運算 二、字符串 【簡介】 str "Hello,…

CLion導入用戶自己的lib和頭文件

文件的層級結構如上面所示對應的CMakeLists.txt配置文件如下面所示 cmake_minimum_required(VERSION 3.15) project(smart_shap)set(CMAKE_CXX_STANDARD 14)add_executable(${PROJECT_NAME} main.cpp )#target_link_directories(${PROJECT_NAME} PRIVATE ${PROJECT_SOURCE_DIR}…

東芝移動硬盤驅動_傳輸數據不用等,高速移動硬盤數據線暢享快傳體驗

不管你是設計師&#xff0c;攝影師亦或是辦公一族&#xff0c;幾乎都能用到電腦&#xff0c;而電腦里的文件如果很多的話&#xff0c;為了安全起見都會備份一份數據&#xff0c;以免電腦儲存容量過大導致電腦卡頓。另一方面&#xff0c;為了保護數據防止丟失造成不必要的麻煩&a…

使用國密瀏覽器和使用Wireshark進行國密抓包

使用的軟件 信密瀏覽器 密信瀏覽器發布Windows正式版 - 密信技術國密Wireshark GMSSL - 國密SSL實驗室支持國密算法的網站 https://www.wotrus.com/ 流程操作 打開windows終端&#xff0c;使用命令ping沃通網站&#xff0c;找到這個網站的ip地址 ping www.wotrus.com打…

django框架學習文檔_Python四大主流網絡編程框架,你知道么?

高并發處理框架—— TornadoTornado 是使用 Python 編寫的一個強大的可擴展的 Web 服務器。它在處理高網絡流量時表現得足夠強健&#xff0c;卻在創建和編寫時有著足夠的輕量級&#xff0c;并能夠被用在大量的應用和工具中。Tornado 作為 FriendFeed 網站的基礎框架&#xff0c…

VS Studio報錯無法解析的外部符號 _imp_XXXXXXXXX

出現字符_imp&#xff0c;說明不是真正的靜態庫&#xff0c;而是某個動態庫的導入庫&#xff0c;導入函數和自己不同名&#xff0c;所以加了字符_imp。比如說_imp_GetUserNameA就是GetUserNameA函數。會報這種錯誤的原因&#xff1a; 1、說明注冊表函數沒有相關的lib庫&#xf…

hashmap put過程_阿里十年技術大咖,教你如何分析1.7中HashMap死循環

在多線程環境下&#xff0c;使用HashMap進行put操作會引起死循環&#xff0c;導致CPU利用率接近100%&#xff0c;HashMap在并發執行put操作時會引起死循環&#xff0c;是因為多線程會導致HashMap的Entry鏈表形成環形數據結構&#xff0c;一旦形成環形數據結構&#xff0c;Entry…

Socket代碼實現服務端 和 客戶端之間通信

服務端代碼 // Socket_connection.cpp : 此文件包含 "main" 函數。程序執行將在此處開始并結束。 // #ifndef UNICODE #define UNICODE #endif#define WIN32_LEAN_AND_MEAN#include <winsock2.h> #include <Ws2tcpip.h> #include <stdio.h> #incl…

python綜合管理系統_Python-20 (信息系統-框架/循環/增刪/綜合應用)

# 1. 目標 這里我們通過簡單案例的綜合應用&#xff0c;了解框架的概念&#xff0c;感受循環、字符字典數據處理等基礎點的應用場景 # 2. 框架 搭建一個人員信息管理系統的簡單框架&#xff0c;初步感受框架的概念。 1> 主程序 -- cards_mian.py程序的主功能代碼&…

本地搭建server和客戶端使用端口進行數據通信,使用Wireshark抓取127.0.0.1環回地址并分析通信數據

本地搭建服務端和客戶端 參考網址 Socket代碼實現服務端 和 客戶端之間通信_CHYabc123456hh的博客-CSDN博客server指定通信的端口是 5099client 使用的端口是動態變化的&#xff0c;因此在wireshark里面需要設定的抓取端口是 5099 使用wireshark開啟抓包 參考鏈接 [tcp] Wir…

double operator[](int i)_java中double類型精度丟失問題及解決方法

原文鏈接&#xff1a;https://blog.csdn.net/yacolspace/article/details/78287394double類型數據加減操作精度丟失問題今天在項目中用到double類型數據加減運算時&#xff0c;遇到了一個奇怪的問題&#xff0c;比如120.2300.03&#xff0c;理論上結果應該是321.23&#xff0c;…

驗證客戶端和服務端可以傳輸經SM4加密的密文數據,從而驗證發送數據已使用服務器密碼機進行SM4加密,而不是隨便的字符串亂碼

前提操作 搭建客戶端和服務端 Socket代碼實現服務端 和 客戶端之間通信_CHYabc123456hh的博客-CSDN博客使用wireshark進行數據的監聽和測試https://blog.csdn.net/CHYabc123456hh/article/details/121929288 結論驗證 使用在線SM4加密&#xff0c;輸入明文 和 選擇模式,生成…

Socket編程 涵蓋代碼和函數參數介紹

Socket是針對端系統&#xff0c;也就是用戶主機上開發程序&#xff0c;不涉及網絡設備(交換機、路由器)獨立于網卡驅動層之上&#xff0c;不涉及硬件&#xff0c;即基于Packet Driver編程端&#xff1a;是指通信雙方兩臺電腦 應用編程接口API 也就是兩端 應用層內部的應用進程之…

springcloud阿里巴巴五大組件_如何無縫遷移 SpringCloud/Dubbo 應用到 Serverless 架構

簡介&#xff1a; 本文分為三部分來介紹&#xff0c;分別介紹微服務應用遷移到 SAE 的優勢&#xff0c;如何遷移 SpringCloud/Dubbo 應用到 SAE 上&#xff0c;以及針對 SpringCloud 應用遷移的實踐演示。背景通過前面幾節課程的學習&#xff0c;相信大家對于 SAE 平臺已經有了…