此文已獨家授權給【新華前后端開發】使用。其他平台使用聯系作者后再使用
簡介
在數據庫方面我們最常用的應該JDBC、Hibernate和Mybatis。通過JDBC方式連接數據庫,我們會發現工作量是相當的復雜。我們得處理一些瑣碎的關閉。然后入參出參我們都得自己管理。基於次產生了ORM(Object Relational Mapping)模型。
ORM模型
- 簡單的說ORM模型就是數據庫表和Java對象的映射模型。主要解決了數據庫和Java對象的相互映射。我們可以操作實體對象進而操作數據庫表。這樣的好處是我們不需要太了解數據庫。減輕了我們的學習代價。
Hibernate
- 基於ORM模型很快我們的第二主角登場了。但是由於Hibernate配置比較復雜,且操作性能上不是很好。雖然大大的弱化了我們的sql但是因為性能低下很快就被淘汰了。
Ibatis
-
Mybatis的前身嚴格意義上說應該是Ibatis,后面我們都稱之為Mybatis.為了解決Hibernate的不足,Mybatis產生了相對於Hibernate的全表映射Mybatis可以說是半自動映射的框架。因為他是實體和sql結合的一個框架。
-
Mybatis有SQL , 實體 , 映射規則三個主要對象主成。和Hibernate相比雖然多出了sql的編寫,但是正是因為sql的編寫使得Mybatis變得很方便。Hibernate因為不用sql,所以他無法調用存儲過程這些數據庫方法。但是Mybatis不一樣,Mybatis可以調用sql中的存儲過程。
環境搭建
jar
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.0</version>
</dependency>
配置
- 在上面的圖示中我們可以發現,Mybatis中提供的注解或者是接口的方式來操作數據庫的。所以這里我們准備一個接口。與接口對應的是xml文件。兩者組成了Mybatis中的一個組件。
package com.github.zxhtom.mapper;
import com.github.zxhtom.model.Student;
import java.util.List;
public interface StudentMapper {
/**
* 獲取學生列表
* @return
*/
public List<Student> getStudents();
/**
* 通過id獲取學生信息
* @param id
* @return
*/
public Student getStudentByStuId(String id);
}
- 與接口對應的是xml,里面記錄了真是的sql。這里注意下xml的位置需要和實體在同意文件夾下且同名
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.github.zxhtom.mapper.StudentMapper">
<select id="getStudents" resultType="com.github.zxhtom.model.Student">
select * from student
</select>
<select id="getStudentByStuId" resultType="com.github.zxhtom.model.Student">
select * from student where id=#{id}
</select>
</mapper>
xml方式配置
- 有了上面的接口和xml,下面我們開始配置我們的Mybatis環境。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--引入外部配置文件-->
<properties resource="config.properties"></properties>
<!--定義別名-->
<typeAliases>
<package name=""/>
</typeAliases>
<!--定義數據庫信息,默認使用development數據庫構建環境-->
<environments default="development">
<environment id="development">
<!--jdbc事物管理-->
<transactionManager type="JDBC"></transactionManager>
<!--配置數據庫連接信息-->
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/github/zxhtom/mapper/StudentMapper.xml"></mapper>
</mappers>
</configuration>
- 然后我們就可以加載這個xml環境配置,構建我們的sqlsession.
//獲取mybatis-config.xml位置
InputStream inputStream = Resources.getResourceAsStream(Constant.MYBATIS);
//加載mybatis-config,並創建sqlsessionfactory對象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//創建sqlsession對象
SqlSession sqlSession = sqlSessionFactory.openSession();
Map<String, Object> paramMap = new HashMap<>();
paramMap.put("id", 1);
//執行select語句,將resultSet映射成對象並返回
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.getStudents();
studentPrint(students);
代碼方式配置
- 官方提供了另外一種Java對象的方式來配置環境。這種配置我們控制的力度更加細膩,但是導致的問題是我們的一些配置將會硬編碼在代碼里。我們這里通過Properties文件將硬編碼的東西挪出去。
Map<Object, Object> properties = PropertiesUtil.getProperties("config.properties");
PooledDataSource dataSource = new PooledDataSource();
dataSource.setDriver(properties.get("database.driver").toString());
dataSource.setUrl(properties.get("database.url").toString());
dataSource.setUsername(properties.get("database.username").toString());
dataSource.setPassword(properties.get("database.password").toString());
//構建數據庫事物方式
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//創建數據庫運行環境
Environment environment = new Environment("development",transactionFactory,dataSource);
//構建Configure對象
Configuration configuration = new Configuration(environment);
//注冊別名
configuration.getTypeAliasRegistry().registerAlias("stu", Student.class);
//加入一個映射器
configuration.addMapper(StudentMapper.class);
//使用sqlsessionfactoryBuilder構建sqlsessionfactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
SqlSession sqlSession = sqlSessionFactory.openSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.getStudents();
studentPrint(students);
兩種方式對比
-
上面我強調了我們的StudentMapper.xml和StudentMapper.java要同名而且在同一位置上。這是為什么呢。因為在Mybatis源碼中默認會讀取Java對象同目錄下的同名的xml文件作為sql配置文件。
-
但是后期我們項目的展開Java和xml會越來越多,放在一起的話很亂。作為一個框架不會這么局限的。在xml配置環境方式中我們是通過Mappers-->Mapper標簽來注入我們的Mapper.xml的。這里的xml路徑並沒有要求在同一個目錄。我們這里可以隨意的改。上面的那些限制是在Java代碼搭建環境的方式中。因為在Java代碼方式中我們只是通過java對象注冊mapper接口的。在這種方式下默認就會加載同目錄下的同名xml
Mybatis結構
-
學習的過程就是認知的過程。接下來我們來認識下Mybnatis的核心組件吧。
-
SqlSessionFactoryBuilder : 根據xml(mybatis-config.xml)或者Java代碼(代碼方式)來生成SqlSessionFactory
-
SqlSessionFactory : 構建SqlSession
-
SqlSession : 既可以發送sql執行並返回結果,也可以獲取Mapper接口
-
SQL Mapper : Mybatis獨有的組件。有Java接口和xml文件構成的一個整體。負責將xml中的sql進行解析然后傳遞給數據庫並獲取結果
源碼解讀xml環境加載
- 因為范疇基礎課程,這里對源碼的跟蹤點到為止(再深我也不會)。
- 在解析mybatis-config.xml標簽這一塊是重點。這一塊會專門介紹各個標簽解析及作用。文章留言或點贊讓我們看到你們對這一塊的喜愛。留言點贊多的會盡快出這一篇。
映射器解讀
- 上面已經說了映射器是有Java+xml組合而成的Mybatis組件。我們上面的案例也展示了兩者的編寫。Java實際就是一個接口定義好方法。在xml中對應的標簽帶上我們的sql就行了。
- 圈出來的這條sql中我們會發現和我們平時的sql不一樣。#{id}是Mybatis為我們提供的入參。在提交給數據庫的時候會將真正的sql填充過來。這里還有一個注意點我們寫的是select * 。因為數據庫字段和我們實體屬性是一樣的。所以Mybatis就會自動把相同字段內容映射給實體了。這就實現了自動映射了。
- 之前說了和Hibernate相比,Mybatis屬於半自動。如果我們的實體和數據庫字段不一樣了(注意駝峰和平峰在數據庫通過設置可以認為是一樣的。Mybatis也提供功能可以映射的。這里我們認為是一樣的),我們可以通過
resultMap
來實現數據庫字段和實體字段的映射。這就是我們所謂的半自動映射
Ibatis
- 雖然我們用Mybatis。但是Ibatis之前的方法還是保留下來的。這里提一下。但是不推薦使用的方式執行sql