MyBatis開山篇
1、MyBatis是什麼?
MyBatis官方定義是這樣描述的,MyBatis 是一款優秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis免除了幾乎所有的 JDBC 代碼以及設置參數和獲取結果集的工作。MyBatis可以通過簡單的 XML或註解來配置和映射原始類型、接口和 Java POJO。
上面文字描述太官方了,整體讀下來可能僅僅瞭解到MyBatis是用於解決持久層方案的一款持久層框架,那麼,在我們沒有使用過MyBatis之前,我們使用各種各樣的持久層技術來與數據庫交互,這些技術和MyBatis有什麼不同呢?
2、傳統的持久層技術
-
JDBC技術
-
SpringJdbcTemplate
Spring中對jdbc進行簡單的封裝。
- Apache的DButils
它和Spring的JdbcTemplate很像,也是對jdbc進行簡單的封裝
上面列舉的都不是框架,JDBC是一種規範,而JdbcTemplate和Dbutils都只是工具類。
既然有那麼多技術用於持久層,那麼我們爲什麼還要學MyBatis呢,我們先使用JDBC技術實現對一個數據庫表的操作,看看有什麼特點
JDBC編碼技術
執行流程
- 加載數據庫驅動
- 獲取數據庫連接
- 定義sql語句
- 預處理
- 遍歷查詢結果集
- 關閉連接
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try { //加載數據庫驅動
Class.forName("com.mysql.jdbc.Driver");
//通過驅動管理類獲取數據庫鏈接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root", "root");
//定義 sql 語句 ?表示佔位符
String sql = "select * from user where username = ?";
//獲取預處理 statement
preparedStatement = connection.prepareStatement(sql);
//設置參數,第一個參數爲 sql 語句中參數的序號(從 1 開始),第二個參數爲設置的 參數值
preparedStatement.setString(1, "Simon");
//向數據庫發出 sql 執行查詢,查詢出結果集
resultSet = preparedStatement.executeQuery();
//遍歷查詢結果集
while(resultSet.next()){
System.out.println(resultSet.getString("id")+"
"+resultSet.getString("username"));
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//釋放資源
if(resultSet!=null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement!=null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection!=null){
try {
connection.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
大家應該很熟悉這段代碼吧,使用原生的JDBC會出現什麼樣的問題呢
- 數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能。
- Sql 語句在代碼中硬編碼,造成代碼不易維護,實際應用 sql 變化的可能較大,sql 變動需要改變 java 代碼。
- 使用 preparedStatement 向佔有位符號傳參數存在硬編碼,因爲 sql 語句的 where 條件不一定,可能 多也可能少,修改 sql 還要修改代碼,系統不易維護
- 對結果集解析存在硬編碼(查詢列名),sql 變化導致解析代碼變化,系統不易維護。
查詢一條語句那麼繁瑣,我們當然希望可以將我們的主要精力放在sql上,那麼MyBatis是否有能力幫我們解決呢?它的執行有什麼特點呢?
3、MyBatis入門
事實上,MyBatis封裝了jdbc操作的很多細節,它可以使開發者更多的關注sql語句本身,而無需關注註冊驅動、創建鏈接等繁瑣的過程,它使用ORM的思想實現對結果集的封裝。
ORM全稱是Object Relational Mapping,即對象關係映射,即把數據庫表和實體類即實體類的屬性對應起來,使得我們可以操作實體類就可以實現操作數據庫表。
3.1MyBatis框架結構
- SqlMapConfig.xml
MyBatis的全局配置文件,配置了MyBatis的運行環境等信息。
- mapper.xml
mapper.xml文件,即sql映射文件,文件中配置了操作數據庫的sql語句,需要在SqlMapperConfig.xml文件中加載
- SqlSessionFactory
通過MyBatis環境等配置信息構造SqlSessionFactory會話工廠
- SqlSession
由會話工廠創建sqlSession,操作數據庫需要通過sqlSession進行
- Executor
MyBatis底層自定義了Executor執行器接口操作的數據庫,Executor接口有兩個實現,一個是基本執行器,一個緩存執行器。
- Mappered Statement
是一個底層封裝對象,包裝了MyBatis配置信息及sql映射信息等。
3.2MyBatis入門案例
- 讀取配置文件
- 創建SqlSessionFactory工廠
- 創建SqlSession
- 創建Dao接口的代理對象
- 執行dao中的方法
- 釋放資源
基於xml配置
- SqlMapConfig配置文件
<?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>
<!--配置mybatis的環境-->
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf8&serverTimezone=UTC"></property>
<property name="username" value="root"></property>
<property name="password" value="root"></property>
</dataSource>
</environment>
</environments>
<!--告知mybatis的映射配置位置-->
<mappers>
<mapper resource="com/simon/dao/IUserDao.xml"></mapper>
</mappers>
</configuration>
- mapper.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.simon.dao.IUserDao">
<select id="findAll" resultType="com.simon.domain.User" >
select * from user
</select>
</mapper>
- User實體類
package com.simon.domain;
import java.util.Date;
/**
* @Author: Simon Lang
* @Date: 2020/2/26 12:09
* @Version 1.0
*/
public class User {
private Integer id;
private String username;
private Date birthday;
private char sex;
private String address;
- dao接口
public interface IUserDao {
public List<User> findAll();
}
- 測試
//導入配置文件
InputStream in= Resources.getResourceAsStream("SqlMapConfig.xml");
//創建sqlSessionFactory的構建者對象
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
//使用構建者創建工廠對象sqlSessionFactory
SqlSessionFactory factory=builder.build(in);
//4.使用 SqlSessionFactory 生產 SqlSession 對象
SqlSession session = factory.openSession();
//5.使用 SqlSession 創建 dao 接口的代理對象
IUserDao userDao = session.getMapper(IUserDao.class);
//6.使用代理對象執行查詢所有方法
List<User> users=userDao.findAll();
for (User user:users){
System.out.println(user);
}
session.close();
in.close();
基於註解
- 修改SqlMapConfig.xml
<mappers>
<mapper class="com.simon.dao.IUserDao.xml"></mapper>
</mappers>
- 移除IUserDao.xml配置文件,並在dao接口的方法上加入@(select * from user)
參考:
https://mybatis.org/mybatis-3/zh/getting-started.html
https://www.cnblogs.com/benjieqiang/p/11183580.html
關注公衆號:10分鐘編程,讓我們每天博學一點點
公衆號回覆success,領取獨家整理的學習資源,JAVA、大數據全套視頻資料