MyBatis介面代理方式實現Dao層
介面代理方式-實現規則
傳統方式實現Dao層,我們既要寫介面。還要寫實現類。而MyBatis框架可以幫助我們省略寫Dao層介面實現類的步驟。程式設計師只需要編寫介面,由MyBatis框架根據介面的定義來創
1該介面的動態代理物件。
實現規則:
1.對映配置檔案中的名稱空間必須和Dao層介面的全類名相同
2.對映配置檔案中的增刪改查標籤的id屬性必須和Dao層介面的方法名相同
3.對映配置檔案中的增刪改查標籤的paramrterType屬性必須和Dao層介面方法的引數相同
4.對映配置檔案中的增刪改查標籤的resultType屬性必須和Dao層介面方法的返回值相同
介面代理方式-程式碼實現
1.刪除mapper層介面的實現類
2.修改對映配置檔案
3.修改service層介面的實現類,採用介面代理方式實現功能
刪除mapper層介面的實現類
修改對映配置檔案
package com.itheima.service.impl; import com.itheima.bean.Student; import com.itheima.mapper.StudentMapper; import com.itheima.service.StudentService; 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; import java.util.List; /* 業務層實現類 */ public class StudentServiceImpl implements StudentService { @Override public List<Student> selectAll() { List<Student> list = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 list = mapper.selectAll(); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return list; } @Override public Student selectById(Integer id) { Student stu = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 stu = mapper.selectById(id); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return stu; } @Override public Integer insert(Student stu) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.insert(stu); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } @Override public Integer update(Student stu) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.update(stu); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } @Override public Integer delete(Integer id) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.delete(id); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } }
修改service層介面的實現類,採用介面代理方式實現功能
介面代理方式-原始碼分析
分析動態代理物件如何生成的?
通過動態代理開發的模式,我們只需要編寫一個介面,不寫實現類,我們通過getMapper()方法最終獲取到
org.apache.ibatis.binding.MapperProxy代理物件,然後執行功能,而這個代理物件正是MyBatis使用了JDK的動態代理技術,幫助我們生成了代理實現類物件。從而可以進行相關持久化操作。
分析方法是如何執行的?
動態代理的實現類物件再執行方法的時候最終呼叫了maperMethod.execute()方法,這個方法中通過switch語句根據操作型別來判斷是新增,修改,刪除,查詢操作,最後一步回到了MMyBatis最原生的SqlSession方式來執行增刪改查。
介面代理方式小結
介面代理方式可以讓我們只編寫介面即可,而實現類物件由MyBatis生成。
實現規則:
1.對映配置檔案中的名稱空間必須和Dao層介面的全類名相同
2.對映配置檔案中的增刪改查標籤的id屬性必須和Dao層介面的方法名相同
3.對映配置檔案中的增刪改查標籤的paramrterType屬性必須和Dao層介面方法的引數相同
4.對映配置檔案中的增刪改查標籤的resultType屬性必須和Dao層介面方法的返回值相同
獲取動態代理物件
SqlSession功能類中的getMapper()方法
刪除mapper中的實現類 ,保留介面
在StudentMapper.xml中修改 <mapper namespace="com.itheima.mapper.StudentMapper">
更改service包下 StudentServiceImpl檔案
package com.itheima.service.impl; import com.itheima.bean.Student; import com.itheima.mapper.StudentMapper; import com.itheima.service.StudentService; 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; import java.util.List; /* 業務層實現類 */ public class StudentServiceImpl implements StudentService { @Override public List<Student> selectAll() { List<Student> list = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 list = mapper.selectAll(); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return list; } @Override public Student selectById(Integer id) { Student stu = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 stu = mapper.selectById(id); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return stu; } @Override public Integer insert(Student stu) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.insert(stu); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } @Override public Integer update(Student stu) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.update(stu); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } @Override public Integer delete(Integer id) { Integer result = null; SqlSession sqlSession = null; InputStream is = null; try{ //1.載入核心配置檔案 is = Resources.getResourceAsStream("MyBatisConfig.xml"); //2.獲取SqlSession工廠物件 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); //3.通過工廠物件獲取SqlSession物件 sqlSession = sqlSessionFactory.openSession(true); //4.獲取StudentMapper介面的實現類物件 StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); // StudentMapper mapper = new StudentMapperImpl(); //5.通過實現類物件呼叫方法,接收結果 result = mapper.delete(id); } catch (Exception e) { } finally { //6.釋放資源 if(sqlSession != null) { sqlSession.close(); } if(is != null) { try { is.close(); } catch (IOException e) { e.printStackTrace(); } } } //7.返回結果 return result; } }
建立dynamic下測試類Test01
package com.itheima.dynamic; import com.itheima.bean.Student; import com.itheima.mapper.StudentMapper; 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.Test; import java.io.IOException; import java.io.InputStream; import java.util.ArrayList; import java.util.List; public class Test01 { @Test public void selectCondition() throws Exception { InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); Student stu=new Student(); stu.setId(2); stu.setName("李四"); //stu.setAge(23); List<Student> list = mapper.selectCondition(stu); for (Student student:list){ System.out.println(student); } sqlSession.close(); is.close(); } @Test public void selectByIds() throws Exception { InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List<Integer> ids=new ArrayList<>(); ids.add(1); ids.add(2); List<Student> list = mapper.selectByIds(ids); for (Student student:list){ System.out.println(student); } sqlSession.close(); is.close(); } }
MyBatis對映配置檔案-----動態sql
動態SQL介紹
MyBatis對映配置檔案中,前面我們的SQL都是比較簡單的,有些時候業務邏輯複雜時,我們的SQL就時動態變化的,此時在前面學習的SQL就不能滿足要求了。
多條件查詢
id:3 name:王五 age:25
select * from Student where id=#{id} and name=#{name} and age=#{age}
id:3 name:王五
select * from Student where id=#{id} and name=#{name}
動態sql標籤
<where>:條件標籤。如果有動態條件,則使用該標籤代替where關鍵字。
<if>:條件判斷標籤
<if test="條件判斷"> 查詢條件拼接 </if>
<foreach>:迴圈遍歷標籤。適用於多個引數或者的關係。
<foreach collection="" open="" close="" item="" separator=""> 獲取引數 </foreach>
屬性:
collection:引數容器型別,(list-集合,array-陣列)。
open:開始的sql語句
close:結束額sql語句
item:引數變數名
separator:分隔符
Sql片段抽取
我們可以將一些重複的SQL語句進行抽取,以達到複用的效果
<sql>: 抽取SQL語句標籤
<sql id ="片段唯一標識" >抽取的SQL語句</sql>
<include>:引入SQL片段標籤
<include refid="片段唯一標識" />
StudentMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!--MyBatis的DTD約束--> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- mapper:核心根標籤 namespace屬性:名稱空間 --> <mapper namespace="com.itheima.mapper.StudentMapper"> <sql id="select">Select * FROM Student</sql> <!-- select:查詢功能的標籤 id屬性:唯一標識 resultType屬性:指定結果對映物件的型別 parameterType:指定引數對映物件型別 --> <select id="selectAll" resultType="student"> <include refid="select"/> </select> <select id="selectById" resultType="student" parameterType="int"> <include refid="select"/> where id = #{id} </select> <insert id="insert" parameterType="student"> Insert into Student values(#{id},#{name},#{age}) </insert> <update id="update" parameterType="student"> update Student set name =#{name},age=#{age} where id=#{id} </update> <delete id="delete" parameterType="int"> delete from Student where id=#{id} </delete> <select id="selectCondition" resultType="student" parameterType="student"> <include refid="select"/> <where> <if test="id!=null"> id=#{id} </if> <if test="name!=null"> and name=#{name} </if> <if test="age!=null"> and age=#{age} </if> </where> </select> <select id="selectByIds" resultType="student" parameterType="list"> <include refid="select"/> <where> <foreach collection="list" open="id in (" close=")" item="id" separator=","> #{id} </foreach> </where> </select> </mapper>
動態SQL小結
動態SQL指的就是SQL語句可以根據條件或者引數的不同進行動態的變化
<where>:條件標籤
<if>:裡面有個test標籤可以幫我們進行判斷
<foreach>:迴圈遍歷的標籤 collection="list" open="id in (" close=")" item="id" separator=","
<sql>:抽取SQL片段的標籤
<include>:引入SQL片段的標籤