Mybatis01-MyBatis快速入門

来源:https://www.cnblogs.com/hanlu0516/archive/2018/11/25/10016969.html
-Advertisement-
Play Games

一、MyBatis MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。 iBATIS一詞來源於“internet”和“ ...


一、MyBatis

MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。

iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。iBATIS提供的持久層框架包括SQL Maps和Data Access Objects(DAOs)

MyBatis 是一款優秀的持久層框架,它支持定製化 SQL、存儲過程以及高級映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動設置參數以及獲取結果集。MyBatis 可以使用簡單的 XML 或註解來配置和映射原生信息,將介面和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對象)映射成資料庫中的記錄。

1.1、 MyBatis 的特點

簡單易學:本身就很小且簡單。沒有任何第三方依賴,最簡單安裝只有兩個jar文件+配置幾個sql映射文件易於學習,易於使用,通過文檔和源代碼,可以比較完全的掌握它的設計思路和實現。

靈活:mybatis不會對應用程式或者資料庫的現有設計加強任何影響。sql寫在xml里,便於統一管理和優化。通過sql基本上可以實現我們不使用數據訪問框架可以實現的所有功能,或許更多。

解除sql與程式代碼的耦合:通過提供DAO層,將業務邏輯和數據訪問邏輯分離,使系統的設計更清晰,更易維護,更易單元測試。sql和代碼的分離,提高了可維護性。

提供映射標簽,支持對象與資料庫的ORM欄位關係映射

提供對象關係映射標簽,支持對象關係組建維護

提供XML標簽,支持編寫動態sql。

1.2、MyBatis工作流程

(1)、載入配置並初始化

觸發條件:載入配置文件

配置來源於兩個地方,一處是配置文件,一處是Java代碼的註解,將SQL的配置信息載入成為一個個MappedStatement對象(包括了傳入參數映射配置、執行的SQL語句、結果映射配置),存儲在記憶體中。

(2)、接收調用請求

觸發條件:調用Mybatis提供的API

傳入參數:為SQL的ID和傳入參數對象

處理過程:將請求傳遞給下層的請求處理層進行處理。

(3)、處理操作請求 觸發條件:API介面層傳遞請求過來

傳入參數:為SQL的ID和傳入參數對象

處理過程:
  (A)根據SQL的ID查找對應的MappedStatement對象。

  (B)根據傳入參數對象解析MappedStatement對象,得到最終要執行的SQL和執行傳入參數。

  (C)獲取資料庫連接,根據得到的最終SQL語句和執行傳入參數到資料庫執行,並得到執行結果。

  (D)根據MappedStatement對象中的結果映射配置對得到的執行結果進行轉換處理,並得到最終的處理結果。

  (E)釋放連接資源。

(4)、返回處理結果將最終的處理結果返回。

無論是用過的hibernate,mybatis,你都可以法相他們有一個共同點:

在java對象和資料庫之間有做mapping的配置文件,也通常是xml 文件

從配置文件(通常是XML配置文件中)得到 SessionFactory

由SessionFactory 產生 Session

在Session中完成對數據的增刪改查和事務提交等

在用完之後關閉Session

1.3、MyBatis架構

Mybatis的功能架構分為三層:

API介面層:提供給外部使用的介面API,開發人員通過這些本地API來操縱資料庫。介面層一接收到調用請求就會調用數據處理層來完成具體的數據處理。

數據處理層:負責具體的SQL查找、SQL解析、SQL執行和執行結果映射處理等。它主要的目的是根據調用的請求完成一次資料庫操作。

基礎支撐層:負責最基礎的功能支撐,包括連接管理、事務管理、配置載入和緩存處理,這些都是共用的東西,將他們抽取出來作為最基礎的組件。為上層的數據處理層提供最基礎的支撐。

1.4、MyBatis的主要成員如層次結構

主要成員:

Configuration:MyBatis所有的配置信息都保存在Configuration對象之中,配置文件中的大部分配置都會存儲到該類中

SqlSession:作為MyBatis工作的主要頂層API,表示和資料庫交互時的會話,完成必要資料庫增刪改查功能

Executor:MyBatis執行器,是MyBatis 調度的核心,負責SQL語句的生成和查詢緩存的維護

StatementHandler:封裝了JDBC Statement操作,負責對JDBC statement 的操作,如設置參數等

ParameterHandler:負責對用戶傳遞的參數轉換成JDBC Statement 所對應的數據類型

ResultSetHandler:負責將JDBC返回的ResultSet結果集對象轉換成List類型的集合

TypeHandler:負責java數據類型和jdbc數據類型(也可以說是數據表列類型)之間的映射和轉換

