04.SSM框架集~Mybatis(二)

04.SSM框架集~Mybatis(二)

本文是上一篇文章的後續,詳情點擊該鏈接

       在上一篇文章中,我們簡單介紹了一下Mybatis,和Mybatis的最基本使用。那麼今天我們就來學習一下Mybatis基於代理模式的開發和動態SQL

Mapper代理:

       前面已經使用Mybatis完成了對Student表的最基本操作,實現了MyBatis的入門。

但是卻存在如下缺點:

       1:不管是selectList()、selectOne()、selectMap(),都是通過SQLSession對象的API完成增刪改查,都只能提供一個查詢參數。如果要多個參數,需要封裝到JavaBean或者Map中,並不一定永遠是一個好辦法。

       2:返回值類型較固定

       3:只提供了映射文件,沒有提供數據庫操作的接口,不利於後期的維護擴展。在MyBatis中提供了另外一種成爲Mapper代理(或稱爲接口綁定)的操作方式。在實際開發中也使用該方式。

       下面我們就是要Mapper代理的方式來實現對Student表的CRUD操作吧。相比而言,增加了接口StudentMapper。但是卻會引起映射文件和測試類的變化。

首先我們回到mybatis.xml,修改配置
    <mappers>
        <!--  通過包掃描的形式加載所有的接口和映射文件  -->
        <package name="com.alvin.mapper"/>
    </mappers>

       這樣一來,不管將來新增了多少個mapper映射文件,只要都在這個包下,就無需重複去寫

       (關於SqlSessionUtil類以及一些配置和jar包,詳情請點擊最上方鏈接,看我上一篇文章的內容。)

優點:

       有接口 模塊之間有規範了

       參數的處理多樣了,接口中的方法參數列表由我們自己決定

       通過代理模式由mybatis提供接口的實現類對象 我們不用寫實現類了

使用Mapper代理方式實現查詢

       需求:查詢全部學生信息

準備接口和mapper映射文件
public interface StudentMapper {
    //查詢全部學生信息
    List<Student> FindAll();
}
<?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.alvin.mapper.StudentMapper">
    <!--  這裏的id必須和對應的方法名相同  -->
    <select id="FindAll" resultType="student">
        select * from student;
    </select>
</mapper>

       接口的名字必須和映射文件名字相同!

public class Test {
    public static void main(String[] args){
        //查詢全部學生信息
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        // 幫助我們生成一個接口下的實現類對象的
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 接收數據
        List<Student> list = studentMapper.FindAll();
        //關閉sqlSession
        sqlSession.close();
        //遍歷結果
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }
}

關於Mapper代理的增刪查改操作

創建好接口:
public interface StudentMapper {
    //查詢全部學生信息
    List<Student> FindAll();

    //增加學生信息
    int Insert(Student student);

    //刪除學生信息
    int delete(String son);

    //修改學生信息
    int change(Student student);
    
