第一個MyBatis程序、MyBatis增刪改查與配置文檔、resultMap映射、log4j日誌、RowBounds分頁

一、MyBatis

1、Mybatis階段學習概述

Mybatis作用:和數據庫打交道,簡化數據庫的操作

javaSE—>前端—>數據庫—>javaWeb(已經可以獨立完成項目,但是太繁瑣,所以需要一些框架來簡化操作,提高開發效率)

1、SSM—企業級開發框架

學習框架之後開發方式會發生變化,越來越簡單

  1. MyBatis

    簡化數據庫操作的,幫助我們獲取數據庫連接、數據處理等

  2. Spring

    用來黏合框架,整合框架(Structs、MyBatis、SpringMVC等)的,可以簡單的理解爲一個粘合劑的作用。

    使用Spring就不需要再自己創建對象了,直接從Spring的IOC容器中取對象

  3. SpringMVC

    Web開發的三層結構,分別爲實體類(一個實體類對應數據庫中的一張表)、視圖、控制層(類似於Servlet/Service等)

2、Spring與SpringBoot聯繫

Spring出現很久了,隨着發展,Spring的配置越來越複雜,所以就有了SpringBoot,相較於Spring,SpringBoot中約定優於配置,簡化了配置流程,可以簡化開發者的使用。

3、前後端分離開發

  1. 什麼是前後端分離開發

    後端僅返回前端所需的數據,前端負責渲染HTML頁面,後端不再控制前端的效果,用戶看到什麼樣的效果,從後端請求的數據如何加載到前端中,都由前端自己決定,後端僅僅需要提供一套邏輯對外提供數據即可,並且前端與後端的耦合度相對較低,在這種模式中,我們通常將後端開發的每個視圖都成爲一個接口,或者API,前端通過訪問接口來對數據進行增刪改查。

    總結一句話,後臺負責提供數據,前端負責數據展示

  2. 前後端分離開發的優點

    1. 分工明確,提升效率

    2. 降低服務器負載,提升性能

      頁面數及進行按需加載,前端頁面也不再由服務器解析

    3. 增加代碼的可維護性

      降低代碼間的耦合度,有利於後期維護

前端、數據庫、業務邏輯

2、第一個MyBatis程序

1、MyBatis是什麼

前身:iBatis,所以在後期編寫代碼的時候,很多時候導的就是iBatis包

下載:在Github上進行下載,https://mybatis.org/mybatis-3/

MyBatis優點:可以解耦、在程序運行時也可以進行管理(在配置文件裏進行管理),自由切換數據庫等作用

MyBatis特性

  1. 基於Java持久層(JDBC)的框架

  2. 支持定製化的SQL

  3. 支持映射

  4. 幾乎避免了所有的JDBC代碼和手動設置參數及獲取結果集

  5. 可以使用簡單的XML或註解進行配置和映射原生類型、接口和Java的POJO作爲數據庫對象