MappedStatement:MappedStatement維護一條<select|update|delete|insert>節點的封裝

SqlSource:負責根據用戶傳遞的parameterObject,動態地生成SQL語句,將信息封裝到BoundSql對象中,並返回

BoundSql:表示動態生成的SQL語句以及相應的參數信息

層次結構:

1.5、學習資源

mybatis3中文幫助:http://www.mybatis.org/mybatis-3/zh/index.html

mybatis-spring:http://www.mybatis.org/spring/zh/index.html

MyBatis中國分站:http://www.mybatis.cn/

源代碼:https://github.com/mybatis/mybatis-3/

二、MyBatis 快速入門示例

2.1、在IDEA中創建項目

普通java項目或者是Maven項目都可以,如下圖所示:

2.2、添加依賴

下載地址:https://github.com/mybatis/mybatis-3/releases

MyBatis

         mybatis-3.4.6.jar

【MYSQL驅動包】
    mysql-connector-java-5.1.38-bin.jar

   

Maven POM

<?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.hmy.mybatis02</groupId>
    <artifactId>Mybatis02</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--MyBatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!--MySql資料庫驅動 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.38</version>
        </dependency>
        <!-- JUnit單元測試工具 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.10</version>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

3、創建資料庫和表,針對MySQL資料庫

CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(10) NOT NULL,
  `sex` enum('boy','girl','secret') DEFAULT 'secret',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;

將SQL腳本在MySQL資料庫中執行,完成創建資料庫和表的操作,如下:

  

表中的數據如下:

2.3、添加Mybatis配置文件

在Resources目錄下創建一個conf.xml文件,如下圖所示:

conf.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>
    <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/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/studentMapper.xml"/>
    </mappers>
</configuration>

解釋

2.4、定義表所對應的實體類

Student實體類的代碼如下:

package com.hanlu.mybatis02.entities;


public class Student {

  private int id;
  private String name;
  private String sex;


  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 getSex() {
    return sex;
  }

  public void setSex(String sex) {
    this.sex = sex;
  }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", sex='" + sex + '\'' +
                '}';
    }
}

2.5、定義操作Student表的sql映射文件

在resources目錄下創建一個mapper目錄,專門用於存放sql映射文件,在目錄中創建一個studentMapper.xml文件,如下圖所示:

studentMapper.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,namespace的值習慣上設置成包名+sql映射文件名,這樣就能夠保證namespace的值是唯一的
例如namespace="com.hanlu.mybatis02.dao.studentMapper"就是com.hanlu.mybatis02.dao(包名)+studentMapper(studentMapper.xml文件去除尾碼)
-->
<mapper namespace="com.hanlu.mybatis02.dao.studentMapper">
    <!-- 在select標簽中編寫查詢的SQL語句, 設置select標簽的id屬性為selectStudentById,id屬性值必須是唯一的,不能夠重覆
 使用parameterType屬性指明查詢時使用的參數類型,resultType屬性指明查詢返回的結果集類型
resultType="com.hanlu.mybatis02.entities.Student"就表示將查詢結果封裝成一個Student類的對象返回
Student類就是student表所對應的實體類
-->
    <!-- 
    根據id查詢得到一個user對象
 -->
    <select id="selectStudentById" resultType="com.hanlu.mybatis02.entities.Student">
        select * from student where id = #{id}
    </select>
</mapper>

解釋

參考:https://www.cnblogs.com/hellokitty1/p/5216025.html

2.6、在配置文件中註冊映射文件

在配置文件conf.xml中註冊studentMapper.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>
    <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/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <!-- 註冊studentMapper.xml文件studentMapper.xml位於mapper這個目錄下,所以resource寫成mapper/studentMapper.xml-->
        <mapper resource="mapper/studentMapper.xml"/>
    </mappers>
</configuration>

2.7、編寫數據訪問類

StudentDao.java,執行定義的select語句

package com.hanlu.mybatis02.dao;

import com.hanlu.mybatis02.entities.Student;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class StudentDao {

    public Student getStudentById(int id){
        //使用類載入器載入mybatis的配置文件(它也載入關聯的映射文件)
        InputStream stream=StudentDao.class.getClassLoader().getResourceAsStream("conf.xml");
        //構建sqlSession的工廠
        SqlSessionFactory ssf=new SqlSessionFactoryBuilder().build(stream);
        //使用MyBatis提供的Resources類載入mybatis的配置文件(它也載入關聯的映射文件)
        //Reader reader = Resources.getResourceAsReader(resource);
        //構建sqlSession的工廠
        //SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
        
        //創建能執行映射文件中sql的sqlSession
        SqlSession session=ssf.openSession();
        /**
         * 映射sql的標識字元串,
         * com.hanlu.mybatis02.dao.studentMapper是studentMapper.xml文件中mapper標簽的namespace屬性的值,
         * selectStudentById是select標簽的id屬性值,通過select標簽的id屬性值就可以找到要執行的SQL
         */
        Student student=session.selectOne("com.hanlu.mybatis02.dao.studentMapper.selectStudentById",1);
        return student;
    }

    public static void main(String[] args) {
        StudentDao dao=new StudentDao();
        Student student=dao.getStudentById(1);
        System.out.println(student);
    }
}

