1. 程式人生 > >Spring Boot 集成 MyBatis(四)

Spring Boot 集成 MyBatis(四)

src 狀態 並且 big 提取 date mapped cut 庫存

Spring Boot 集成 MyBatis

    A、ORM框架是什麽?
            對象關系映射(Object Relational Mapping,簡稱 ORM)模式是一種為了解決面向對象與關系數據庫存在的
            互不匹配的現象技術。簡單的說,ORM 是通過使用描述對象和數據庫之間映射的元數據,將程序中的對象自
            動持久化到關系數據庫中。
    
    B、為什麽需要ORM框架
            當開發一個應用程序的時候(不使用 O/R Mapping),可能會寫不少數據訪問層的代碼,用來從數據庫保存、
            刪除、讀取對象信息等。在 DAL 中寫了很多的方法來讀取對象數據、改變狀態對象等任務,而這些代碼寫
            起來總是重復的。針對這些問題 ORM 提供了解決方案,簡化了將程序中的對象持久化到關系數據庫中的操作。
            
            ORM 框架的本質是簡化編程中操作數據庫的編碼,一個是宣稱可以不用寫一句 SQL 的 Hibernate,
            一個是以動態 SQL 見長的 MyBatis,兩者各有特點。在企業級系統開發中可以根據需求靈活使用,
            有趣的現象:傳統企業大都喜歡使用 Hibernate,而互聯網行業通常使用MyBatis。
    C、MyBatis 介紹
            MyBatis 支持普通 SQL 查詢,存儲過程和高級映射的優秀持久層框架。MyBatis 消除了幾乎所有的 JDBC 代
            碼和參數的手工設置以及對結果集的檢索封裝。MaBatis 可以使用簡單的 XML 或註解用於配置和原始映射。
            將接口和 Java 的 POJO(Plain Old Java Objects,普通的 Java 對象)映射成數據庫中的記錄。
            
            優點:
                SQL 被統一提取出來,便於統一管理和優化
                SQL 和代碼解耦,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試
                提供映射標簽,支持對象與數據庫的 ORM 字段關系映射
                提供對象關系映射標簽,支持對象關系組件維護
                靈活書寫動態 SQL,支持各種條件來動態生成不同的 SQL
            缺點:
                編寫 SQL 語句時工作量很大,尤其是字段多、關聯表多時,更是如此
                SQL 語句依賴於數據庫,導致數據庫移植性差

    E、MyBatis 重要的概念
            Mapper 配置: Mapper 配置可以使用基於 XML 的 Mapper 配置?文件來實現,也可以使用基於 Java 註解的
                          MyBatis 註解來實現,甚至可以直接使用 MyBatis 提供的 API 來實現。
            Mapper 接口: Mapper 接口是指自行定義的一個數據操做接口,類似於通常所說的 DAO 接?口。早期的Mapper
                          接口需要自定義去實現,現在 MyBatis 會自動為 Mapper 接口創建動態代理對象。Mapper 接
                          口的方法通常與 Mapper 配置?文件中的 select、insert、update、delete 等 XML 結點存在
                          一一對應關系。
            Executor: MyBatis 中所有的 Mapper 語句的執行都是通過 Executor 進行的,Executor 是 MyBatis 的一個
                       核?心接口。
            SqlSession: SqlSession 是 MyBatis 的關鍵對象,是執行持久化操作的獨享,類似於 JDBC 中的Connection,
                         SqlSession 對象完全包含以數據庫為背景的所有執行 SQL 操作的方法,它的底層封裝了JDBC連
                         接,可以用 SqlSession 實例來直接執行被映射的 SQL 語句。
            SqlSessionFactory: SqlSessionFactory 是 MyBatis 的關鍵對象,它是單個數據庫映射關系經過編譯後的內
                                存鏡像。SqlSessionFactory 對象的實例可以通過 SqlSessionFactoryBuilder 對象類獲
                                得,而SqlSessionFactoryBuilder 則可以從 XML 配置文件或一個預先定制的 
                                Configuration 的實例構建出。

    F、MyBatis 的工作流程如下:
            a、首先加載 Mapper 配置的 SQL 映射文件,或者是註解的相關 SQL 內容。
            b、創建會話工廠,MyBatis 通過讀取配置文件的信息來構造出會話工廠(SqlSessionFactory)。
            c、創建會話。根據會話工廠,MyBatis 就可以通過它來創建會話對象(SqlSession)。會話對象是一個接
               口,該接口中包含了對數據庫操作的增刪改查?方法。
            d、創建執行器。因為會話對象本身不能直接操作數據庫,所以它使用了一個叫做數據庫執行器(Executor)
               的接口來幫它執行操作。
            e、封裝 SQL 對象。在這一步,執行器將待處理的 SQL 信息封裝到一個對象中(MappedStatement),該對
               象包括 SQL 語句、輸?入參數映射信息(Java 簡單類型、HashMap 或 POJO)和輸出結果映射信息(Java 簡單類型、HashMap 或 POJO)。
            f、操作數據庫。擁有了執行器和 SQL 信息封裝對象就使用它們訪問數據庫了,最後再返回操作結果,結束流程。
               在具體的使用過程中,按照上述的流程來執行。

技術分享圖片

1、mybatis-spring-boot-starter 主要提供了兩種解決方式,①XML配置,②使用註解。

A、XML版本

XML 版本保持映射文件的老傳統,優化主要體現在不需要實現 Dao 的實現層,系統會自動根據方法名在映射文件中找到對應的 SQL。

POM.XML文件
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>RELEASE</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-lang3</artifactId>
            <version>3.4</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
            <optional>true</optional>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
                <configuration>
                    <fork>true</fork>
                </configuration>
            </plugin>
        </plugins>
    </build>

    我還會引入另外一個組件,Apache 的 commons-lang 3 ,此包有非常多的工具類可以使用,
    比如常用的判斷字符串是否為空,快速復寫實體類的 toString() 方法等。

