Mybatis基礎知識極其運用解析

mybatis的介紹

Mybatis是一個封裝來jdbc的持久層框架,它和Hibernate都屬於ORM框架,但是具體來講,Hibernate是一個完全的ORM框架,而Mybatis是一個不完全的ORM框架。

Mybatis讓程序員只關注sql本身,而不需要再去關注如連接的創建、statement的創建等操作(類似於把需要重複使用的方法包裝起來)。

 

Mybatis會將輸入參數、輸出結果進行映射。

分析jdbc的問題

原生態的jdbc代碼

public static void main(String[] args) {

Connection connection = null;

PreparedStatement preparedStatement = null;

ResultSet resultSet = null;



try {

//1、加載數據庫驅動

Class.forName("com.mysql.jdbc.Driver");

//2、通過驅動管理類獲取數據庫鏈接

connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "admiin");

//3、定義sql語句 ?表示佔位符

String sql = "select * from user where username = ?";

//4、獲取預處理statement

preparedStatement = connection.prepareStatement(sql);

//5、設置參數,第一個參數爲sql語句中參數的序號(從1開始),第二個參數爲設置的參數值

preparedStatement.setString(1, "王五");

//6、向數據庫發出sql執行查詢,查詢出結果集

resultSet =  preparedStatement.executeQuery();

//7、遍歷查詢結果集

while(resultSet.next()){

User user

System.out.println(resultSet.getString("id")+"  "+resultSet.getString("username"));

}

} catch (Exception e) {

e.printStackTrace();

}finally{

//8、釋放資源

if(resultSet!=null){

try {

resultSet.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(preparedStatement!=null){

try {

preparedStatement.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

if(connection!=null){

try {

connection.close();

} catch (SQLException e) {

// TODO Auto-generated catch block

e.printStackTrace();

}

}

}

}

 

 

總結:

1.在創建連接時,存在硬編碼

2.配置文件(全局配置文件):

在執行statement時存在硬編碼

3.配置文件(映射文件)

頻繁的開啓和關閉數據庫連接,會造成數據庫性能下降。

數據庫連接池(全局配置文件)

 

Mybatis的框架原理

參考畫圖.xlsx

 

入門程序

從需求入手:

對訂單商品案例中的用戶表進行增刪改查操作

  1. 根據用戶ID查詢用戶信息
  2. 根據用戶名稱模糊查詢用戶列表
  3. 添加用戶
  4. 刪除用戶(練習)
  5. 修改用戶(練習)

 

環境配置準備

Jdk:1.8
Idea:Rapideclipse 
Mybatis:3.5.2
數據庫:MySQL 

 

下載mybatis(去maven裏查找然後注入依賴)

 

  1. 數據庫腳本初始化
    1. 數據庫腳本
導入包:

1.執行sql_table.sql腳本,創建數據庫表;
2.執行sql_data.sql初始化測試數據。

 

工程搭建

  1. 注入Mybatis的核心包和依賴包
  2. 注入MySQl的驅動包
  3. Junit(非必須)

 

代碼實現

創建pojo類(例如對象的屬性,getset方法等等)

創建全局配置文件

在config目錄下,創建mybatis-config.xml文件。

需求開發

  1. 根據用戶ID查詢用戶信息

映射文件:

在config目錄下,創建UserMapper.xml(這種命名規範是由ibatis遺留下來)

 

 

在全局配置文件中加載映射文件

測試代碼

記得更改圖中的配置文件,那是先前的~

 

根據用戶名稱模糊查詢用戶列表

  1. 射文件

 

測試代碼

 

2.添加用戶

映射文件

 

測試代碼

 

​​​​​​​主鍵返回之自增主鍵

 

​​​​​​​主鍵返回值UUID

UUID函數是mysql的函數

 

 

​​​​​​​主鍵返回值序列

序列也就是sequence,它是Oracle的主鍵生成策略

 

​​​​​​​小結

認識一些比較特殊的符號(及語法使用差不多)

1.#{}和${}

#{}表示佔位符?,#{}接收簡單類型的參數時,裏面的名稱可以任意

${}表示拼接符,${}接收簡單類型的參數時,裏面的名稱必須是value

${}裏面的值會原樣輸出,不加解析(如果該參數值是字符串,有不會添加引號)

${}存在sql注入的風險,但是有些場景下必須使用,比如排序後面會動態傳入排序的列名

   2.parameterType和resultType

parameterType指定輸入參數的java類型,parameterType只有一個,也就是說入參只有一個。

resultType指定輸出結果的java類型(是單條記錄的java類型)

3.selectOne和selectList

selectOne查詢單個對象

selectList查詢集合對象

 

mybatis開發dao的方式

​​​​​​​需求:

  1. 根據用戶ID查詢用戶信息
  2. 根據用戶名稱模糊查詢用戶列表
  3. 添加用戶
    1. 原始dao的開發方式

即開發dao接口和dao實現類

 

1.Dao接口

 

​​​​​​​2.Dao實現類

SqlSessionFactory,它的生命週期,應該是應用範圍,全局範圍只有一個工廠,使用單例模式來實現這個功能。與spring集成之後,由spring來對其進行單例管理。

 

SqlSession,它內部含有一塊數據區域,存在線程不安全的問題,所以應該將sqlsession聲明到方法內部。

 

public class UserDaoImpl implements UserDao {

// 依賴注入
private SqlSessionFactory sqlSessionFactory;

public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}

@Override
public User findUserById(int id) throws Exception {
// 創建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

// 調用SqlSession的增刪改查方法
// 第一個參數:表示statement的唯一標示
User user = sqlSession.selectOne("test.findUserById", id);
System.out.println(user);
// 關閉資源
sqlSession.close();
return sqlSession.selectOne("test.findUserById", 1);
}

@Override
public List<User> findUsersByName(String name) {
// 創建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

// 調用SqlSession的增刪改查方法
// 第一個參數:表示statement的唯一標示
List<User> list = sqlSession.selectOne("test.findUsersByName", name);
System.out.println(list);
// 關閉資源
sqlSession.close();
return list;
}

@Override
public void insertUser(User user) {
// 創建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();

// 調用SqlSession的增刪改查方法
// 第一個參數:表示statement的唯一標示
sqlSession.insert("test.insertUser", user);

System.out.println(user.getId());
// 提交事務
sqlSession.commit();
// 關閉資源
sqlSession.close();
}

}

​​​​​​​測試代碼

 

​​​​​​​問題思考?

  1. 以上代碼有大量的重複的模板代碼
  2. 存在硬編碼
  3. 想辦法改善它

 

​​​​​​​Mapper代理的開發方式

即開發mapper接口(相當於dao接口)

 

Mapper代理使用的是jdk的代理策略。

 

​​​​​​​Mapper代理的開發規範

  1. mapper接口的全限定名要和mapper映射文件的namespace值一致。
  2. mapper接口的方法名稱要和mapper映射文件的statement的id一致。
  3. mapper接口的方法參數類型要和mapper映射文件的statement的parameterType的值一致,而且它的參數是一個。
  4. mapper接口的方法返回值類型要和mapper映射文件的statement的resultType的值一致。

 

  1. mapper接口

​​​​​​​​​​​​​​mapper映射文件

在config下創建mapper目錄然後創建UserMapper.xml(這是mybatis的命名規範,當然,也不是必須是這個名稱)

sqlSession內部的數據區域本身就是一級緩存,是通過map來存儲的。

 

  1. 加載映射文件

     ​​​​​​​2.測試代碼

 

  1. 全局配置文件
    1. 概覽

SqlMapConfig.xml的配置內容和順序如下(順序不能亂):

Properties(屬性)

Settings(全局參數設置)

typeAliases(類型別名)

typeHandlers(類型處理器)

objectFactory(對象工廠)

plugins(插件)

environments(環境信息集合)

environment(單個環境信息)

transactionManager(事物)

dataSource(數據源)

mappers(映射器)
    1. 常用配置
      1. Properties

jdbc.properties

 

SqlMapConfig.xml

 

 

加載的順序

  1. 先加載properties中property標籤聲明的屬性
  2. 再加載properties標籤引入的java配置文件中的屬性
  3. parameterType的值會和properties的屬性值發生衝突。

 

  1. settings

mybatis全局配置參數,全局參數將會影響mybatis的運行行爲。

詳細參見“mybatis學習資料/mybatis-settings.xlsx”文件

​​​​​​​2.typeAliases

對po類進行別名的定義

  1. mybatis支持的別名

別名

映射的類型

_byte

byte

_long

long

_short

short

_int

int

_integer

int

_double

double

_float

float

_boolean

boolean

string

String

byte

Byte

long

Long

short

Short

int

Integer

integer

Integer

double

Double

float

Float

boolean

Boolean

date

Date

decimal

BigDecimal

bigdecimal

BigDecimal

 

​​​​​​​自定義別名

1.Mappers

<mapper resource=’’/>

使用相對於類路徑的資源

如:<mapper resource="sqlmap/User.xml" />

​​​​​​​2.<mapper url=’’/>

使用完全限定路徑

如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />​​​​​​​

3.<mapper class=’’/>

使用mapper接口的全限定名

如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

 

注意此種方法要求mapper接口和mapper映射文件要名稱相同,且放到同一個目錄下

  1. <package name=’’/>(推薦)

註冊指定包下的所有映射文件

如:<package name="cn.itcast.mybatis.mapper"/>

 

注意此種方法要求mapper接口和mapper映射文件要名稱相同,且放到同一個目錄下

 

映射文件:

1.輸入映射

2.簡單類型

根據用戶ID查詢用戶信息的映射文件

​​​​​​​Pojo類型

添加用戶的映射文件

包裝pojo類型

需求:

綜合查詢時,可能會根據用戶信息、商品信息、訂單信息等作爲條件進行查詢,用戶信息中的查詢條件由:用戶的名稱和性別進行查詢

 

​​​​​​​1建包裝pojo

 

​​​​​​​2.映射文件

 

​​​​​​​3.Mapper接口

 

​​​​​​​4.測試代碼

​​​​​​​Map結合使用

同傳遞POJO對象一樣,map的key相當於pojo的屬性

 

1.​​​​​​​映射文件

<!-- 傳遞hashmap綜合查詢用戶信息 -->

<select id="findUserByHashmap" parameterType="hashmap" resultType="user">

   select * from user where id=#{id} and username like '%${username}%'

</select>

 

2.​​​​​​​測試代碼

Public void testFindUserByHashmap()throws Exception{

//獲取session

SqlSession session = sqlSessionFactory.openSession();

//獲限mapper接口實例

UserMapper userMapper = session.getMapper(UserMapper.class);

//構造查詢條件Hashmap對象

HashMap<String, Object> map = new HashMap<String, Object>();

map.put("id", 1);

map.put("username", "管理員");



//傳遞Hashmap對象查詢用戶列表

List<User>list = userMapper.findUserByHashmap(map);

//關閉session

session.close();

}

 

 

異常測試:

傳遞的map中的key和sql中解析的key不一致。

測試結果沒有報錯,只是通過key獲取值爲空。

輸出映射

  1. ​​​​​​​resultType
    1. 使用要求

使用resultType進行結果映射時,需要查詢出的列名和映射的對象的屬性名一致,才能映射成功。

 

如果查詢的列名和對象的屬性名全部不一致,那麼映射的對象爲空。

如果查詢的列名和對象的屬性名有一個一致,那麼映射的對象不爲空,但是隻有映射正確那一個屬性纔有值。

 

如果查詢的sql的列名有別名,那麼這個別名就是和屬性映射的列名。

​​​​​​​1.簡單類型

注意,對簡單類型的結果映射也是有要求的,查詢的列必須是一列,才能映射爲簡單類型。

 

​​​​​​​​​​​​​​2.需求

綜合查詢時,需要根據綜合查詢的添加查詢用戶的總數

 

​​​​​​​3.映射文件

​​​​​​​4.Mapper接口

​​​​​​​5.測試代碼

​​​​​​​Pojo對象和pojo列表

參考入門程序之根據用戶ID查詢用戶信息和根據用戶名稱模糊查詢用戶列

resultMap

使用要求:

使用resultMap進行結果映射時,不需要查詢的列名和映射的屬性名必須一致。但是需要聲明一個resultMap,來對列名和屬性名進行映射。

 

​​​​​​​需求:

對以下sql查詢的結果集進行對象映射

Select id id_,username username_,sex sex_ from user where id = 1;

 

​​​​​​​1.映射文件

 

​​​​​​​2.Mapper接口

 

​​​​​​​3.測試代碼

 

​​​​​​​動態sql

在mybatis中,它提供了一些動態sql標籤,可以讓程序員更快的進行mybatis的開發,這些動態sql可以通過sql的可重用性。。

常用的動態sql標籤:if標籤、where標籤、sql片段、foreach標籤

 

  1. If標籤/where標籤

需求:

綜合查詢時,查詢條件由用戶來輸入,用戶名稱可以爲空,需要滿足這種情況下的sql編寫。

 

​​​​​​​映射文件

 

​​​​​​​測試代碼

 

​​​​​​​Sql片段

Sql片段可以讓代碼有更高的可重用性

Sql片段需要先定義後使用

 

 

​​​​​​​Foreach標籤

可以循環傳入參數值

 

​​​​​​​需求:

綜合查詢時,會根據用戶ID集合進行查詢

SELECT * FROM USER WHERE id IN (1,2,10)

 

​​​​​​​1.修改包裝pojo

​​​​​​​2.映射文件​​​​​​

3.測試代碼

 

mybatis與hibernate的區別及各自應用場景

 

Mybatis技術特點:

優點:通過直接編寫SQL語句,可以直接對SQL進行性能的優化;

學習門檻低,學習成本低。只要有SQL基礎,就可以學習mybatis,而且很容易上手;

由於直接編寫SQL語句,所以靈活多變,代碼維護性更好。

缺點:不能支持數據庫無關性,即數據庫發生變更,要寫多套代碼進行支持,移植性不好。

Hibernate技術特點:

優點:標準的orm框架,程序員不需要編寫SQL語句。

具有良好的數據庫無關性,即數據庫發生變化的話,代碼無需再次編寫。

學習要求:學習門檻較高,需要對數據關係模型有良好的基礎,而且在設置OR映射的時候,需要考慮好性能和對象模型的權衡。

缺點:程序員不能自主的去進行SQL性能優化。

 

Mybatis應用場景:

需求多變的互聯網項目,例如電商項目。

Hibernate應用場景:

需求明確、業務固定的項目,例如OA項目、ERP項目等。

以上總結尚未完善好,有基礎的同學應該都大概懂一些!

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章