    //查詢單個學生信息
    Student FindByOn(String son);
}

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="com.alvin.mapper.StudentMapper">
    <!--  這裏的id必須和對應的方法名相同  -->
    <select id="FindAll" resultType="student">
        select * from student;
    </select>

    <!--  增,刪,改 返回值默認爲int,所以這裏就沒有resultType參數  -->
    <insert id="Insert">
                                <!--  這裏的參數名建議最好和實體類裏面的變量對應! -->
        insert into student value(#{son},#{realname},#{password},#{classname},#{score});
    </insert>

    <!--  修改學生信息 -->
    <update id="change">
        update student  set realname = #{realname}, password = #{password},classname = #{classname},score = #{score} where son = #{son};
    </update>

    <!--  刪除學生信息 -->
    <delete id="delete">
        delete from student where son = #{son}
    </delete>

    <!--  查找學生信息 -->
    <select id="FindByOn" resultType="student">
        select * from student where son = #{son};
    </select>

</mapper>

Java代碼
public class Test {
    public static void main(String[] args){
        //Insert();
       // Del();
        //FindAll();
        //Update();
        Find();
    }

    //查詢全部學生信息
    public static void FindAll(){
        //查詢全部學生信息
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        // 幫助我們生成一個接口下的實現類對象的
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        // 接收數據
        List<Student> list = studentMapper.FindAll();
        //關閉sqlSession
        sqlSession.close();
        //遍歷結果
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

    //新增學生信息
    public static void Insert(){
                                    //當執行增刪改時,就需要提交True,否則無法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //需要新增的信息
        Student student = new Student("666666","黃貴根","666666","信息工程學院",533.0);
        //調用新增
        int n = studentMapper.Insert(student);
        //關閉sqlSession
        sqlSession.close();
        //處理結果
        String str = n > 0 ? "新增成功!" : "新增失敗!";
        System.out.println(str);
    }

    //修改學生信息
    public static void Update(){
        //當執行增刪改時,就需要提交True,否則無法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //需要修改的信息
        Student student = new Student("666666","黃貴根","123456","信息工程學院",600.0);
        //調用修改
        int n = studentMapper.change(student);
        //關閉sqlSession
        sqlSession.close();
        //處理結果
        String str = n > 0 ? "修改成功!" : "修改失敗!";
        System.out.println(str);
    }

    //刪除學生信息
    public static void Del(){
        //當執行增刪改時,就需要提交True,否則無法完成操作!
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //調用刪除
        int n = studentMapper.delete("666666");
        //關閉sqlSession
        sqlSession.close();
        //處理結果
        String str = n > 0 ? "刪除成功!" : "刪除失敗!";
        System.out.println(str);
    }

    //查找學生信息
    public static void Find(){
        //查詢操作則無需提交
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        //調用查詢
        Student student  = studentMapper.FindByOn("154787");
        //關閉sqlSession
        sqlSession.close();
        //處理結果
        String str = student != null ? student.toString() : "沒找到!";
        System.out.println(str);
    }
}

模糊查詢:

接口:
    //模糊查詢
    List<Student> getByName( String realname);
Mapper映射
   <!-- 模糊查詢  -->
    <select id="getByName"  resultType="student" >
        select * from student where realname like concat('%',#{realname},'%')
    </select>
Java代碼
public static void main(String[] args) {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        //查詢姓名包含張的學生
        List<Student> students = mapper.getByName("張");
        //遍歷
        Iterator iterator = students.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
        sqlSession.close();
    }

       好了,關於Mapper代理這一塊的基本知識,暫時先學到這裏,現在讓我們來了解一下動態SQL

動態SQL

       經常遇到很多按照很多查詢條件進行查詢的情況,比如智聯招聘的職位搜索,比如OA系統中的支出查詢等。其中經常出現很多條件不取值的情況,在後臺應該如何完成最終的SQL語句呢?

       如果採用JDBC進行處理,需要根據條件是否取值進行SQL語句的拼接,一般情況下是使用StringBuilder類及其append方法實現,還是有些繁瑣的。如果你有使用 JDBC 或其它類似框架的經驗,你就能體會到根據不同條件拼接 SQL語句的痛苦。例如拼接時要確保不能忘記添加必要的空格,還要注意去掉列表最後一個列名的逗號。利用動態 SQL 這一特性可以徹底擺脫這種痛苦。

       MyBatis在簡化操作方法提出了動態SQL功能,將使用Java代碼拼接SQL語句,改變爲在XML映射文件中截止標籤拼接SQL語句。相比而言,大大減少了代碼量,更靈活、高度可配置、利於後期維護。

       MyBatis中動態SQL是編寫在mapper.xml中的,其語法和JSTL類似,但是卻是基於強大的OGNL表達式實現的。

       MyBatis也可以在註解中配置SQL,但是由於註解功能受限,尤其是對於複雜的SQL語句,可讀性很差,所以較少使用。

Where和IF標籤

       通過if處理用戶多變的查詢條件

接口
public interface StudentMapper {
	//登錄實現
    Student Login(Student student);
}
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="com.alvin.mapper.StudentMapper">
    <select id="Login" resultType="student">

        select * from student
        <where>
            <if test="son != null">
                and son= #{son}
            </if>
            <if test="realname != null and realname != ''">
                and realname= #{realname}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
            <if test="classname != null ">
                and classname = #{classname}
            </if>
            <if test="score != null ">
                and score = #{score}
            </if>
        </where>
    </select>
</mapper>
Java代碼
public static void Login(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student();
        //輸入賬號和密碼
        student.setSon("666666");
        student.setPassword("666666");
        Student stu = mapper.Login(student);
        //處理結果
        String string = stu != null ? "登陸成功!歡迎您: " + stu.getRealname() : "登陸失敗!";
        System.out.println(string);
    }

Choose When標籤

在剛剛的標籤裏面進行修改

<?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.alvin.mapper.StudentMapper">
    <select id="Login" resultType="student">

        select * from student
        <where>
        <choose>
                <when test="son != null">
                    and son= #{son}
                </when>
                <when test="realname != null and realname != ''">
                    and realname= #{realname}
                </when>
                <when test="password != null and password != ''">
                    and password = #{password}
                </when>
                <when test="classname != null ">
                    and classname = #{classname}
                </when>
                <when test="score != null ">
                    and score = #{score}
                </when>
        </choose>
        </where>
    </select>
</mapper>

       特點:前面的when條件成立 後面的 when就不再判斷了

Set標籤

修改案例

接口
 int update(Student student);
Mapper映射
 <update id="update" >
        update student
        <set>
            <if test="realname != null and realname != ''">
                realname= #{realname},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="classname != null ">
                classname = #{classname},
            </if>
            <if test="score != null ">
                score = #{score},
            </if>
        </set>
        where  son = #{son}
    </update>
Java
public static void Update(){
        SqlSession sqlSession = SqlSessionUtil.getSqlSession(true);
        StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
        Student student = new Student();
        //修改後的數據
        Student stu = new Student("666666","黃貴根","654321","信息工程學院",666.0);
        int n = mapper.update(stu);
        //處理結果
        String string = n > 0 ? "修改成功!" : "修改失敗!";
        System.out.println(string);
        //關閉
        sqlSession.close();
    }

Trim標籤

處理set

<update id="update" >
        <!--prefix      要增加什麼前綴
        prefixOverrides 要去除什麼前綴
        suffix          要增加什麼後綴
        suffixOverrides 要去除什麼後綴
        set 和where是   trim的一種特殊情況
        -->
        update student
        <trim prefix="set" suffixOverrides=",">
            <if test="realname != null and realname != ''">
                realname= #{realname},
            </if>
            <if test="password != null and password != ''">
                password = #{password},
            </if>
            <if test="classname != null ">
                classname = #{classname},
            </if>
            <if test="score != null ">
                score = #{score},
            </if>
        </trim>
        where  son = #{son}
    </update>
處理where
    <select id="Login" resultType="student">
        select * from student
        <trim prefix="where" prefixOverrides="and">
            <if test="son != null">
                and son= #{son}
            </if>
            <if test="realname != null and realname != ''">
                and realname= #{realname}
            </if>
            <if test="password != null and password != ''">
                and password = #{password}
            </if>
            <if test="classname != null ">
                and classname = #{classname}
            </if>
            <if test="score != null ">
                and score = #{score}
            </if>
        </trim>
    </select>

Sql片段標籤

案例: 根據指定字段查詢

接口
    List<Student> FindAll();
Mapper
    <!--  將字段包含 -->
    <sql id="data">
        son,realname,password,classname,score
    </sql>
    <!--  調用 -->
    <select id="FindAll" resultType="student">
        select <include refid="data"/> from student;
    </select>

Java

    public static void main(String[] args) {
        SqlSession sqlSession = SqlSessionUtil.getSqlSession();
        StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
        List<Student> list = studentMapper.FindAll();
        Iterator iterator = list.iterator();
        while(iterator.hasNext()){
            System.out.println(iterator.next());
        }
    }

       好了!今天我們就學到這裏吧,我們下期再見~

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