Mybatis

定義:持久層?

幹啥的?作用於哪一方面?

基本配置,基本操作?

  • 重點,難點---結果集對映
  • 分頁,
  • 註解開發(重點
  • 一對多,多對多的處理(難點)
  • 動態SQL(重點
  • 快取(十分重要,極其重要)

mybatis開始

-----環境準備

- JDK 1.8
- mysql 8.0.21
- maven 3.6.1
- mybatis 3.5.3
- IDEA

一.簡介

1.什麼是MyBatis

  • MyBatis 是一款優秀的持久層框架
  • MyBatis 避免了幾乎所有的 JDBC 程式碼手動設定引數以及獲取結果集的過程
  • MyBatis 可以使用簡單的 XML 或註解來配置和對映原生資訊,

    將介面和 Java 的 實體類 【Plain Old Java Objects,普通的 Java物件】對映成資料庫中的記錄。
  • MyBatis 本是apache的一個開源專案ibatis, 2010年這個專案由apache 遷移到了google code,並且改名為MyBatis 。
  • 2013年11月遷移到Github .

2.持久化

  • 1.持久化是將程式資料在持久狀態和瞬時狀態間轉換的機制。

    • 1).即把資料(如記憶體中的物件)儲存到可永久儲存的儲存裝置中(如磁碟)。持久化的主要應用

      將記憶體中的物件儲存在資料庫中,或者儲存在磁碟檔案中、XML資料檔案中等等。
    • 2).JDBC就是一種持久化機制。檔案IO也是一種持久化機制。
    • 3).在生活中 : 將鮮肉冷藏,吃的時候再解凍的方法也是。將水果做成罐頭的方法也是。
  • 2.為什麼需要持久化服務呢?那是由於記憶體本身的缺陷引起的(記憶體斷電即失

    • 1).記憶體斷電後資料會丟失,但有一些物件是無論如何都不能丟失的,比如銀行賬號等,遺憾的

      是,人們還無法保證記憶體永不掉電。
    • 2).記憶體過於昂貴,與硬碟、光碟等外存相比,記憶體的價格要高2~3個數量級,而且維持成本也

      高,至少需要一直供電吧。所以即使物件不需要永久儲存,也會因為記憶體的容量限制不能一直

      呆在記憶體中,需要持久化來快取到外存

3.持久層

  • 什麼是持久層?

    • 1.完成持久化工作的程式碼塊 . ----> dao層 【DAO (Data Access Object) 資料訪問物件】
    • 2.大多數情況下特別是企業級應用,資料持久化往往也就意味著將記憶體中的資料儲存到磁碟上加

      以固化,而持久化的實現過程則大多通過各種關係資料庫來完成。
    • 3.不過這裡有一個字需要特別強調,也就是所謂的“層”。對於應用系統而言,資料持久功能大多

      是必不可少的組成部分。也就是說,我們的系統中,已經天然的具備了“持久層”概念?也許

      是,但也許實際情況並非如此。之所以要獨立出一個“持久層”的概念,而不是“持久模組”,“持久

      單元”,也就意味著,我們的系統架構中,應該有一個相對獨立的邏輯層面,專著於資料持久

      化邏輯的實現.
    • 4.與系統其他部分相對而言,這個層面應該具有一個較為清晰和嚴格的邏輯邊界。 【說白了就

      是用來操作資料庫存在的!】

4.為什麼需要Mybatis?

  • 幫助程式設計師將資料存到資料庫中
  • 方便
  • 傳統JDBC程式碼臺複雜。簡化。框架。自動化
  • 不用Mybatis也可以,更容易上手。技術沒有高低之分
  • 優點-------主要就是用的人多

二.第一個Mybatis程式

思路:搭建環境-->匯入mybatis-->編寫程式碼-->測試

1.搭建環境

1).資料庫的

        mysql> create database `mybatis`;
Query OK, 1 row affected (0.00 sec) mysql> use `mybatis`;
Database changed
mysql> create table `user`(
-> `id` int not null,
-> `name` varchar(20) DEFAULT null,
-> `password` varchar(20) DEFAULT null,
-> primary key(`id`)
-> )engine = INNODB DEFAULT charset=utf8;
Query OK, 0 rows affected (0.02 sec)
mysql> insert into `user`(`id`,`name`,`password`) values(0,'zjz0','123456'),(1,'zjz1','123456'),(2,'zjz2','123456');
Query OK, 3 rows affected (0.00 sec)

2).maven專案

  • 普通maven專案
  • 刪除src
  • 匯入mysql mybatis junit 包
        <dependencies>
<!-- mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 單元測試-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.3</version>
</dependency> </dependencies>
<!-- ex:此處增加的build詳細在maven====太長不加了-->

3).建立一個子類modules

4).編寫mybatis的核心配置檔案

  • 配置 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核心配置檔案--> <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? useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8"/>
    <property name="username" value="root"/>
    <property name="password" value="123456"/>
    </dataSource>
    </environment>
    </environments>
    <!--每一個mapper.xml都需要在mybatis核心配置檔案中註冊-->
    <mappers>
    <mapper resource="com/zjz/dao/UserMapper.xml"/>
    </mappers>
    </configuration>
    • 編寫mybatis工具類

      • sqlSessionFactory -- 構建sqlSession
         // sqlSessionFactory -產生-> sqlSession
    public class MybatisUtils {
    private static SqlSessionFactory sqlSessionFactory; static {
    try {
    // 第一步--獲取sqlSessionFactory物件 String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    } catch (IOException e) {
    e.printStackTrace();
    }
    }//獲取SqlSession連線 public static SqlSession getSqlSession() {
    SqlSession sqlSession = sqlSessionFactory.openSession(); // sqlSession 不是執行緒安全的
    return sqlSession; }
    }

