認識mybatis

MyBatis

什麼是MyBatis

  1. 找到mybatis:mybatis被託管在github上,github地址:https://github.com/mybatis/mybatis-3
  2. MyBatis 是一款優秀的持久層框架
  3. MyBatis 避免了幾乎全部的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可使用簡單的 XML 或註解來配置和映射原生類型、接口和 Java 的 POJO(Plain Old Java Objects,普通老式 Java 對象)爲數據庫中的記錄。
  4. mybatis是一個半orm(對象關係映射)框架。
  5. mybatis專一於SQL自己,是一個足夠靈活的dao層解決方案。

什麼是持久層

  1. 持久態和瞬時態:持久化就是數據在瞬時狀態和持久狀態之間轉化的一個過程。
  2. 持久層對應咱們代碼架構的dao層,dao層專一於處理數據庫的操做,可是要寫一大堆的jdbc代碼,咱們應注語句的編寫,獲得SQL的返回值便可。
  3. 持久層:咱們的系統中應該有一個單獨的層面來處理數據鏈接的問題;就是咱們所說的解耦。解耦,這個層面就應該有較爲清晰的邏輯邊界。

爲何須要mybatis這個框架

  1. 黑箱操做:hibernate全自動的ORM框架,不用編寫sql語句;
  2. 白箱操做:mybatis半自動的ORM框架 , 咱們能夠自定義sql語句;更加靈活;全部sql語句都由咱們開發人員來編寫,可以定製化完成許多功能。
  3. SSM框架:Spring 、SpingMVC、MyBatis。
  4. MyBatis的優勢:
    1. 不用再去編寫一堆JDBC代碼;
    2. 簡單易學,不依賴第三方的程序或者框架;
    3. 官網文檔強大,開源,咱們能夠隨時分析源碼;
    4. 實現解耦,低耦合,高內聚;(接口之間進行交互)
    5. ORM,對象關係映射;
    6. 提供XML標籤;只須要經過簡單的xml就能夠完成全部SQL語句的編寫。

使用MyBatists只須要將mybatis-x.x.x.jar文件放到項目中便可;前端

若是使用Maven來構建項目,將dependency代碼(依賴)放在pom.xml文件中就能夠了java

xml中不容許&出現,須要使用&ampmysql

