mybatis學習日誌二

1、動態sql語句html

  1. if語句
  2. if+where語句
  3. if+set語句
  4. choose(when,otherwise)語句
  5. trim語句
  6. sql片斷
  7. foreach語句
  8. 總結

bean部分的User類代碼:java

public class User {
        private int id;
        private String name;
        private int age;//若是在if判斷中用null,則把int改爲Integer
        private String sex;
        private  List<Integer> ids;
}

dao部分的接口UserDao代碼:mysql

public interface UserDao {
     /**
      *  根據id查詢
      * @param id
      * @return
      */
    public User selectByWhere1(User user);
    public User selectByWhere2(User user);
    public User selectByWhere3(User user);
    /**
     * 添加
     * @param user
     */
    public void addUser(User user);
    /**
     * 刪除用戶
     * @param id
     */
    public void deleteByIds(User ids);
    public void delete(@Param("ids") List<Integer> ids);
    //調用其餘的類型要先設置key,Mybatis默認爲map
    public void deleteByIds2(User ids);
    /**
     * 更新用戶
     * @param user
     */
    public void updateUser(User user);
    
    
}

如下爲mapper.xml部分:git

1.if語句github

<!-- 根據name和sex來查詢數據。若是name爲空,那麼將只根據sex來查詢;反之只根據name來查詢
缺點:若是第二個條件知足,第一個條件不知足,那麼就會致使sql語句出錯
where 1=1 防止where後面什麼也沒有會報錯
-->sql

<select id="selectByWhere1" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
     select * from users  
          <if test="name!=null">
              where name=#{name}
          </if>
          <if test="sex!=null and sex!=''">
              and sex=#{sex}
          </if>
</select>

2.if+where 語句數據庫

<!-- 解決:若是第二個條件知足,第一個條件不知足,那麼就會致使sql語句出錯
if+where:若是第一個條件知足,則用where,並去掉where後的and
-->apache

<select id="selectByWhere2"  resultType="com.zhiyou100.xz.bean.User">
             select * from users 
         <where>
          <if test="name!=null">
              and name=#{name}
          </if>
          <if test="sex!=null and sex!=''">
              and sex=#{sex}
          </if>
         </where> 
</select>

3. if+set 語句api

 <!-- if+set:若是傳來的字段爲null,那麼保留原來的內容 -->
     <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
             update users
             <set>
                  <if test="name!=null">
                      name=#{name},
                  </if>
                   <if test="sex!=null and sex!=''">
                      sex=#{sex},
                   </if>
                   <if test="age>0">
                       age=#{age}
                   </if>
             </set>
             where id=#{id}
     </update>

4. choose(when,otherwise) 語句session