5).編寫程式碼

  • UserMapper介面

        public interface UserMapper {
    List<User> getUserList();
    }
  • UserMapper.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,繫結一個Dao/Mapper介面-->
<mapper namespace="com.zjz.dao.UserMapper">
<!--id要與mapper的方法對應-->
<!--resultType返回型別-->
<select id="getUserList" resultType="com.zjz.pojo.User">
select * from user
</select>
</mapper>

6).測試

  • Junit測試

            @Test
    public void test(){ // 第一步,獲得SqlSession物件
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    // 執行sql
    UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.getUserList(); System.out.println(userList.toString()); // 關閉SqlSession
    sqlSession.close(); }

三個核心介面



注意

  • org.apache.ibatis.binding.BindingException:

    Type interface com.zjz.dao.UserMapper is not known to the MapperRegistry.
  • MapperRegistry
  • 問題
    • 1.配置檔案沒有註冊(mybatis-config沒配置)
    • UserMapper.xml--2.繫結介面錯誤 3.方法名不對 4.返回型別不對
    • pom.xml 5.Maven匯出資源錯誤 MapperRegistry

總:

三,基本CRUD

操作DML一定要提交事務 sqlSession.commit();

1.namespace

  • namespace中的包名要和Mapper介面的包名一致

2.Mapper.xml

  • 語句

    • 1.id:對應的namesapce中的方法名
    • 2.resultType
      • Sql語句執行的返回值(對應物件則為物件型別)-單表返回對應的物件,多表返回
      • --如果select,必須有,其它可以沒有
    • 3.parameterType 引數型別
    • 4.語句中傳參使用#{XXX} XXX 要對應 parameterType裡面的東西

問題 sqlSession 是如何控制全域性的,中途關閉它,有什麼影響?(或者只讓它有初始值)

  • 查詢時,可以依據引數查詢物件---入參parameterType 出參 resultType
  • 插入時,入參parameterType--一般就是物件了 ,出參不寫

程式碼

  • 1.介面Mapper

        public interface UserMapper {
    // 查詢全部使用者
    List<Object> getUserList(); // list中可以指定POJO,也可以指定Object(多表) // 根據id查詢
    User getUserById(int id); // 插入insert
    int addUser(User user); // 修改使用者
    int updateUser(User user); // 刪除使用者
    int deleteUser(int id);
    }
  • 2.Mapper.xml

        <!--namespace,繫結一個Dao/Mapper介面-->
    <mapper namespace="com.zjz.dao.UserMapper">
    <!--id要與mapper的方法對應-->
    <!--resultType返回型別-->
    <!--resultType返回型別
    select中,如果指定,那麼返回指定物件,不指定報錯 多表應該怎麼寫??
    --> <select id="getUserList" resultType="com.zjz.pojo.User" >
    select * from user
    </select> <select id="getUserById" parameterType="int" resultType="com.zjz.pojo.User">
    select * from mybatis.user where id = #{id}
    </select> <insert id="addUser" parameterType="com.zjz.pojo.User">
    insert into mybatis.user(id,name,password) values (#{id},#{name},#{password});
    </insert> <update id="updateUser" parameterType="com.zjz.pojo.User">
    update mybatis.user
    set name = #{name},password = #{password}
    where id = #{id};
    </update> <delete id="deleteUser" parameterType="int">
    delete from mybatis.user where id = #{id};
    </delete>
    </mapper>
  • 3.Test

            @Test
    public void TestGetUserById(){
    SqlSession sqlSession = MybatisUtils.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    User userById = mapper.getUserById(1);
    System.out.println(userById); sqlSession.close();
    } @Test
    public void TestAddUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.addUser(new User(5, "zjz05", "123456")); // 提交事務
    sqlSession.commit(); sqlSession.close(); } @Test
    public void TestUpdateUser(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateUser(new User(4,"zjz04","123456")); sqlSession.commit();
    sqlSession.close(); }

模糊查詢 切記防止sql注入

  • 方式一:安全的

    • XXXMappper.xml
          <!--like '%zjz%'-->
    <select id="getUserLike" resultType="com.zjz.pojo.User" >
    select * from user where name like #{value}
    </select>
    • test語句
    • List<User> list = mapper.getUserLike("%zjz%");
  • 方式二:可sql注入

    • XXXMappper.xml
          <!--like '%zjz%'-->
    <select id="getUserLike" resultType="com.zjz.pojo.User" >
    select * from user where name like "%"#{value}"%"
    </select>
    • test語句
    • List<User> list = mapper.getUserLike("zjz");

一些錯誤

  • 1.標籤。。各對各的 select……
  • 2.resource繫結mapper,需要使用路徑
  • 3.程式配置檔案符合規範
  • 4.NullPointException 沒找到資源
  • 5.輸出的xml檔案有亂碼。。。
  • 6.maven資源匯出問題