實體類文件:UserEntity
    public class UserEntity implements Serializable {

        private static final long serialVersionUID = 1L;
        private Long id;
        private String userName;
        private String passWord;
        private UserSexEnum userSex;
        private String nickName;
        //getter/setter省略
    }
枚舉類:
    public enum UserSexEnum {
        MAN, WOMAN
    }

application.properties文件
    mybatis.config-location=classpath:mybatis/mybatis-config.xml
    mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
    mybatis.type-aliases-package=com.kid.entity
    
    spring.datasource.driverClassName = com.mysql.jdbc.Driver
    spring.datasource.url = jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
    spring.datasource.username = root
    spring.datasource.password = root

    # mybatis.config-locations :配置 mybatis-config.xml 路徑,mybatis-config.xml 中配置MyBatis 基礎屬性。
    # mybatis.mapper-locations :配置 Mapper 對應的 XML 文件路徑
    # mybatis.type-aliases-package :配置項目中實體類包路徑
    # spring.datasource.* :數據源配置
    
    # Spring Boot 啟動時數據源會自動註入到 SqlSessionFactory 中,使用 SqlSessionFactory 構建
    # SqlSessionFactory,再自動註入到 Mapper 中,最後我們直接使用 Mapper 即可

啟動類:在啟動類中添加對 Mapper 包掃描 @MapperScan ,Spring Boot 啟動的時候會自動加載包路徑下的Mapper。
    @SpringBootApplication
    @MapperScan("com.kid.mapper")
    public class SpringbootMybatisApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(SpringbootMybatisApplication.class, args);
        }
    }
    
開發SQL:
    MyBatis公共屬性
        <!--配置別名-->
        <typeAliases>
            <typeAlias alias="Integer" type="java.lang.Integer" />
            <typeAlias alias="Long" type="java.lang.Long" />
            <typeAlias alias="HashMap" type="java.util.HashMap" />
            <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
            <typeAlias alias="ArrayList" type="java.util.ArrayList" />
            <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        </typeAliases>
        mybatis-config.xml ,主要配置常用的 typeAliases,設置類型別名為 Java 類型設置一個短的名字。只和 XML 配置有關,存在的意義僅在於用來減少類完全限定名的冗余。

UserMapper接口
    public interface UserMapper {       
        List<UserEntity> getAll();      
        UserEntity getOne(Long id);     
        void insert(UserEntity user);       
        void update(UserEntity user);       
        int delete(Long id);        
        List<UserEntity> getList(UserParam userParam);      
        Long getCount(UserParam userParam);
    }
    註意:這裏的方法名需要和 XML 配置中的 id 屬性一致,不然會找不到方法去對應執行的 SQL。
    
添加UserMapper映射文件
    <!--指明對應文件的 Mapper 類地址-->
    <mapper namespace="com.kid.mapper.UserMapper" >
    
        <!--
            配置表結構和類的對應關系:
                這裏故意將類的兩個字段和數據庫字段設置為不一致,並且有一個使用枚舉。
                使?用枚舉有一個非常?大的優點,插?入此屬性的數據會自動進?行校驗,
                如果不是枚舉的內容會報錯。
        -->
        <resultMap id="BaseResultMap" type="com.kid.entity.UserEntity" >
            <id column="id" property="id" jdbcType="BIGINT" />
            <result column="userName" property="userName" jdbcType="VARCHAR" />
            <result column="passWord" property="passWord" jdbcType="VARCHAR" />
            <result column="user_sex" property="userSex" javaType="com.kid.enums.UserSexEnum"/>
            <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
        </resultMap>
        
        <sql id="Base_Column_List" >
            id, userName, passWord, user_sex, nick_name
        </sql>
    
        <sql id="Base_Where_List">
            <if test="userName != null  and userName != ‘‘">
                and userName = #{userName}
            </if>
            <if test="userSex != null and userSex != ‘‘">
                and user_sex = #{userSex}
            </if>
        </sql>
    
        <select id="getAll" resultMap="BaseResultMap"  >
           SELECT 
           <include refid="Base_Column_List" />
           FROM users
        </select>
    
        <select id="getList" resultMap="BaseResultMap" parameterType="com.kid.param.UserParam">
            select
            <include refid="Base_Column_List" />
            from users
            where 1=1
            <include refid="Base_Where_List" />
            order by id desc
            limit #{beginLine} , #{pageSize}
        </select>
    
        <select id="getCount" resultType="Integer" parameterType="com.kid.param.UserParam">
            select
            count(1)
            from users
            where 1=1
            <include refid="Base_Where_List" />
        </select>
    
        <select id="getOne" parameterType="Long" resultMap="BaseResultMap" >
            SELECT 
           <include refid="Base_Column_List" />
           FROM users
           WHERE id = #{id}
        </select>
    
        <insert id="insert" parameterType="com.kid.entity.UserEntity" >
           INSERT INTO 
                users
                (userName,passWord,user_sex) 
            VALUES
                (#{userName}, #{passWord}, #{userSex})
        </insert>
        
        <update id="update" parameterType="com.kid.entity.UserEntity" >
           UPDATE 
                users 
           SET 
            <if test="userName != null">userName = #{userName},</if>
            <if test="passWord != null">passWord = #{passWord},</if>
            nick_name = #{nickName}
           WHERE 
                id = #{id}
        </update>
        
        <delete id="delete" parameterType="Long" >
           DELETE FROM
                 users 
           WHERE 
                 id =#{id}
        </delete>
    </mapper>

Spring Boot 集成 MyBatis(四)