建立一個MyBatists

  1. 搭建實驗環境:建立數據庫及數據表git

    CREATE DATABASE /*!32312 IF NOT EXISTS*/`mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */;
    
    USE `mybatis`;
    
    DROP TABLE IF EXISTS `user`;
    
    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,'張三','abcdef'),(3,'李四','987654');
  2. 建立項目:建立Maven項目,導入dependency代碼github

    項目結構以下:web

    找到pom.xml文件:導入依賴,連接數據庫驅動包,並使依賴能夠應用到項目中,代碼以下:sql

    <?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>com.kuang</groupId>
        <artifactId>ssm-mybatis-study</artifactId>
        <version>1.0-SNAPSHOT</version>
    
        <dependencies>
    
            <!--單元測試-->
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.11</version>
            </dependency>
    
            <!--mybatis的包-->
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>3.5.1</version>
            </dependency>
    
            <!--鏈接數據庫的驅動包-->
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.47</version>
            </dependency>
    
        </dependencies>
    
    
        <build>
            <!--但願maven在導出項目的時候,可以將咱們的配置及資源導出-->
            <resources>
                <resource>
                    <directory>src/main/java</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
                <resource>
                    <directory>src/main/resources</directory>
                    <includes>
                        <include>**/*.properties</include>
                        <include>**/*.xml</include>
                    </includes>
                    <filtering>false</filtering>
                </resource>
            </resources>
        </build>
    </project>
  3. 刪除src文件夾,在項目裏建立一個子項目,子項目共有父項目的全部東西。數據庫

  4. 編寫代碼:apache

    1. 在resource文件夾下建立mybatis-config.xml文件,從網上拿取固定代碼,配置默認的development環境,編寫環境的名字,將事務管理標籤改爲"JDBC"。將數據源改成"pooled"並編寫其中的property信息()創建數據庫鏈接。編程

    2. 建立一個包,構建一個鏈接xml的流mybatisUtils工具類提純重複代碼,解決代碼中的報紅問題,在maven項目中全部的資源文件都放在resource文件夾下,咱們能夠直接拿到

    3. 建立pojo包,編寫操做數據的user實體類:

      package com.david.pojo;
      
      public class User {
      
          private int id;
          private String name;
          private String pwd;
      
          public User() {
          }
      
          public User(int id, String name, String pwd) {
              this.id = id;
              this.name = name;
              this.pwd = pwd;
          }
      
          public int getId() {
              return id;
          }
      
          public void setId(int id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          public String getPwd() {
              return pwd;
          }
      
          public void setPwd(String pwd) {
              this.pwd = pwd;
          }
      
          @Override
          public String toString() {
              return "User{" +
                      "id=" + id +
                      ", name='" + name + '\'' +
                      ", pwd='" + pwd + '\'' +
                      '}';
          }
      }
    4. 建立dao層,寫userMapper接口:

      package com.david.dao;
      
      import com.kuang.pojo.User;
      
      import java.util.List;
      
      public interface UserMapper {
          //獲取所有的用戶
          List<User> selectUser();
      }
    5. 建立與mapper接口對應的xml文件:編寫查詢(select標籤,標籤的ID對應映射接口的方法名字,resultType寫返回結果類型)select標籤中編寫SQL語句。

    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>
          <!--配置環境,這裏能夠有多套環境 default表明默認的是那一套-->
          <environments default="development">
              <!--配置一套環境 id .環境的名字-->
              <environment id="development">
                  <!--transactionManager:事務管理,type:jdbc-->
                  <transactionManager type="JDBC"/>
                  <!--dataSource 數據源-->
                  <dataSource type="POOLED">
                      <property name="driver" value="com.mysql.jdbc.Driver"/>
                      <!--xml中不容許&符號直接出現,咱們須要使用 &amp; 代替-->
                      <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;charsetEncoding=UTF-8"/>
                      <property name="username" value="root"/>
                      <property name="password" value="123456"/>
                  </dataSource>
              </environment>
          </environments>
      </configuration>
    7. 建立工具類

      package com.david.utils;
      
      import org.apache.ibatis.io.Resources;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.apache.ibatis.session.SqlSessionFactoryBuilder;
      
      import java.io.IOException;
      import java.io.InputStream;
      
      //mybatis的工具類,重複的代碼的提純
      public class MyBatisUtils {
      
          //類變量不須要設置默認值;
          private static SqlSessionFactory sqlSessionFactory;
      
          static {
      
              //在maven中,全部的資源文件通常都放在resources目錄下,咱們能夠直接拿到。
              try {
                  String resource = "mybatis-config.xml";
                  InputStream inputStream = Resources.getResourceAsStream(resource);
                  sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
              } catch (IOException e) {
                  e.printStackTrace();
              }
      
          }
      
          //設置SqlSessionFactory公共的方法
          public static SqlSessionFactory getSqlSessionFactory(){
              return sqlSessionFactory;
          }
      
      
      }
    8. 測試:在maven的test文件夾下編寫對應的測試類

      package com.david.dao;
      
      import com.kuang.dao.UserMapper;
      import com.kuang.pojo.User;
      import com.kuang.utils.MyBatisUtils;
      import org.apache.ibatis.session.SqlSession;
      import org.apache.ibatis.session.SqlSessionFactory;
      import org.junit.Test;
      
      import java.util.List;
      
      public class UserMapperTest {
          @Test
          public void selectUser(){
      
              //1.拿到sqlSessionFactory對象
              SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
              //2.經過sqlSessionFactory對象openSession()建立一個sqlSession。
              SqlSession sqlSession = sqlSessionFactory.openSession();
              //3.經過sqlSession得到mapper對象 , 參數爲映射文件對應的接口類的class對象
              UserMapper mapper = sqlSession.getMapper(UserMapper.class);
              //4.經過mapper對象來執行操做;
              List<User> users = mapper.selectUser();
      
              //得到結果集
              for (User user : users) {
                  System.out.println(user);
              }
      
      
          }
      }
    9. 獲得代碼的查詢數據庫的結果

增刪改查操做

Mapper接口本質就是原來的Dao接口,只是爲了方便書寫。一個,Mapper接口對應一個Mapper映射文件。

  1. 編寫接口:

    package com.david.dao;
    
    import com.david.pojo.User;
    
    import java.util.List;
    
    public interface UserDao {
        //獲取所有的用戶
        List<User> selectUser();
    
        //根據id查找用戶
        User selectUserById(int id);
    
        //添加一個用戶
        int addUser(User user);
    
        //刪除用戶
        int deleteUserByID(int id);
    
        //修改用戶
        int updateUser(User user);
    
    }
  2. 編寫對應的mapper語句:

    <?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對應Mapper接口的類,包名+類名-->
    <mapper namespace="com.david.dao.UserDao">
    
        <!--select標籤的id對應映射接口的方法名字  resultType:返回結果的類型  中間就編寫sql語句-->
        <select id="selectUser" resultType="com.david.pojo.User">
        select * from user
        </select>
    
        <select id="selectUserById" resultType="com.david.pojo.User">
            select * from user where id = #{id}
        </select>
    
        <!--
        咱們須要接受一個自定義的對象(引用對象),須要設置parameterType,爲參數類型
        接受這個對象的值,直接使用 #{對象字段名}
        -->
        <insert id="addUser" parameterType="com.david.pojo.User">
            insert into user(id ,name, pwd) values (#{id},#{name},#{pwd})
        </insert>
    
        <delete id="deleteUserByID" parameterType="int">
            delete from user where id = #{id}
        </delete>
    
        <update id="updateUser" parameterType="com.david.pojo.User">
            update user set name =#{name},pwd = #{pwd} where id = #{id}
        </update>
    
    </mapper>
  3. 編寫測試類:

    package com.david.dao;
    
    import com.david.dao.UserDao;
    import com.david.pojo.User;
    import com.david.utils.MyBatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.junit.Test;
    import java.util.List;
    
    public class UserMapperTest {
        @Test
        public void selectUser() {
            //1.拿到sqlSessionFactory對象
            SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
            //2.經過sqlSessionFactory對象openSession()建立一個sqlSession。
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //3.經過sqlSession得到mapper對象 , 參數爲映射文件對應的接口類的class對象
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            //4.經過mapper對象來執行操做;
            List<User> users = mapper.selectUser();
            //得到結果集
            for (User user : users) {
                System.out.println(user);
            }
            sqlSession.close(); //關閉sqlSession
        }
        @Test
        public void selectUserById(){
            SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            //接口  對象名  = new  接口實現類
            User user = mapper.selectUserById(1);
            System.out.println(user);
            sqlSession.close(); //關閉sqlSession
        }
        @Test
        public void addUser(){
            User user = new User(2,"a_xia","792228573");
            SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
            SqlSession sqlSession = sqlSessionFactory.openSession();
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            int i = mapper.addUser(user);
            //沒有插入成功的緣由:沒有提交事務;
            sqlSession.commit(); //提交事務
            sqlSession.close(); //關閉sqlSession
            if (i>0){
                System.out.println("插入成功!");
            }
        }
        @Test
        public void deleteUserByID(){
            SqlSession sqlSession = MyBatisUtils.getSqlSessionFactory().openSession();
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            int i = mapper.deleteUserByID(4);
            //記得提交事務,不然刪除不成功!
            sqlSession.commit();//提交事務
            sqlSession.close();//關閉
            if (i>0){
                System.out.println(i);
            }
        }
        @Test
        public void updateUser(){
            SqlSession sqlSession = MyBatisUtils.getSqlSessionFactory().openSession();
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            User user = new User(1,"啊俠","ironman");
            mapper.updateUser(user);
            sqlSession.commit();
            sqlSession.close();
        }
    }

增刪改查注意點

  1. 增,改,刪須要提交事務!查詢不須要提交事務。

  2. 若是出現亂碼,先在sql中進行測試,sql沒問題,就檢查配置文件

    jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf-8"
  3. 參數若是是基本數據類型,能夠省略,可是建議寫上引用類型必須寫指定的 包名+類名。



配置文件的詳解:mybatis-config文件解析

<?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 配置
    properties   配置文件
    settings     mybatis設置
    typeAliases   爲Java類起別名
    typeHandlers  類處理器
    objectFactory  對象工廠 
    plugins   插件
    environments  環境
        transactionManager : 事務管理
        dataSource : 數據源
    mappers 映射器
<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="${driver}"/>
            <property name="url" value="${url}"/>
            <property name="username" value="${username}"/>
            <property name="password" value="${password}"/>
        </dataSource>
    </environment>
</environments>

關聯映射文件:推薦使用resource

<!--關聯映射文件-->
    <mappers>
        <mapper resource="com/work/dao/user/UserMapper.xml"/>
    </mappers>

優化代碼

  1. 優化配置文件

    1. 建立一個database.properties

      driver = com.mysql.jdbc.Driver
      url = jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=utf-8
      username = root
      password = 123456
    2. 在mybatis核心配置文件中引入properties配置文件並用${}表達式引入其中的值

      <configuration>
      
          <!--配置文件修改-->
          <properties resource="database.properties"/>
      
          <environments default="development">
              <environment id="development">
                  <transactionManager type="JDBC"/>
                  <dataSource type="POOLED">
                      <property name="driver" value="${driver}"/>
                      <property name="url" value="${url}"/>
                      <property name="username" value="${username}"/>
                      <property name="password" value="${password}"/>
                  </dataSource>
              </environment>
          </environments>
      
          <mappers>
              <mapper resource="com/david/dao/userMapper.xml"/>
          </mappers>
      </configuration>
  2. 優化別名:

    1. 位置必須正確

      <!--配置別名-->
      <typeAliases>
          <!--配置指定類的別名-->
          <typeAlias type="com.david.pojo.User" alias="User"/>
          <!--
              能夠爲一個包的全部類指定別名,這個別名爲類名
              com.david.pojo.User    -  >  User
              com.david.pojo.Student   -  >  Student
              -->
          <package name="com.david.pojo"/>
      </typeAliases>
    2. 優化完畢後咱們在mapper映射文件中就可使用別名了

      <?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對應Mapper接口的類,包名+類名-->
      <mapper namespace="com.david.dao.UserDao">
          <!--select標籤的id對應映射接口的方法名字  resultType:返回結果的類型  中間就編寫sql語句-->
          <select id="selectUser" resultType="User">
          select * from user
          </select>
          <select id="selectUserById" resultType="User">
              select * from user where id = #{id}
          </select>
          <!--
          咱們須要接受一個自定義的對象(引用對象),須要設置parameterType,爲參數類型
          接受這個對象的值,直接使用 #{對象字段名}
          -->
          <insert id="addUser" parameterType="User">
              insert into user(id ,name, pwd) values (#{id},#{name},#{pwd})
          </insert>
          <delete id="deleteUserByID" parameterType="int">
              delete from user where id = #{id}
          </delete>
          <update id="updateUser" parameterType="User">
              update user set name =#{name},pwd = #{pwd} where id = #{id}
          </update>
      </mapper>

經過結果映射集解決屬性和字段名不一致的問題

mybatis會根據數據庫的字段名去找對應的實體類的屬性名,(他會將全部列名轉換爲小寫,而後去找實體類中對應的 set方法 ,set方法後面的字段就對應數據庫的字段名;若是不同就會返回null)

因此爲了不萬一數據庫中數據表字段名和pojo層私有屬性名不一致的問題,推薦使用結果映射集resultMap來解決,在pojo層對應的dao層XML文件中添加resultMap標籤

<!--設置結果的映射類型-->
<resultMap id="UserMap" type="User">
    <!--
    通常經過id標籤來映射主鍵
    column = 數據庫的列名
    property = 結果集對應的數據庫列名的映射名
    -->
    <id column="id" property="id"/>
    <result column="name" property="name"/>
    <result column="pwd" property="password"/>
</resultMap>


<select id="selectUser" resultMap="UserMap">
  select * from user
</select>

log4j實現

log4java:Java日誌的實現;

將log4j依賴放到父項目中應用全局:

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>

log4j.properties配置文件:

### Log4j配置 ###
### 與Spring結合須要在web.xml中指定此文件位置,並添加監聽器 ###
#定義log4j的輸出級別和輸出目的地(目的地能夠自定義名稱,和後面的對應)
#[ level ] , appenderName1 , appenderName2
log4j.rootLogger=DEBUG,console,file

#-----------------------------------#
#1 定義日誌輸出目的地爲控制檯
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold=DEBUG
####能夠靈活地指定日誌輸出格式,下面一行是指定具體的格式 ###
#%c: 輸出日誌信息所屬的類目,一般就是所在類的全名
#%m: 輸出代碼中指定的消息,產生的日誌具體信息
#%n: 輸出一個回車換行符,Windows平臺爲"/r/n",Unix平臺爲"/n"輸出日誌信息換行
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=[%c]-%m%n

#-----------------------------------#
#2 文件大小到達指定尺寸的時候產生一個新的文件
log4j.appender.file = org.apache.log4j.RollingFileAppender
#日誌文件輸出目錄
log4j.appender.file.File=log/tibet.log
#定義文件最大大小
log4j.appender.file.MaxFileSize=10mb
###輸出日誌信息###
#最低級別
log4j.appender.file.Threshold=ERROR
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=[%p][%d{yy-MM-dd}][%c]%m%n

#-----------------------------------#
#3 druid
log4j.logger.druid.sql=INFO
log4j.logger.druid.sql.DataSource=info
log4j.logger.druid.sql.Connection=info
log4j.logger.druid.sql.Statement=info
log4j.logger.druid.sql.ResultSet=info

#4 mybatis 顯示SQL語句部分
log4j.logger.org.mybatis=DEBUG
#log4j.logger.cn.tibet.cas.dao=DEBUG
#log4j.logger.org.mybatis.common.jdbc.SimpleDataSource=DEBUG
#log4j.logger.org.mybatis.common.jdbc.ScriptRunner=DEBUG
#log4j.logger.org.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
#log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

mybatis的日誌實現

  1. 默認的日誌實現

    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
  2. log4j日誌實現

    1. 導包

    2. 配置文件編寫

    3. mybatis核心文件中進行配置

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

limit分頁的實現

  1. mysql的分頁語句:

    select*from user limit #{startIndex},#{pageSize};
    #startIndex:起始位置,默認從零
    # pageSize頁面大小
    #如何計算當前頁:currentPage = (currentPage-1)* pageSize
  2. 查詢所有用戶,實現分類的Dao接口:

    //查詢所有用戶實現分頁
    List<User> selectUserByLimit(Map<String,Integer> map);
  3. 編寫userMapper.xml文件中的方法:參數可使用map進行封裝,方便參數傳遞

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

    1. 模擬分頁數據
    2. 測試
    @Test
    public void selectUserByLimit(){
    
        //建立sqlSession
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        //準備數據
        int currentPage = 2;//當前是第幾頁
        int pageSize = 2; //頁面大小
    
        Map<String, Integer> map = new HashMap<String, Integer>();
        map.put("startIndex",(currentPage-1)*pageSize);
        map.put("pageSize",pageSize);
    
        //測試
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> users = mapper.selectUserByLimit(map);
    
        for (User user : users) {
            System.out.println(user);
        }
    
        sqlSession.close();//關閉鏈接
    
    }
  5. 更換模擬由前端給過來當前頁面的數字進行改動,查看結果:

使用RowBounds(瞭解)

使用RowBounds就不能用getMapper

  1. 寫接口:

    //查詢所有用戶實現分頁使用RowBounds
    List<User> selectUserByRowBounds();
  2. 寫mapper映射

    <select id="selectUserByRowBounds" resultType="User">
        select * from mybatis.user
    </select>
  3. 編寫測試代碼

    @Test
    public void selectUserByRowBounds(){
        //建立sqlSession
        SqlSessionFactory sqlSessionFactory = MyBatisUtils.getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
    
        int currentPage = 2; //當前頁
        int pageSize = 2; //頁面大小
    
        RowBounds rowBounds = new RowBounds((currentPage - 1) * pageSize, pageSize);
    
        //注意點;使用RowBounds就不能使用getMapper了
        //selectList: 接收一個List
        //selectMap: 接收一個Map
        //selectOne : 接收只有一個對象的時候
    
        List<User> users = sqlSession.selectList("com.kuang.dao.UserDao.selectUserByRowBounds", null, rowBounds);
    
        for (User user : users) {
            System.out.println(user);
        }
    }

limit和rowBounds的區別:

  1. rowBounds本質上是封裝了limit;
  2. limit是在SQL層面實現分頁;
  3. rowBounds 在代碼層面實現分頁。

面向接口編程

爲了解耦、方便拓展、提升代碼的複用性,上層不用管下層實驗,只用去調用對應的接口,而提出的面向接口編程。

面向過程編程→面向對象編程→面向接口編程:

  1. 面向過程:系統代碼較少的時候,咱們能夠專一於過程的編寫,但隨着系統愈來愈大,咱們沒法使用面向過程的思想知足,就須要面向對象的編程。
  2. 面向對象:全部系統耦合性高,全部的功能都是由許許多多不一樣的對象去完成的,可是隨着系統的增大,就須要解耦,就像生活中文章的提綱同樣,就須要面向接口的編程。
  3. 面向接口:約束開發人員操做,而且方便擴展以及規劃。

實現了定義與實現的一個分離

接口能夠反映一個開發人員的水平高低,以及對系統架構的理解。


使用註解開發

早起的mybatis都是使用xml進行配置的,而註解能夠替代一些xml中的配置。再也不須要XML文件

CRUD的註解:(增刪改查)

  1. @insert()
  2. @delete()
  3. @update()
  4. @select()

因爲編程中始終沒有對事物進行優化,mybatis開發者想到了,有一個構造器,能夠實現事物自動提交。

openSession(true); //openSession構造器若是參數爲true,則事務會自動提交。咱們就不用每次都commit;

優化項目

  1. 事物優化:自動提交事物;

    //得到一個帶事務自動提交功能的SqlSession公共的方法
    public static SqlSession getSqlSession(){
        //自動提交事務
        return sqlSessionFactory.openSession(true);
    }
  2. 別名優化:pojo包下類自動設置別名

    <!--配置別名-->
    <typeAliases>
        <!--<typeAlias type="com.david.pojo.User" alias="User"/>-->
        <package name="com.david.pojo"/>
    </typeAliases>
  3. mapper映射文件路徑修改

    <mappers>
        <!--class對應的是一個接口類-->
        <!--resource對應的是一個接口類的映射文件-->
        <mapper class="com.david.dao.UserDao"/>
    </mappers>

使用註解進行開發

  1. 編輯UserDao.java;

    package com.david.dao;
    
    import com.david.pojo.User;
    import org.apache.ibatis.annotations.*;
    
    import java.util.List;
    
    public interface UserDao {
    
        //查詢所有用戶
        @Select("select * from user")
        List<User> getUserList();
    
        //經過ID查詢用戶
        @Select("select * from user where id = #{id}")
        User getUserById(@Param("id") int id);
    
        //添加用戶
        @Insert("insert into user(id,name,pwd) values (#{id},#{name},#{pwd})")
        int addUser(User user);
    
        //修改用戶信息
        @Update("update user set name = #{name}, pwd = #{pwd} where id = #{id}")
        int updateUser(User user);
    
        //刪除用戶
        @Delete("delete from user where id =#{uid}")
        int deleteUser(@Param("uid") int id);
    }
  2. 編輯mybatis核心文件;

    <?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>
    
        <!--配置文件修改-->
        <properties resource="database.properties"/>
    
        <!--Mybatis設置-->
        <settings>
            <!--默認日誌實現-->
            <!--<setting name="logImpl" value="STDOUT_LOGGING"/>-->
    
            <!--Log4j實現-->
            <setting name="logImpl" value="LOG4J"/>
        </settings>
    
        <!--配置別名-->
        <typeAliases>
            <!--<typeAlias type="com.david.pojo.User" alias="User"/>-->
            <package name="com.david.pojo"/>
        </typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <!--class對應的是一個接口類-->
            <!--resource對應的是一個接口類的映射文件-->
            <mapper class="com.david.dao.UserDao"/>
        </mappers>
    
    </configuration>
  3. 編寫測試類;

    package com.david.dao;
    
    import com.david.pojo.User;
    import com.david.utils.MyBatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    import sun.rmi.server.UnicastServerRef;
    
    import java.util.List;
    
    
    public class UserDaoTest {
    
        @Test
        public void getUserList(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();//帶自動提交事務
    
            UserDao mapper = sqlSession.getMapper(UserDao.class);
    
            List<User> userList = mapper.getUserList();
    
            for (User user : userList) {
                System.out.println(user);
            }
            sqlSession.close();//關閉sqlSession;
        }
    
        @Test
        public void getUserById(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();//帶自動提交事務
    
            UserDao mapper = sqlSession.getMapper(UserDao.class);
    
            User user = mapper.getUserById(1);
    
            System.out.println(user);
    
            sqlSession.close();//關閉sqlSession;
        }
    
    
        @Test
        public void addUser(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();//帶自動提交事務
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            User user = new User(5, "阿宇", "like-chickenpizza");
            int i = mapper.addUser(user);
            System.out.println(i);
    
            sqlSession.close();//關閉sqlSession;
    
        }
    
        @Test
        public void updateUser(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();//帶自動提交事務
            UserDao mapper = sqlSession.getMapper(UserDao.class);
            User user = new User(5, "阿俠", "love-cheeseBurger");
            int i = mapper.updateUser(user);
            System.out.println(i);
    
            sqlSession.close();//關閉sqlSession;
    
        }
    
        @Test
        public void deleteUser(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();//帶自動提交事務
            UserDao mapper = sqlSession.getMapper(UserDao.class);
    
            int i = mapper.deleteUser(5);
            System.out.println(i);
            //關閉sqlSession;
            sqlSession.close();
        }
    }
  4. 注意事項:

    1. 事物自動提交已經開啓;
    2. @param參數儘可能都寫上,若是存在多個參數,就必須填寫。

多對一處理

多個對象,對應一個對象。mybatis中遇到多對一的狀況,要使用關聯映射處理:使用association。

association --- 聯繫 ,關聯;

多對一業務狀況,須要使用association標籤進行關聯。

  1. 數據庫思想:鏈表查詢:

    1. 定義dao接口:

      List<Student> getStudents();
    2. 編寫查詢語句:

      1. 查詢學生信息id、name、tid,因爲咱們要獲得老師的信息,因此須要聯表查詢;

      2. 查詢老師的信息id、name。

        <!--遇到問題:學生類中關聯老師: 多個學生對應一個老師 -->
        <!--<select id="getStudents" resultType="Student">-->
            <!--select s.id,s.name,t.name from mybatis.student as s,mybatis.teacher as t-->
            <!--where s.tid = t.id-->
        <!--</select>-->
        <!--解決問題方式一:按查詢結果嵌套處理,模擬數據庫思想;
        -->
        <select id="getStudents" resultMap="StudentTeacher">
            select * from mybatis.student
        </select>
        <resultMap id="StudentTeacher" type="Student">
            <id column="id" property="id"/>
            <result column="name" property="name"/>
            <!--屬性和字段對應  , 類和表對應  , 對象和記錄
            關聯一個字段
            需求:拿到老師這個類的屬性
            association : 關聯,多對一
                column : 數據庫對應的列名
                property : 對應屬性名
                javaType : 多對一字段對應的Java類型
                select : 關聯一個語句
            -->
            <association column="tid" property="teacher" javaType="Teacher" select="getTeacher"/>
        </resultMap>
        <select id="getTeacher" resultType="Teacher">
            select * from mybatis.teacher where id = #{id}
        </select>
    3. 編寫測試類:

      @Test
          public void getStudents(){
              SqlSession sqlSession = MyBatisUtils.getSqlSession();
              StudentDao mapper = sqlSession.getMapper(StudentDao.class);
              List<Student> students = mapper.getStudents();
              for (Student student : students) {
                  System.out.println("學生姓名:"+student.getName()+"\t老師姓名:"+student.getTeacher().getName());
              }
          }
  2. opp思想:關聯對象:

    1. 編寫接口

      List<Student> getStudentTwo();
    2. 編寫處理的mapper

      1. 查詢學生id,學生姓名,老師姓名,須要從學生表和老師表中查詢;

      2. 學生對應的類進行映射,發現老師一個對象 , 因此關聯一個對象;

        <!-- 解決方式二:一個resultMap解決 , 模擬面向對象的思想-->
        <select id="getStudentsTwo" resultMap="StudentTeacher2">
            select s.id,s.name,t.name as tname from mybatis.student as s, mybatis.teacher as t
            where s.tid = t.id
        </select>
        <!--設置結果集映射ResultMap -->
        <resultMap id="StudentTeacher2" type="Student">
            <id property="id" column="id"/>
            <result property="name" column="name"/>
            <!--直接關聯一個老師-->
            <association property="teacher" javaType="Teacher">
                <result property="name" column="tname"/>
            </association>
        </resultMap>
    3. 編寫測試類:

      @Test
      public void getStudentsTwo(){
          SqlSession sqlSession = MyBatisUtils.getSqlSession();
          StudentDao mapper = sqlSession.getMapper(StudentDao.class);
          List<Student> students = mapper.getStudentsTwo();
          for (Student student : students) {
              System.out.println("學生姓名:"+student.getName()+"\t老師姓名:"+student.getTeacher().getName());
          }
      }

一對多處理

一對多的業務使用collection處理

  1. 搭建實驗環境:

    public class Teacher {
        private int id;
        private String name;
    
        //一個老師對應對個學生
        private List<Student> students;
    }
  2. 編寫接口:

    package com.david.dao;
    
    import com.david.pojo.Teacher;
    
    public interface TeacherDao {
    
        //得到一個老師下的全部學生信息; 老師是包含學生的集合;
        Teacher getTeacher(int id);
    
        Teacher getTeacherTwo(int id);
    
    }
  3. 編寫對應的mapper文件:

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.david.dao.TeacherDao">
    
        <!--一對多的處理-->
        <!--面向對象方式解決-->
        <select id="getTeacher" resultMap="TeacherStudent">
            select s.name sname,s.id sid,t.id tid, t.name tname
            from mybatis.student as s,mybatis.teacher as t
            where s.tid = t.id and t.id = #{id}
        </select>
        <resultMap id="TeacherStudent" type="Teacher">
            <result property="name" column="tname"/>
            <collection property="students" ofType="Student">
                <id property="id" column="sid"/>
                <result property="name" column="sname"/>
            </collection>
        </resultMap>
    
    
        <!--數據庫思想-->
        <select id="getTeacherTwo" resultMap="TeacherStudent2">
            select * from mybatis.teacher where id = #{id}
        </select>
        <resultMap id="TeacherStudent2" type="Teacher">
            <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="T2"/>
        </resultMap>
        <select id="T2" resultType="Student">
            select * from mybatis.student where tid = #{id}
        </select>
    
    </mapper>
  4. 編寫測試類:

    package com.david.dao;
    
    import com.david.pojo.Teacher;
    import com.david.utils.MyBatisUtils;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    
    public class TeacherDaoTest {
        @Test
        public void getTeacher(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherDao mapper = sqlSession.getMapper(TeacherDao.class);
            Teacher teacher = mapper.getTeacher(1);
    
            System.out.println(teacher.getName());
            System.out.println(teacher.getStudents());
    
        }
    
        @Test
        public void getTeacherTwo(){
            SqlSession sqlSession = MyBatisUtils.getSqlSession();
            TeacherDao mapper = sqlSession.getMapper(TeacherDao.class);
            Teacher teacher = mapper.getTeacherTwo(1);
    
            System.out.println(teacher.getName());
            System.out.println(teacher.getStudents());
    
        }
    }

動態SQL

動態SQL就是根據不一樣的查詢條件,生成不一樣的SQL語句

代碼測試

  1. 接口編寫:

    //模糊查詢,能夠經過自定義條件查詢
    List<User> getUserByLike(Map<String,Object> map);
  2. 映射文件的編寫:

    <select id="getUser" resultType="User">
        select * from mybatis.user
    </select>
    
    <select id="getUserByLike" resultType="User" parameterType="Map">
        select * from mybatis.user
        <where>
            <if test="name!=null">
                name like CONCAT('%',#{name},'%')
            </if>
            <if test="id!=null">
                and id = #{id}
            </if>
        </where>
    </select>
  3. 測試類:

    @Test
    public void getUserByLike(){
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
    
        Map<String,Object> map = new HashMap<String,Object>();
    
        map.put("name","俠");
        map.put("id",2);
    
        List<User> users = mapper.getUserByLike(map);
        for (User user : users) {
            System.out.println(user);
        }
    }

    太過複雜的邏輯不建議使用動態SQL,簡單的話能夠直接使用動態SQL實現

相關文章
相關標籤/搜索