2、第一個HelloWorld程序

  1. 數據庫準備

    創建mybatis數據庫,在數據庫中創建表user,鍵分別爲id、name、pwd,將id設置爲主鍵,設置編碼集爲INNODB

    /*
    創建數據庫和表
    */
    CREATE DATABASE `mybatis`;
    
    USE `mybatis`;
    
    CREATE TABLE `user`(
        `id` INT(20) NOT NULL,
        `name` VARCHAR(30) DEFAULT NULL,
        `pwd` VARCHAR(30) DEFAULT NULL,
         PRIMARY KEY(`id`)
    )ENGINE=INNODB DEFAULT CHARSET=utf8;
    
    /*
    給表中填充數據
    */
    INSERT INTO `user`(`id`,`name`,`pwd`)
    VALUES (1,'張三','123456'),(2,'李四','123456'),(3,'王五','123456');
  2. 導入MyBatis和mysql依賴

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.3</version>
    </dependency>
    

    操作數據庫的依賴

    <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
    
  3. 編輯核心配置文件Mybatis.config.xml

    在resource目錄下,創建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裏面可以有多個environment標籤,通過id值進行切換-->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <!--固定寫法,驅動和URL-->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                    <!--MySQL數據庫賬號-->
                    <property name="username" value="root"/>
                    <!--MySQL數據庫密碼-->
                    <property name="password" value="123456"/>
                </dataSource>
            </environment>
        </environments>
    
    </configuration>
  4. 編寫工具類

    1. 創建utils包,在utils包下創建工具類MyBatisUtil
    2. 公開靜態方法獲取sqlSession的連接
    package org.westos.utils;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    import java.io.IOException;
    import java.io.InputStream;
    
    //MyBatis工具類
    public class MyBatisUtil {
        private static SqlSessionFactory sqlSessionFactory;
    
        static {
            try {
                //因爲mybatis-config.xml配置文件在resource根目錄下,所以可以直接寫文件名
                String resource = "mybatis-config.xml";
                //固定的寫法
                InputStream inputStream = Resources.getResourceAsStream(resource);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        // 獲取sqlSession的連接
        // sqlSession中包括了面向數據庫執行的SQL命令的所有方法
        public static SqlSession getSession() {
            return sqlSessionFactory.openSession();
        }
    }
  5. 創建實體類User,對應數據庫中的表user

    實體類與數據庫中的表一一對應,使用Lombok創建User類(Lombok簡化開發步驟)

    導入Lombok的Maven依賴

    <!-- lombok依賴 -->
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.12</version>
    </dependency>

    創建User類

    package org.westos.pojo;
    
    import lombok.AllArgsConstructor;
    import lombok.Data;
    import lombok.NoArgsConstructor;
    
    //lombok的註解
    @Data
    //這個註解加有參構造
    @AllArgsConstructor
    //這個註解加默認無參構造
    @NoArgsConstructor
    public class User {
        private int id;
        private String name;
        private String pwd;
    }
  6. dao層接口編寫

    創建mapper包,在mapper包中創建包含用戶操作的接口類UserMapper (不用編寫接口的實現類UserMapperImpl)

    package org.westos.mapper;
    
    import org.westos.pojo.User;
    import java.util.List;
    
    public interface UserMapper {
        //得到數據庫表中的所有用戶
        List<User> getUserList();
    }
  7. 編寫UserMapper.xml文檔

    UserMapper.xml文檔代替原有接口的實現類UserMapperImpl,在resource目錄下創建與UserMapper 接口所在包名相一致的包,在該包中創建一個和接口對應的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綁定一個對應的接口-->
    <mapper namespace="org.westos.mapper.UserMapper">
    
        <!--
        一個select標籤對應原有UserMapper接口實現類的方法
        id屬性與UserMapper接口的方法名一致
        resultType屬性與UserMapper接口的方法返回值類型一致
        在select標籤中寫要執行的查詢語句
        -->
        <select id="getUserList" resultType="org.westos.pojo.User">
           select * from mybatis.user
       </select>
    
    </mapper>

    使用UserMapper.xml配置文檔代替原有的接口實現類的優點

    1. 可以在程序運行起來之後仍然修改程序的代碼

    2. 修改的時候只需要修改配置文檔即可,不用改動原有程序

  8. 將自定義的UserMapper.xml註冊到配置文檔Mybatis.config.xml中,進行綁定

    在UserMapper.xml中進行設置之後還需要在Mybatis.config.xml中進行映射的設置

        <!--添加用戶映射配置-->
        <mappers>
            <mapper resource="org\westos\mapper\UserMapper.xml"/>
        </mappers>
  9. 添加junit依賴

    <!-- https://mvnrepository.com/artifact/junit/junit -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.13</version>
        <scope>test</scope>
    </dependency>
  10. 編寫測試類,測試運行

    package org.westos.test;
    
    import org.apache.ibatis.session.SqlSession;
    import org.westos.mapper.UserMapper;
    import org.westos.pojo.User;
    import org.westos.utils.MyBatisUtil;
    
    import java.util.List;
    
    public class MyBatisTest {
        public static void main(String[] args) {
            //1、使用工具類獲取SqlSession(執行sql使用)
            SqlSession session = MyBatisUtil.getSession();
            //2、通過session獲得接口對象,可以調用接口的方法
            UserMapper mapper = session.getMapper(UserMapper.class);
            //3、調用接口的getUserList()方法,得到數據庫表中的所有user記錄
            List<User> userList = mapper.getUserList();
            //4、循環打印
            for (User user : userList) {
                System.out.println(user);
            }
        }
    }

3、CURD(增刪改查)

所有的增刪改操作都要提交事務,session.commit();

完成MyBatis配置後,新增接口的固定操作

  1. 編寫接口
  2. 在接口對應的接口名.xml中進行配置
  3. 保證id與接口方法名一致
  4. 進行測試

練習:

  1. select

    通過ID查詢user表中記錄

    通過用戶名和密碼查詢user表中記錄

    當接口中的方法有多個參數時,要在每個參數前加註解@Param(“變量名”)

  2. insert

    給表中插入一條記錄

    如果參數是對象,可以在配置文檔中使用#{屬性}的方式直接獲得對象的屬性

    所有的增刪改操作都要使用事務

  3. update

    根據id更新用戶的賬號和密碼

  4. delete

    根據id刪除用戶記錄

UserMapper接口及測試類

//UserMapper接口
package org.westos.mapper;

import org.apache.ibatis.annotations.Param;
import org.westos.pojo.User;
import java.util.List;

public interface UserMapper {
    List<User> getUserList();

    //使用ID得到用戶
    User getUserById(int id);

    //使用賬號密碼得到用戶信息
    User getUserByUnamePwd(@Param("username") String username, @Param("password") String password);

    //添加用戶
    int  addUser(User user);

    //修改用戶
    int updateUser(User user);

    //刪除用戶
    int  deleteUserById(int id);
}


//測試類
package org.westos.test;

import org.apache.ibatis.session.SqlSession;
import org.westos.mapper.UserMapper;
import org.westos.pojo.User;
import org.westos.utils.MyBatisUtil;

public class MyBatisExercise {
    public static void main(String[] args) {
        SqlSession session = MyBatisUtil.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);

        /*
        根據ID獲得對象
        User user = mapper.getUserById(1);
        System.out.println(user);
        */

        /*
        根據賬號密碼得到對象
        System.out.println(mapper.getUserByUnamePwd("張三", "123456"));
         */

        /*
        添加用戶
        mapper.addUser(new User(5, "李四", "123456"));
        session.commit();
         */

        /*
        根據ID刪除用戶
        mapper.deleteUserById(2);
        session.commit();
         */

        /*
        更新記錄
        mapper.updateUser(new User(3, "張三", "123456"));
        session.commit();
         */
    }
}

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">

<mapper namespace="org.westos.mapper.UserMapper">
    
    <!--查詢數據庫user表中所有的記錄-->
    <select id="getUserList" resultType="org.westos.pojo.User">
        select * from user;
    </select>

    <!--根據ID查詢表中記錄,resultType是設置返回值類型的-->
    <select id="getUserById" resultType="org.westos.pojo.User">
        select * from user where `id`=#{id}
    </select>

    <!--根據賬號和密碼查詢表中記錄-->
    <select id="getUserByUnamePwd" resultType="org.westos.pojo.User">
        select * from user where `name`=#{username}and `pwd`=#{password}
    </select>

    <!--插入記錄,parameterType是設置參數類型的-->
    <insert id="addUser" parameterType="org.westos.pojo.User">
       INSERT INTO `user`(`id`,`name`,`pwd`) VALUES (#{id},#{name},#{pwd})
    </insert>

    <!--根據ID更新記錄-->
    <update id="updateUser" parameterType="org.westos.pojo.User">
        UPDATE `user` SET `name` = #{name},`pwd`=#{pwd} WHERE `id` = #{id}
    </update>

    <!--根據ID刪除記錄-->
    <delete id="deleteUserById" parameterType="int">
        DELETE FROM `user` WHERE `id` = #{id}
    </delete>

</mapper>
  1. 注意事項

    1. 多個參數使用註解@Param("參數名稱")
    2. 增刪改要增加事務session.commit();
    3. 增刪改放的xml標籤中參數類型parameterType一定要寫
    4. 增刪改不用寫返回值,查詢要寫返回值,

4、配置文檔配置

[外鏈圖片轉存失敗,源站可能有防盜鏈機制,建議將圖片保存下來直接上傳(img-BvaTKxc4-1582124870348)(assets/1582094567251.png)]

  1. environments標籤

    內部可以有多個environment子元素,多套配置,只需要更換default屬性的值就行

  2. transactionManager

    事務管理器,默認是JDBC

  3. dataSource

    數據源配置,默認使用池化技術POOLED

  4. mappers

    映射器,有三種配置方法

    1. class:接口對應的類的路徑,前提是配置文檔和接口的包名稱相同

    2. package:可以掃描具體的包中所有的接口,開發中多使用

    3. resource:對應的資源路徑

  5. 配置文件中標籤不可以亂放,元素的位置是有順序要求的

1、db.properties配置文檔,不寫死

  1. 在resource目錄下創建db.properties文件

    將數據庫的配置信息放在裏面

    driver=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis? useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf8
    username=root
    password=123
    
  2. 使用properties標籤引入db.properties文件,<property name="" value=""/>標籤的value值可以使用${屬性名}來引用db.properties文件。

    <!--配置db.properties文件,資源從db.properties文件中獲得,更靈活-->
    <properties resource="db.properties"/>
    
    <!--使用${}符號動態取出數據庫的配置參數-->
    <property name="driver" value="${driver}"/>
    <property name="url" value="${url}"/>
    <property name="username" value="${username}"/>
    <property name="password" value="${password}"/>

2、包的別名設置

設置了以後在接口名r.xml文檔中進行配置就不用再寫類的全路徑了,可以直接使用別名

    <!--別名設置,簡化開發-->
    <typeAliases>
        <!-- type指的是原來的包名,而alias指的是新的別名-->
        <typeAlias type="org.westos.pojo.User" alias="User"/>
    </typeAliases>

3、setting 配置輸出日誌

可以看到具體的SQL執行信息,檢查錯誤

<!--日誌輸出,可以顯示執行的日誌-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

4、用戶映射配置

可以修改掃描設置爲一個包下的所有接口配置文件,就不用一一導入了

<!--添加用戶映射配置-->
<mappers>
    <!--<mapper resource="org\westos\mapper\UserMapper.xml"/>-->
    <!--修改掃描設置爲包的設置,掃描mapper包下的所有的配置文件-->
    <package name="org.westos.mapper"/>
</mappers>

5、映射

1、結果集映射

resultMap:做結果映射,對數據庫字段和實體類屬性進行映射

有時候我們會遇到數據庫中表的字段名和對應實體類的屬性名不一致的情況,這樣子就會導致數據庫中的某些字段查詢不出來

解決方案

  1. 手動將SQL補全,使用as起別名

    <select id="getUserList" resultType="User">
        <!--select * from user;-->
        select id,name,pwd as password from user
        <!--
        完整的將SQL的字段寫出來,將名稱不一樣的字段使用AS起別名
        不推薦使用,比較繁瑣,每次查詢都要寫一遍
        -->
    </select>
  2. 使用resultMap,一勞永逸

    <!--
    當調用getUserList方法的時候,就會先去找別名爲UserMap的標籤,然後使用該標籤中修改過後的屬性去查找
    數據庫和實體表名稱一樣的屬性可以刪掉不寫,只寫不一樣的映射
    -->    
    <select id="getUserList" resultMap="UserMap">
        select * from user
    </select>
    
    <resultMap id="UserMap" type="User">
        <result column="pwd" property="password"/>
        <result column="id" property="id"/>
        <result column="name" property="name"/>
    </resultMap>

6、log4j日誌使用

爲什麼使用日誌

爲了便於排查錯誤,日誌會將程序的運行過程都打印在控制檯,也可以生成在日誌文件中

MyBatis默認日誌
默認是STDOUT_LOGGING,但在實際的開發中更多的使用Log4j

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

Log4j日誌配置步驟

  1. Log4j依賴導入
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  1. 在resource目錄下導入Log4j.properties配置文件

    ### 設置###
    log4j.rootLogger = debug,stdout,D,E
    
    ### 輸出信息到控制擡 ###
    log4j.appender.stdout = org.apache.log4j.ConsoleAppender
    log4j.appender.stdout.Target = System.out
    log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
    log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
    
    ### 輸出DEBUG 級別以上的日誌到=./log/logs/error.log ###
    log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.D.File = ./log/log.log
    log4j.appender.D.Append = true
    log4j.appender.D.Threshold = DEBUG
    log4j.appender.D.layout = org.apache.log4j.PatternLayout
    log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
    
    ### 輸出ERROR 級別以上的日誌到=./log/logs/error.log ###
    log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
    log4j.appender.E.File =./log/error.log
    log4j.appender.E.Append = true
    log4j.appender.E.Threshold = ERROR
    log4j.appender.E.layout = org.apache.log4j.PatternLayout
    
  2. 將默認的配置日誌換成Log4j,注意必須是全部大寫,沒有空格

    <!--日誌輸出設置爲Log4j-->
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    </settings>
  3. Log4j使用

    獲得Logger對象logger,用來輸出

    1. logger.error();錯誤信息

    2. logger.info();提示信息

    3. logger.debug();調試信息

    可以將日誌實現細粒度的控制,將錯誤信息輸出到log日誌中

練習:使用Log4j打印錯誤信息到log日誌中

package org.westos.test;

import org.apache.ibatis.session.SqlSession;
import org.apache.log4j.Logger;
import org.westos.mapper.UserMapper;
import org.westos.utils.MyBatisUtil;

public class Log4jTest {

 static Logger logger = Logger.getLogger(Log4jTest.class);

 public static void main(String[] args) {
     SqlSession session = MyBatisUtil.getSession();
     UserMapper mapper = session.getMapper(UserMapper.class);

     logger.error("錯誤信息");
     logger.info("提示信息");
     logger.debug("調試信息");

     System.out.println(mapper.getUserList());
 }
}

7、分頁(一定要會)

爲什麼使用分頁

提高服務器性能,網站響應的時候不希望一次性將所有的數據都刷新出去,而是一部分一部分刷新。分頁有利於服務器資源的節約

當參數過多的時候,可以使用Map集合進行傳遞參數,使用鍵值對得到值

接口名.xml配置文檔中配置非基本類型參數時,需要使用parameterType屬性來顯示的定義

1、Limit分頁(SQL層面)

在ResultMapper中創建帶分頁操作的方法

  1. 在接口中定義方法getUsersByLimit()

  2. 在xml配置文檔中配置

        <select resultType="User" parameterType="Map" id="getUsersByLimit">
            select * from user limit #{startIndex},#{pageSize}
        </select>
  3. 測試類

    package org.westos.test;
    
    import org.apache.ibatis.session.SqlSession;
    import org.westos.mapper.ResultMapper;
    import org.westos.pojo.User;
    import org.westos.utils.MyBatisUtil;
    
    import java.util.HashMap;
    import java.util.List;
    
    public class ResultMapTest {
        public static void main(String[] args) {
            SqlSession session = MyBatisUtil.getSession();
            ResultMapper mapper = session.getMapper(ResultMapper.class);
    
            int currentPage = 2; //當前頁面
            int pageSize = 3;    //每頁顯示幾條記錄
            //創建HashMap,存放頁面信息
            HashMap<String, Integer> map = new HashMap<String, Integer>();
            //計算開始索引
            map.put("startIndex",(currentPage-1)*pageSize);
            //頁面大小
            map.put("pageSize",pageSize);
            //調用方法得到分頁查詢得到的用戶記錄
            List<User> users = mapper.getUsersByLimit(map);
            //打印
            System.out.println(users);
        }
    }

2、RowBounds分頁(Java層面)

其實底層也是使用limit實現的

  1. 接口中定義方法

    List<User> selectUserByLimit();
  2. xml配置

    <!-- 非基本類型之外的數據類型,List,Map,需要顯示的定義 -->
    <select id="selectUserByLimit" parameterType="map" resultMap="UserMap">
        select * from user;
    </select>
  3. 測試類

    package org.westos.test;
    
    import org.apache.ibatis.session.RowBounds;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.log4j.Logger;
    import org.westos.pojo.User;
    import org.westos.utils.MyBatisUtil;
    
    import java.util.List;
    
    public class RowBoundsTest {
    
        //導入org.apache.log4j.Logger包
        static Logger logger = Logger.getLogger(RowBoundsTest.class);
    
        public static void main(String[] args) {
    
            SqlSession session = MyBatisUtil.getSession();
    
            int currentPage = 1; //當前頁
            int pageSize = 3;    //每頁顯示幾個
    
            //展示的頁面信息
            RowBounds rowBounds = new RowBounds((currentPage-1)*pageSize,pageSize);
    
            // selectList(方法的路徑)
            //不使用對象,直接調用方法
            List<User> users = session.selectList("org.westos.mapper.ResultMapper.selectUserByLimit", null, rowBounds);
    
            for (User user : users) {
                System.out.println(user);
            }
        }
    }
  4. 可以使用selectXXX執行具體的某個方法,得到結果,通過這個方法,實現Java分頁

3、分頁插件 - PageHelper

使用分頁插件PageHelper也可以通過插件實現分頁,但是底層也是通過limit實現的

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章