執行過程解釋:

 

1、mybatis配置

SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運行環境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作資料庫的sql語句。此文件需要在SqlMapConfig.xml中載入。

2、通過mybatis環境等配置信息構造SqlSessionFactory即會話工廠

3、由會話工廠創建sqlSession即會話,操作資料庫需要通過sqlSession進行。

4、mybatis底層自定義了Executor執行器介面操作資料庫,Executor介面有兩個實現,一個是基本執行器、一個是緩存執行器。

5、Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應一個Mapped Statement對象,sql的id即是Mapped statement的id。

6、Mapped Statement對sql執行輸入參數進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql前將輸入的java對象映射至sql中,輸入參數映射就是jdbc編程中對preparedStatement設置參數。

7、Mapped Statement對sql執行輸出結果進行定義,包括HashMap、基本類型、pojo,Executor通過Mapped Statement在執行sql後將輸出結果映射至java對象中,輸出結果映射過程相當於jdbc編程中對結果的解析處理過程。

參考:https://www.cnblogs.com/selene/p/4604605.html

2.8、編寫單元測試

import com.hanlu.mybatis02.dao.StudentDao;
import com.hanlu.mybatis02.entities.Student;
import org.junit.Test;
import org.junit.Before;
import org.junit.After;


public class StudentDaoTest {

    @Before
    public void before() throws Exception {
    }

    @After
    public void after() throws Exception {
    }

    /**
     * Method: getStudentById(int id)
     */
    @Test
    public void testGetStudentById() throws Exception {
        StudentDao dao=new StudentDao();
        Student student=dao.getStudentById(1);
        System.out.println(student);
    }


}

測試結果:

2.9、IDEA中Junit插件與生成測試類位置

打開IntelliJ IDEA工具,Alt+Ctrl+S,打開設置視窗,點擊進入Plugins。

從插件資源庫中搜索JunitGenerator V2.0版本

安裝此插件,重啟IDEA就可以了。

現在可通過此工具自動完成test類的生成了,在需要進行單元測試的類中按 Alt+Insert

選中你要創建測試用例的方法即可。

IntelliJ IDEA JUnit Generator自動創建測試用例到指定test目錄

1.打開File->Settings

2.搜索junit,找到JUnit Generator

3.Properties選項卡裡的Output Path為測試用例生成的目錄,修改為test目錄:

SOURCEPATH/../../test/java/SOURCEPATH/../../test/java/{PACKAGE}/${FILENAME}

4.切換到JUnit 4選項卡,可以修改生成測試用例的模板,比如類名、包名等

修改生成位置:

修改模板文件:

測試類生成目錄分析:

${SOURCEPATH}/test/${PACKAGE}/${FILENAME}
$SOURCEPATH/../../test/java/{PACKAGE}/${FILENAME}

 

對應的目錄結構為

${SOURCEPATH}是到src/main/java這一層

../是退到上一層目錄的意思,對著圖理解一下

三、基於XML映射實現完整數據訪問

MyBatis可以使用XML或註解作為映射器的描述,XML強大且可以解偶,註解方便且簡單。

因為每一個操作都需要先拿到會話,這裡先定義一個工具類以便復用:

會話工具類:

 

package com.hanlu.mybatis02.utils;

import com.hanlu.mybatis02.dao.StudentDao;
import com.hanlu.mybatis02.entities.Student;
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;

/**
 * @author HMY
 * @date 2018/10/17-17:07
 */

/**
 * MyBatis 會話工具類
 * */
