全網最詳細的Mybatis介紹和基本使用
Mybatis簡單瞭解和基本使用
1、資料庫操作框架的歷程
JDBC
JDBC(Java Data Base Connection,java資料庫連線)是一種用於執行SQL語句的Java API,可以為多種關係資料庫提供統一訪問,它由一組用Java語言編寫的類和介面組成.JDBC提供了一種基準,據此可以構建更高階的工具和介面,使資料庫開發人員能夠編寫資料庫應用程式
- 優點:執行期:快捷、高效
- 缺點:編輯期:程式碼量大、繁瑣異常處理、不支援資料庫跨平臺
jdbc核心api
-
1.DriverManager 連線資料庫
-
2.Connection 連線資料庫的抽象
-
3.Statment 執行SQL
-
4.ResultSet 資料結果集
DBUtils
DBUtils是Java程式設計中的資料庫操作實用工具,小巧簡單實用。
DBUtils封裝了對JDBC的操作,簡化了JDBC操作,可以少寫程式碼。
DBUtils三個核心功能介紹
-
1、QueryRunner中提供對sql語句操作的API
-
2、ResultSetHandler介面,用於定義select操作後,怎樣封裝結果集
-
3、DBUtils類,它就是一個工具類,定義了關閉資源與事務處理的方法
Hibernate
名字 | 解釋 |
---|---|
ORM | 物件關係對映 |
object | java物件 |
relational | 關係型資料 |
mapping | 對映 |
Hibernate介紹
-
Hibernate 是由 Gavin King 於 2001 年建立的開放原始碼的物件關係框架。它強大且高效的構建具有關係物件永續性和查詢服務的 Java 應用程式。
-
Hibernate將Java 類對映到資料庫表中,從 Java 資料型別中對映到 SQL 資料型別中,並把開發人員從95% 的公共資料持續性程式設計工作中解放出來。
-
Hibernate 是傳統 Java 物件和資料庫伺服器之間的橋樑,用來處理基於 O/R 對映機制和模式的那些物件。
Hibernate 優勢
-
Hibernate 使用 XML 檔案來處理對映 Java 類別到資料庫表格中,並且不用編寫任何程式碼。
-
為在資料庫中直接儲存和檢索 Java 物件提供簡單的 APIs。
-
如果在資料庫中或任何其它表格中出現變化,那麼僅需要改變 XML 檔案屬性。
-
抽象不熟悉的 SQL 型別,併為我們提供工作中所熟悉的 Java 物件。
-
Hibernate 不需要應用程式伺服器來操作。
-
操控你資料庫中物件複雜的關聯。
-
最小化與訪問資料庫的智慧提取策略。
-
提供簡單的資料詢問。
Hibernate劣勢
-
hibernate的完全封裝導致無法使用資料的一些功能。
-
Hibernate的快取問題。
-
Hibernate對於程式碼的耦合度太高。
-
Hibernate尋找bug困難。
-
Hibernate批量資料操作需要大量的記憶體空間而且執行過程中需要的物件太多
JDBCTemplate
JdbcTemplate針對資料查詢提供了多個過載的模板方法,你可以根據需要選用不同的模板方法.如果你的查詢很簡單,僅僅是傳入相應SQL或者相關引數,然後取得一個單一的結果,那麼你可以選擇如下一組便利的模板方法。
優點
-
執行期:高效
-
內嵌Spring框架中
-
支援基於AOP的宣告式事務
缺點
-
必須於Spring框架結合在一起使用
-
不支援資料庫跨平臺
-
預設沒有快取
2、什麼是Mybatis?
MyBatis 是一款優秀的持久層框架/半自動的ORM,它支援自定義 SQL、儲存過程以及高階對映。MyBatis 免除了幾乎所有的 JDBC 程式碼以及設定引數和獲取結果集的工作。MyBatis 可以通過簡單的 XML 或註解來配置和對映原始型別、介面和 Java POJO(Plain Old Java Objects,普通老式 Java 物件)為資料庫中的記錄。
優點
-
1、與JDBC相比,減少了50%的程式碼量
-
2、 最簡單的持久化框架,簡單易學
-
3、SQL程式碼從程式程式碼中徹底分離出來,可以重用
-
4、提供XML標籤,支援編寫動態SQL
-
5、提供對映標籤,支援物件與資料庫的ORM欄位關係對映
-
支援快取、連線池、資料庫移植....
缺點
-
1、SQL語句編寫工作量大,熟練度要高
-
2、資料庫移植性比較差,如果需要切換資料庫的話,SQL語句會有很大的差異
3、快速搭建Mybatis專案
1、建立普通的maven專案
2、匯入相關的依賴pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.tulingxueyuan</groupId>
<artifactId>mybatis_helloworld</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
</dependencies>
</project>
3、建立對應的資料表
4、建立與表對應的實體類物件
- emp.java
public class Emp {
private Integer id;
private String username;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Override
public String toString() {
return "Emp{" +
"id=" + id +
", username='" + username + ''' +
'}';
}
}
5、建立對應的Mapper介面
- EmpMapper.java
public interface EmpMapper {
// 根據id查詢Emp實體
//@Select("select * from emp where id=#{id}")
Emp selectEmp(Integer id);
// 插入
Integer insertEmp(Emp emp);
// 更新
Integer updateEmp(Emp emp);
// 刪除
Integer deleteEmp(Integer id);
}
6、編寫配置檔案
- mybatis-config.xml
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--<mapper resource="EmpMapper.xml"/>-->
<mapper class="com.mybatis.mapper.EmpMapper"></mapper>
</mappers>
</configuration>
- EmpMapper.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.mybatis.mapper.EmpMapper">
<!--根據id查詢Emp實體-->
<select id="selectEmp" resultType="com.mybatis.pojo.Emp">
select * from Emp where id = #{id}
</select>
<insert id="insertEmp">
INSERT INTO
`mybatis`.`emp` ( `username`)
VALUES (#{username});
</insert>
<update id="updateEmp">
UPDATE EMP
SET username=#{username}
WHERE id=#{id}
</update>
<delete id="deleteEmp">
DELETE FROM emp
WHERE id=#{id}
</delete>
</mapper>
7、編寫測試類
- MyTest.java
/***
*
* MyBatis 搭建步驟:
* 1.新增pom依賴 (mybatis的核心jar包和資料庫版本對應版本的驅動jar包)
* 2.新建資料庫和表
* 3.新增mybatis全域性配置檔案 (可以從官網中複製)
* 4.修改mybatis全域性配置檔案中的 資料來源配置資訊
* 5.新增資料庫表對應的POJO物件(相當於我們以前的實體類)
* 6.新增對應的PojoMapper.xml (裡面就維護所有的sql)
* 修改namespace: 如果是StatementId沒有特殊的要求
* 如果是介面繫結的方式必須等於介面的完整限定名
* 修改對應的id(唯一)、resultType 對應返回的型別如果是POJO需要制定完整限定名
* 7.修改mybatis全域性配置檔案:修改Mapper
*/
public class MybatisTest {
SqlSessionFactory sqlSessionFactory;
@Before
public void before(){
// 從 XML 中構建 SqlSessionFactory
String resource = "mybatis.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
} catch (IOException e) {
e.printStackTrace();
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
/**
* 基於StatementId的方式去執行SQL
* <mapper resource="EmpMapper.xml"/>
* @throws IOException
*/
@Test
public void test01() {
try (SqlSession session = sqlSessionFactory.openSession()) {
Emp emp = (Emp) session.selectOne("cn.tulingxueyuan.pojo.EmpMapper.selectEmp", 1);
System.out.println(emp);
}
}
/**
* 基於介面繫結的方式
* 1.新建資料訪問層的介面: POJOMapper
* 2.新增mapper中對應的操作的方法
* 1.方法名要和mapper中對應的操作的節點的id要一致
* 2.返回型別要和mapper中對應的操作的節點的resultType要一致
* 3.mapper中對應的操作的節點的引數必須要在方法的引數中宣告
* 3.Mapper.xml 中的namespace必須要和介面的完整限定名要一致
* 4.修改mybatis全域性配置檔案中的mappers,採用介面繫結的方式:
* <mapper class="com.mybatis.EmpMapper"></mapper>
* 5.一定要將mapper.xml和介面放在同一級目錄中,只需要在resources新建和介面同樣結構的資料夾就行了,生成就會合並在一起
*
* @throws IOException
*/
@Test
public void test02(){
try (SqlSession session = sqlSessionFactory.openSession()) {
EmpMapper mapper = session.getMapper(EmpMapper.class);
Emp emp = mapper.selectEmp(1);
System.out.println(emp);
}
}
/**
* 基於註解的方式
* 1.在介面方法上面寫上對應的註解
*@Select("select * from emp where id=#{id}")
* 注意:
* 註解可以和xml共用, 但是不能同時存在方法對應的xml的id
*
*/
@Test
public void test03(){
try (SqlSession session = sqlSessionFactory.openSession()) {
EmpMapper mapper = session.getMapper(EmpMapper.class);
Emp emp = mapper.selectEmp(1);
System.out.println(emp);
}
}
}
4、增刪改查的基本操作
- EmpMapper.java
public interface EmpMapper {
public Emp findEmpByEmpno(Integer empno);
public int updateEmp(Emp emp);
public int deleteEmp(Integer empno);
public int insertEmp(Emp emp);
}
- EmpMapper.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">
<!--namespace:編寫介面的全類名,就是告訴要實現該配置檔案是哪個介面的具體實現-->
<mapper namespace="com.mybatis.mapper.EmpMapper">
<!--
select:表示這個操作是一個查詢操作
id表示的是要匹配的方法的名稱
resultType:表示返回值的型別,查詢操作必須要包含返回值的型別
#{屬性名}:表示要傳遞的引數的名稱
-->
<select id="findEmpByEmpno" resultType="com.mybatis.bean.Emp">
select * from emp where empno = #{empno}
</select>
<!--增刪改查操作不需要返回值,增刪改返回的是影響的行數,mybatis會自動做判斷-->
<insert id="insertEmp">
insert into emp(empno,ename) values(#{empno},#{ename})
</insert>
<update id="updateEmp">
update emp set ename=#{ename} where empno = #{empno}
</update>
<delete id="deleteEmp">
delete from emp where empno = #{empno}
</delete>
</mapper>
- MyTest.java
public class MyTest {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
// 根據全域性配置檔案創建出SqlSessionFactory
// SqlSessionFactory:負責建立SqlSession物件的工廠
// SqlSession:表示跟資料庫建議的一次會話
String resource = "mybatis-config.xml";
InputStream inputStream = null;
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void test01() {
// 獲取資料庫的會話
SqlSession sqlSession = sqlSessionFactory.openSession();
Emp empByEmpno = null;
try {
// 獲取要呼叫的介面類
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
// 呼叫方法開始執行
empByEmpno = mapper.findEmpByEmpno(7369);
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
System.out.println(empByEmpno);
}
@Test
public void test02(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
int zhangsan = mapper.insertEmp(new Emp(1111, "zhangsan"));
System.out.println(zhangsan);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test03(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
int zhangsan = mapper.updateEmp(new Emp(1111, "lisi"));
System.out.println(zhangsan);
sqlSession.commit();
sqlSession.close();
}
@Test
public void test04(){
SqlSession sqlSession = sqlSessionFactory.openSession();
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
int zhangsan = mapper.deleteEmp(1111);
System.out.println(zhangsan);
sqlSession.commit();
sqlSession.close();
}
}
- EmpMapperImpl.java
public interface EmpMapperImpl {
@Select("select * from emp where id= #{id}")
public Emp findEmpByEmpno(Integer empno);
@Update("update emp set ename=#{ename} where id= #{id}")
public int updateEmp(Emp emp);
@Delete("delete from emp where id= #{id}")
public int deleteEmp(Integer empno);
@Insert("insert into emp(id,user_name) values(#{id},#{username})")
public int insertEmp(Emp emp);
}