配置文件和映射文件再解讀
映射文件
在mapper.xml文件中配置很多的sql語句,執行每個sql語句時,封裝爲MappedStatement對象,mapper.xml以statement爲單位管理sql語句
Statement的實際位置就等於namespace+StatementId
配置文件
別名
typeAliases別名:
自定義別名:
<!-- 定義 別名 -->
<typeAliases>
<!--
單個別名的定義
alias:別名,type:別名映射的類型 -->
<!-- <typeAlias type="cn.itcast.mybatis.po.User" alias="user"/> -->
<!-- 批量別名定義
指定包路徑,自動掃描包下邊的pojo,定義別名,別名默認爲類名(首字母小寫或大寫)
-->
<package name="cn.itcast.mybatis.po"/>
</typeAliases>
Mapper加載
<mappers>
<!-- 通過resource引用mapper的映射文件 -->
<mapper resource="sqlmap/User.xml" />
<!-- <mapper resource="mapper/UserMapper.xml" /> -->
<!-- 通過class引用mapper接口
class:配置mapper接口全限定名
要求:需要mapper.xml和mapper.java同名並且在一個目錄 中
-->
<!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
<!-- 批量mapper配置
通過package進行自動掃描包下邊的mapper接口,
要求:需要mapper.xml和mapper.java同名並且在一個目錄 中
-->
<package name="cn.itcast.mybatis.mapper"/>
</mappers>
Mybatis解決JDBC編程的問題
1、數據庫鏈接創建、釋放頻繁造成系統資源浪費從而影響系統性能,如果使用數據庫鏈接池可解決此問題。
- 解決:在SqlMapConfig.xml中配置數據鏈接池,使用連接池管理數據庫鏈接。
2、Sql語句寫在代碼中造成代碼不易維護,實際應用sql變化的可能較大,sql變動需要改變java代碼。
- 解決:將Sql語句配置在XXXXmapper.xml文件中與java代碼分離。
3、向sql語句傳參數麻煩,因爲sql語句的where條件不一定,可能多也可能少,佔位符需要和參數一一對應。
- 解決:Mybatis自動將java對象映射至sql語句,通過statement中的parameterType定義輸入參數的類型。
4、對結果集解析麻煩,sql變化導致解析代碼變化,且解析前需要遍歷,如果能將數據庫記錄封裝成pojo對象解析比較方便。
- 解決:Mybatis自動將sql執行結果映射至java對象,通過statement中的resultType定義輸出結果的類型。
佔位符
在Mybatis中,有兩種佔位符
- #{}解析傳遞進來的參數數據
- ${}對傳遞進來的參數原樣拼接在SQL中
主鍵生成策略
如果我們在Hibernate中,當我們插入數據的時候,我們是可以選擇是UUID策略的…
那麼在Mybatis是怎麼做的呢??
UUID
<!-- mysql的uuid生成主鍵 -->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="string">
select uuid()
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
主鍵返回
如果我們一般插入數據的話,如果我們想要知道剛剛插入的數據的主鍵是多少,我們可以通過以下的方式來獲取
需求:
- user對象插入到數據庫後,新記錄的主鍵要通過user對象返回,通過user獲取主鍵值。
解決思路:
- 通過LAST_INSERT_ID()獲取剛插入記錄的自增主鍵值,在insert語句執行後,執行select LAST_INSERT_ID()就可以獲取自增主鍵。
mysql:
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
oracle:
實現思路:
- 先查詢序列得到主鍵,將主鍵設置到user對象中,將user對象插入數據庫。
<!-- oracle
在執行insert之前執行select 序列.nextval() from dual取出序列最大值,將值設置到user對象 的id屬性
-->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select 序列.nextval() from dual
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert>
Mapper代理方式
Mapper代理方式的意思就是:程序員只需要寫dao接口,dao接口實現對象由mybatis自動生成代理對象。
經過我們上面的幾篇博文,我們可以發現我們的DaoImpl是十分重複的…
1 dao的實現類中存在重複代碼,整個mybatis操作的過程代碼模板重複(先創建sqlsession、調用sqlsession的方法、關閉sqlsession)
2、dao的實現 類中存在硬編碼,調用sqlsession方法時將statement的id硬編碼。
以前的重複代碼和硬編碼如下:
public class StudentDao {
public void add(Student student) throws Exception {
//得到連接對象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空間.SQL片段的ID,就可以調用對應的映射文件中的SQL
sqlSession.insert("StudentID.add", student);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public static void main(String[] args) throws Exception {
StudentDao studentDao = new StudentDao();
Student student = new Student(3, "zhong3", 10000D);
studentDao.add(student);
}
}
Mapper開發規範
想要Mybatis幫我們自動生成Mapper代理的話,我們需要遵循以下的規範:
1、mapper.xml中namespace指定爲mapper接口的全限定名
- 此步驟目的:通過mapper.xml和mapper.java進行關聯。
2、mapper.xml中statement的id就是mapper.java中方法名
3、mapper.xml中statement的parameterType和mapper.java中方法輸入參數類型一致
4、mapper.xml中statement的resultType和mapper.java中方法返回值類型一致.
再次說明:statement就是我們在mapper.xml文件中寫sql指定的id
Mapper代理返回值問題
mapper接口方法返回值:
- 如果是返回的單個對象,返回值類型是pojo類型,生成的代理對象內部通過selectOne獲取記錄
- 如果返回值類型是集合對象,生成的代理對象內部通過selectList獲取記錄。