<!-- choose+where+otherwise -->
     <select id="selectByWhere3"  resultType="com.zhiyou100.xz.bean.User">
             select * from users 
         <where>
             <choose>
                  <when test="name!=null and name!=''">
                      name like concat('%',#{name},'%')
                  </when>
                  <when test="sex!=null and sex!=''">
                      sex=#{sex}
                  </when>
                  <otherwise>
                      age>=#{age}
                  </otherwise>
              </choose>
         </where> 
     </select>

5. trim 語句

<!-- trim -->
     <select id="selectByWhere2"  resultType="com.zhiyou100.xz.bean.User">
             select * from users 
         <trim prefix="where" prefixOverrides="and / or">
              <if test="name!=null">
                  and name=#{name}
              </if>
              <if test="sex!=null and sex!=''">
                  and sex=#{sex}
              </if>
         </trim> 
     </select>
<!-- trim -->
     <update id="updateUser" parameterType="com.zhiyou100.xz.bean.User">
             update users
             <!-- 
                 prefix:把trim中返回的字符串前添加一個set
                 prefixOverrides:覆蓋trim中返回的字符串的前綴爲and | or
                 suffix:把trim中返回的字符串後添加一個指定字符串
                 suffixOverrides:覆蓋trim中返回的字符串的前綴
              -->
             <trim prefix="set" suffixOverrides=",">
                  <if test="name!=null">
                      name=#{name},
                  </if>
                   <if test="sex!=null and sex!=''">
                      sex=#{sex},
                   </if>
                   <if test="age>0">
                       age=#{age}
                   </if>
             </trim>
             where id=#{id}
     </update>

6. SQL 片斷

<!-- sql片斷  -->
    <sql id="usercolumns">
       id,name,age,sex
    </sql>

<select id="selectByWhere1" parameterType="int" resultType="com.zhiyou100.xz.bean.User">
          select
          <!-- 引用相應的sql片斷  -->
          <include refid="usercolumns" /> 
             from users  
          <if test="name!=null">
              where name=#{name}
          </if>
          <if test="sex!=null and sex!=''">
              and sex=#{sex}
          </if>
    </select>

7. foreach 語句

<!-- delete from users where id in(?,?,?) -->
     <delete id="deleteByIds">
             delete from users where id in
             <!-- 
                 collection:表示要遍歷的集合名稱
                 open:以(做爲開始
                 close:以)做爲結束
                 separator:每一個元素之間使用,分割
                 item:每次遍歷的值賦值給的變量名
              -->
             <foreach collection="ids" open="(" close=")" separator="," item="id">
                     #{id}
             </foreach>
     </delete>
     <!-- delete from users where id=1 or id=4 or id=6 -->
     <delete id="delete">
             delete from users 
             <!-- 
                 collection:表示要遍歷的集合名稱
                 open:以(做爲開始
                 close:以)做爲結束
                 separator:每一個元素之間使用,分割
                 item:每次遍歷的值賦值給的變量名
                 這裏最好不要在foreach標籤中用open="where " 由於當id等於0時,作全表刪除時會報錯
              -->
              <where>
             <foreach collection="ids"  separator="or" item="id">
                     id=#{id}
             </foreach>
             </where>
     </delete>

8. 總結

其實動態 sql 語句的編寫每每就是一個拼接的問題,爲了保證拼接準確,咱們最好首先要寫原生的 sql 語句出來,而後在經過 mybatis 動態sql 對照着改,防止出錯。

2、逆向工程

經過前面的學習,在實際開發中,咱們基本上能對mybatis應用自如了,可是咱們發現了一個問題,全部操做都是圍繞着po類,xxxMapper.xml文件,xxxMapper接口等文件來進行的。若是實際開發中數據庫的表特別多,那麼咱們須要手動去寫每一張表的po類,xxxMapper.xml,xxxMapper.java文件,這顯然須要花費巨大的精力,並且可能因爲表字段太多,寫錯了而不知道也是可能的。

  因此咱們在實際開發中,通常使用逆向工程方式來自動生成所需的文件,如dao,bean,xml映射文件 。

http://www.mybatis.org/generator/index.html

 1.新建一個工程並導入jar包

 

注意:使用逆向工程時,最好新建一個工程,若是你在原來的工程中使用,那也能夠,可是有必定的風險,由於mybatis是根據配置文件中配置的路徑來生成的文件的,若是你工程中有相同名字的文件,那麼就會被新生成的文件所覆蓋。因此實際開發中,咱們通常新建一個工程,將生成的文件複製到本身的所需的工程中。

 2.建立generator.xml配置文件

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!-- mysql驅動jar所在的位置 -->
  <classPathEntry location="D:\\mysql\\mysql-connector-java-5.1.47.jar" />
    
    <!-- 數據源的信息 -->
  <context id="DB2Tables" targetRuntime="MyBatis3">
      <!-- 禁止全部註釋 -->
      <commentGenerator>
        <property name="suppressAllComments" value="true" />
    </commentGenerator>
    <jdbcConnection driverClass="com.mysql.jdbc.Driver"
        connectionURL="jdbc:mysql://localhost:3306/mybatis"
        userId="root"
        password="root">
    </jdbcConnection>

    <javaTypeResolver >
      <property name="forceBigDecimals" value="false" />
    </javaTypeResolver>
    <!-- 生產的實體類所在的位置 -->
    <javaModelGenerator targetPackage="com.zhiyou100.xz.bean" targetProject="./src">
      <property name="enableSubPackages" value="true" />
      <property name="trimStrings" value="true" />
    </javaModelGenerator>
    <!-- 生成的映射文件所在的位置 -->
    <sqlMapGenerator targetPackage="com.zhiyou100.xz.mapper"  targetProject="./resources">
      <property name="enableSubPackages" value="true" />
    </sqlMapGenerator>
    <!-- 生產的dao文件所在位置 -->
    <javaClientGenerator type="XMLMAPPER" targetPackage="com.zhiyou100.xz.dao"  targetProject="./src">
      <property name="enableSubPackages" value="true" />
    </javaClientGenerator>
    <!-- 某張表與實體類的對應關係
        schema:該表所在的數據庫
        tableName:表名
        domainObjectName:實體類名
     當須要多張表創建實體類時要創建多個table標籤
--> <table schema="mybatis" tableName="users" domainObjectName="Users" enableCountByExample="false" enableSelectByExample="false" enableUpdateByExample="false" enableDeleteByExample="false">
    <!--以Example結尾的屬性全爲false,是爲了減小生成複雜的方法 --> <property name="useActualColumnNames" value="true"/> <generatedKey column="ID" sqlStatement="DB2" identity="true" /> <columnOverride column="DATE_FIELD" property="startDate" /> <ignoreColumn column="FRED" /> <columnOverride column="LONG_VARCHAR_FIELD" jdbcType="VARCHAR" /> </table> </context> </generatorConfiguration>

注意:

  一、鏈接數據庫的配置,包括數據名稱,數據庫用戶名密碼等配置

  二、指定要生成代碼的包名,包括實體類po的包名,mapper的包名等

  三、指定數據庫中哪些表須要生成文件

3.運行主程序生成代碼

package com.zhiyou100.xz.test;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

public class Test {
      public static void main(String[] args) throws Exception{
          List<String> warnings = new ArrayList<String>();
           boolean overwrite = true;
           File configFile = new File("generator.xml");
           ConfigurationParser cp = new ConfigurationParser(warnings);
           Configuration config = cp.parseConfiguration(configFile);
           DefaultShellCallback callback = new DefaultShellCallback(overwrite);
           MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
           myBatisGenerator.generate(null);
    }
}

3、分頁查詢助手pagehelper

1.導入jar包

 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

 2.在mybatis工程下的conf.xml中配置PageHelper的攔截器插件

<!-- 
    plugins在配置文件中的位置必須符合要求,不然會報錯,順序以下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
    -->
    <plugins>
    <!-- com.github.pagehelper爲PageHelper類所在包名 -->
        <plugin interceptor="com.github.pagehelper.PageInterceptor">
            <!-- 使用下面的方式配置參數,後面會有全部的參數介紹 -->
            <property name="param1" value="value1"/>
        </plugin>
    </plugins>

3.先在UsersMapper.xml中寫出查詢全部的sql語句

 <resultMap id="BaseResultMap" type="com.zhiyou100.xz.bean.Users">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="NAME" jdbcType="VARCHAR" property="NAME" />
    <result column="age" jdbcType="INTEGER" property="age" />
    <result column="sex" jdbcType="VARCHAR" property="sex" />
  </resultMap>
  <sql id="Base_Column_List">
    id, NAME, age, sex
  </sql>
  <!-- 查詢全部 -->
  <select id="selectAll" resultMap="BaseResultMap">
          select <include refid="Base_Column_List" /> from users
  </select>

4.在接口UsersMapper中寫 出查詢全部的方法

package com.zhiyou100.xz.dao;

import java.util.List;

import com.zhiyou100.xz.bean.Users;

public interface UsersMapper {    
    //查詢全部用戶
    List<Users> selectAll();
}

5.測試運行,並在其中使用PageHelper類設置起始頁與每頁顯示的條數和用pageInfo進行查詢結果的封裝。

package com.test;


import java.io.Reader;
import java.util.ArrayList;
import java.util.List;

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 org.junit.jupiter.api.AfterAll;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zhiyou100.xz.bean.Users;
import com.zhiyou100.xz.dao.UsersMapper;

class TestMybatis {
    static SqlSession session=null; 
    final String str="com.zhiyou100.xz.mapper.UserMapper";
    static  UsersMapper usersMapper;
    @BeforeAll
    static void setUpBeforeClass() throws Exception {
        //解析配置文件conf.xml
                Reader reader=Resources.getResourceAsReader("conf.xml");
                //獲取SessionFactory對象
                SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(reader);
                
                //獲取Session對象,表示jdbc中connection,操做數據庫的
                session=sessionFactory.openSession();
                //獲得接口的實現類
                usersMapper=session.getMapper(UsersMapper.class);//至關於建立一個Dao對象
    }
    @Test
    void testSelectByPage() {

      // 1.使用PageHelper類設置起始頁和每頁顯示的條數
      int pageNum = 3;// 當前的頁碼 從網頁中能夠獲取
      int pageSize = 2;// pageSize:自定義
      PageHelper.startPage(pageNum, pageSize);

      // 2.調用查詢全部的方法
      List<Users> list = usersMapper.selectAll();
      System.out.println(list);
      // 3.把查詢的結果封裝到pageInfo對象中
      PageInfo<Users> pageInfo = new PageInfo<>(list,3);
      System.out.println(pageInfo);
      //pageInfo.setNavigatePages(2);//setNavigatePages 設置每頁顯示的頁碼個數,這裏這個屬性沒起做用
      System.out.println("總頁碼:"+pageInfo.getPages());
      System.out.println("當前頁:"+pageInfo.getPageNum());
      System.out.println("上一頁:"+pageInfo.getPrePage());
      int[] pages=pageInfo.getNavigatepageNums();//getNavigatepageNums顯示頁碼的具體頁數
      for(int p:pages) {
      System.out.print(p+"\t");
      }
      System.out.println("下一頁:"+pageInfo.getNextPage());
      List<Users> users=pageInfo.getList();
      for(Users users2:users) {
      System.out.println(users2);
      }

    }
    @AfterAll
    static void tearDownAfterClass() throws Exception {
        session.commit();//提交數據   事物管理:要麼都執行,要麼都不執行
    }


}

 6.對pageInfo對象中各個屬性的解釋

PageInfo{pageNum=3,<!--當前頁碼 -->
pageSize=2,<!--每頁顯示的條數 -->
size=2,<!--該頁的實際條數 -->
startRow=5,<!--從第幾條開始 -->
endRow=6, total=8,<!--到第幾條結束 -->
pages=4,<!-- 總共的頁數-->
list=Page{count=true, pageNum=3, pageSize=2, startRow=4, endRow=6,
total=8, pages=4,
reasonable=false, pageSizeZero=false}
[Users [id=5,
NAME=孔妖精, age=18,
sex=小妖精], Users [id=10, NAME=孔妖精, age=20, sex=騷妖精]],<!--當前頁的數據 -->
prePage=2,<!--上一頁 -->
nextPage=4,<!--下一頁 -->
isFirstPage=false, <!--是否爲第一頁 -->
isLastPage=false, hasPreviousPage=true,
hasNextPage=true,
navigatePages=8,<!--每頁顯示的頁碼個數 -->
navigateFirstPage=1,
navigateLastPage=4, navigatepageNums=[1, 2, 3, 4]}<!--顯示頁碼的具體頁數 -->
相關文章
相關標籤/搜索