public class SqlSessionFactoryUtil {

/**
     * 獲得會話工廠
     *
     * */
    public static SqlSessionFactory getFactory(){

        InputStream inputStream=null;
        SqlSessionFactory sqlSessionFactory=null;
        try {
            //載入conf.xml配置文件,轉換成輸入流
            inputStream= StudentDao.class.getClassLoader().getResourceAsStream("conf.xml");
            //根據配置文件的輸入流構造一個SQL會話工廠
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        }finally {
            if (inputStream!=null){
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return sqlSessionFactory;
    }

    /**
     * 獲得sql會話,是否自動提交
     * */
    public static SqlSession openSession(boolean isAutoCommit){
        return getFactory().openSession(isAutoCommit);
    }
    
    /**
     * 關閉會話
     * */
    public static void closeSession(SqlSession session){
        if (session!=null){
            session.close();
        }
    }

}
            

XML映射器studentMapper:

<?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="com.hanlu.mybatis02.studentMapper">

    <select id="selectStudentById" resultType="student">
        select id,name,sex from student where id = #{id}
    </select>

    <select id="selectStudentByName" parameterType="String" resultType="Student">
        select id,name,sex from student where name LIKE '%${value}%'
    </select>

    <insert id="insertStudent" parameterType="student">
        insert into student(name,sex) values (#{name},#{sex})
    </insert>

    <update id="updateStudent" parameterType="student">
        UPDATE student SET name=#{name},sex=#{sex} WHERE id=#{id}
    </update>

    <delete id="deleteStudent" parameterType="int">
        DELETE FROM student WHERE id=#{id}
    </delete>
</mapper>

數據訪問類StudentDao.java:

package com.hanlu.mybatis02.dao;

import com.hanlu.mybatis02.entities.Student;
import com.hanlu.mybatis02.utils.SqlSessionFactoryUtil;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;
import java.util.List;

/**
 * @author HMY
 * @date 2018/10/17-10:20
 */
public class StudentDao implements StudentMapper {

    
    public Student selectStudentById(int id) {
        Student entity = null;

        /* //載入conf.xml配置文件,轉換成輸入流
        InputStream inputStream=StudentDao.class.getClassLoader().getResourceAsStream("conf.xml");

        //根據配置文件的輸入流構造一個SQL會話工廠
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);

        //打開一個會話
        SqlSession session = sqlSessionFactory.openSession();*/

        //打開一個會話
        SqlSession session = SqlSessionFactoryUtil.openSession(true);

        //查詢單個對象
        entity = session.selectOne("com.hanlu.mybatis02.studentMapper.selectStudentById", id);

        //關閉會話
        SqlSessionFactoryUtil.closeSession(session);

        return entity;
    }

    public List<Student> selectStudentByName(String name) {
        /*InputStream inputStream=StudentDao.class.getClassLoader().getResourceAsStream("conf.xml");
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session=sqlSessionFactory.openSession();*/

        SqlSession session = SqlSessionFactoryUtil.openSession(true);

        List<Student> list = session.selectList("com.hanlu.mybatis02.studentMapper.selectStudentByName", name);

        SqlSessionFactoryUtil.closeSession(session);

        return list;
    }

    public int insertStudent(Student student) {
        int rows = 0;
        SqlSession session = SqlSessionFactoryUtil.openSession(true);
        rows = session.insert("com.hanlu.mybatis02.studentMapper.insertStudent", student);
        SqlSessionFactoryUtil.closeSession(session);
        return rows;
    }

    public int updateStudent(Student student) {
        int rows = 0;
        SqlSession session = SqlSessionFactoryUtil.openSession(true);
        rows = session.update("com.hanlu.mybatis02.studentMapper.updateStudent", student);
        SqlSessionFactoryUtil.closeSession(session);
        return rows;
    }

    public int deleteStudent(int id) {
        int rows = 0;
        SqlSession session = SqlSessionFactoryUtil.openSession(true);
        rows = session.delete("com.hanlu.mybatis02.studentMapper.updateStudent", id);
        SqlSessionFactoryUtil.closeSession(session);
        return rows;
    }

}
    

單元測試:

package com.hanlu.mybatis02.dao; 

import com.hanlu.mybatis02.entities.Student;
import org.junit.Assert;
import org.junit.Test;
import org.junit.Before; 
import org.junit.After;

import java.util.List;

/** 
* StudentDao Tester. 
* 
* @author <Authors name> 
* @since <pre>ʮ�� 17, 2018</pre> 
* @version 1.0 
*/ 
public class StudentDaoTest { 
StudentDao dao;
@Before
public void before() throws Exception {
    dao=new StudentDao();
} 

@After
public void after() throws Exception { 
} 

/** 
* 
* Method: selectStudentById(int id) 
* 
*/ 
@Test
public void testSelectStudentById() throws Exception { 
//TODO: Test goes here... 
} 

/** 
* 
* Method: selectStudentByName(String name) 
* 
*/ 
@Test
public void testSelectStudentByName() throws Exception {

    List<Student> list=dao.selectStudentByName("i");
    System.out.println(list);
    Assert.assertNotNull(list);
} 
@Test
public void testInsertStudent() throws Exception {

    Student student=new Student();
    student.setName("瑪麗");
    student.setSex("girl");
    Assert.assertEquals(1,dao.insertStudent(student));
}

@Test
public void testUpdateStudent() throws Exception {

    Student student=dao.selectStudentById(5);
    student.setSex("boy");
    student.setName("Mario");
    Assert.assertEquals(1,dao.updateStudent(student));
}


} 

參考映射文件1:

<?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介面的全限定名一致 -->
<mapper namespace="com.san.mapper.UserMapper">

    <!-- 通過ID查詢用戶 -->
    <select id="findUserById" parameterType="int" resultType="user">
        select * from user where id=#{id}
    </select>

    <!-- 定義sql片段 -->
    <!-- sql片段內,可以定義sql語句中的任何內容 -->
    <!-- sql片段內,最好不要使用where和select關鍵字聲明在內 -->
    <sql id="whereClause">
        <!-- if標簽:對輸入的參數進行判斷 -->
        <!-- test標簽:指定判斷的表達式 -->
        <if test="user!=null">
            <!-- 判斷用戶名不為空 -->
            <if test="user.username!=null and user.username!=''">
                and username like '%${user.username}%'
            </if>

            <!-- 判斷性別不為空 -->
            <if test="user.sex!=null and user.sex!=''">
                and sex=#{user.sex}
            </if>
        </if>

        <!-- 判斷集合 -->
        <!-- collection:表示pojo中集合屬性的屬性名稱 -->
        <!-- item:為遍歷出的結果聲明一個變數名稱 -->
        <!-- open:遍歷開始時,需要拼接的字元串 -->
        <!-- close:遍歷結束時,需要拼接的字元串 -->
        <!-- separator:遍歷中間需要拼接的字元串 -->
        <if test="idList!=null">
            and id in
            <	   

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • bat處理文件 (一)定義 bat處理文件就是可以一次性執行多個命令的文件。 (二)編寫步驟 只需要打開一個文本文件,將所要執行的命令寫入其中,然後將文件的尾碼改為.bat即可 (三)bat處理文件的常用命令 pause 讓當前控制台停留 echo 向控制台輸出指定內容 echo off 隱藏ech ...
  • Java開發學習心得(一):SSM環境搭建 有一點.NET的開發基礎,在學校學過基礎語法,對JAVA有點興趣,就簡單學習了一下,記錄一下從哪些方面入手的,暫時不打算深入到原理方面,先簡單搭下環境看看,所以有些地方可能講得不慎準確。 1 SSM框架 從網上的討論來看,SSM框架似乎正在慢慢被Sprin ...
  • 1. 帶著問題去閱讀 為什麼說ConcurrentHashMap是線程安全的?或者說 ConcurrentHashMap是如何防止併發的? 2. 欄位和常量 首先,來看一下ConcurrentHashMap中的一些欄位和常量,這些在接下來的操作中會用得到 2.1. 常量 從中,我們可以獲得以下信息: ...
  • a) 一個整型數(An integer) b) 一個指向整型數的指針(A pointer to an integer) c) 一個指向指針的的指針,它指向的指針是指向一個整型數(A pointer to a pointer to an integer) d) 一個有10個整型數的數組(An arra ...
  • 整理了下阿裡近幾年的java面試題目,大家參考下吧,希望對大家有幫助,可以幫大家查漏補缺。 答對以下這些面試題,可以淘汰掉 80 % 的求職競爭者。 1.hashcode相等兩個類一定相等嗎?equals呢?相反呢? 2.介紹一下集合框架? 3.hashmap hastable 底層實現什麼區別?h ...
  • 1.安裝第三方庫(matplotlib,jieba,wordcloud,numpy) 1.1安裝方法:pip命令線上安裝(python3.x預設安裝了pip,pip下載地址:https://pypi.python.org/pypi/pip#downloads) 已經配置好環境變數前提下,在cmd視窗 ...
  • 一、subprocess 註:如果是Windows,那麼res.stdout.read()讀出的是GBK編碼的信息,在接收端需要用GBK解碼且只能從管道里讀一次結果,PIPE稱為管道。 二、粘包現象 1. TCP會粘包,UDP永遠不會粘包 發送端可以是一K一K地發送數據,而接收端的應用程式可以兩K兩 ...
  • 1. 創建一個Maven的項目,我的項目結構如下: 2. 在pom文件里寫下需要導入的依賴: 3. 在Java文件夾下新建package,在package包下新建介面及其實現類 介面: 實現類: 4. 在resources目錄下新建 文件 我們需要在spring容器的配置文件中進行註冊該Bean s ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...