1. 程式人生 > >【SSM-MyBatis框架】MyBatis開發DAO的方式

【SSM-MyBatis框架】MyBatis開發DAO的方式

Mybatis開發Dao的方式

  MyBatis開發Dao有兩種方式:原始Dao的開發方式,Mapper動態代理的方式。

    兩種開發方式在企業開發中均有運用。都要掌握。

   使用myBatis時,需要對其進行一個全域性的管理配置。

    sqlMappingConfig.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>

	<!--  載入屬性檔案-->
	<properties resource="db.properties"></properties>
	
	<!-- 全域性引數配置,在需要時候進行配置 -->
	<!-- <settings></settings> -->
	
	<!-- 別名設定 -->
	<!-- 單個配置
			 type:型別路徑
			 alias:別名-->
			<!-- <typeAliases>
					<typeAlias type="cn.edu.hpu.ssm.po.User" alias="user"/>
			</typeAliases> -->
	<!-- 批量設定(推薦使用)
			指定包名,mybatis自動掃描掃描po類,自動定義別名。預設為類名(首字母大寫或小寫) -->
			<typeAliases>
					<package name="cn.edu.hpu.ssm.po"/>
			</typeAliases>
			
			
	<!-- 和spring整合後 environments配置將廢除-->
	<environments default="development">
		<environment id="development">
		<!-- 使用jdbc事務管理,事物控制有mybatis控制-->
			<transactionManager type="JDBC" />
		<!-- 資料庫連線池,由mybatis管理-->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- 配置mpper,載入對映檔案 -->
<!-- <mappers>
				<mapper resource="sqlmap/User.xml"/>
				<mapper resource="mapper/UserMapper.xml"/>
		</mappers> -->
	
		<!-- 通過mapper介面,載入對映檔案
			規範:mapper介面名必須與mapper。xml檔名相同,且放在同一包下
					前提是使用mapper代理的方式 -->
					<mappers>
							<mapper class="cn.edu.hpu.ssm.mapper.UserMapper"/>
							<mapper class="cn.edu.hpu.ssm.mapper.OrdersMapperCustom"/>
					</mappers>
</configuration>

        其中關於資料庫的一些配置,抽取出來了,這樣可以減少硬編碼:

      db.properties:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456


1.原始Dao的開發方式

              原始Dao的開發,需要程式設計師自己編寫Dao的介面和Dao介面的實現類。(一下以一個按照id查詢為例說明)

    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:名稱空間,作用就是對sql進行分類化管理,sql隔離
		注意:在使用mapper的代理方法開發時,有重要作用 -->
<mapper namespace="test">

	<!-- 在對映檔案中配置多個,sql語句 -->
	
	<!-- 按照id查詢 -->
	<!-- 將sql語句封裝到MapperStatement中,所以也將id 成為statement的Id -->
	<!-- paramerType:指定輸入引數的型別。
			#{ } :代表佔位符。
			#{id }:表示接受輸入引數id的值,如果輸入引數是簡單型別,#{ }中的引數名可以任意
					 ,可以是value或是其他值
					 
			resultType:表示sql輸出結果的所對映的Javabean的物件型別,resultType指定將單條記錄對映成Java對像-->
	<select id="findUserById" parameterType="int"  resultType="cn.edu.hpu.ssm.po.User">
		SELECT * FROM USER WHERE id = #{value}
	</select>
	
	
</mapper>

         2.Dao介面:

Public interface UserDao {
	public User getUserById(int id) throws Exception;
}

         3.Dao介面的實現

Public class UserDaoImpl implements UserDao {
	
	//通過建構函式注入SqlSessionFactory
	public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
		this.setSqlSessionFactory(sqlSessionFactory);
	}
	
	private SqlSessionFactory sqlSessionFactory;
	@Override
	public User getUserById(int id) throws Exception {
		SqlSession session = sqlSessionFactory.openSession();
		User user = null;
		try {
			//通過sqlsession呼叫selectOne方法獲取一條結果集
			//引數1:指定定義的statement的id,引數2:指定向statement中傳遞的引數
			user = session.selectOne("test.findUserById", 1);
			System.out.println(user);
						
		} finally{
			session.close();
		}
		return user;
	}
}

    通過上面的例子,我們可以總結:

         原始Dao開發存在以下問題:

            Dao的方法存在重複程式碼,:通過sqlSessionFactory建立SqlSession,呼叫sqlSession資料庫的操作方法。

           呼叫sqlSession操作資料庫的方法(第一個引數)時,硬編碼,不利於系統的維護。

  SqlSessionFactory的使用範圍:

     通過SQLSessionFactoryBuilder建立會話工廠SQLSessionFactory。將SQLSessionFactoryBuilder當做一個工具類來使用即可,不需要使用單例模式去管理。

    通過SQLSessionFactory建立sqlSession,使用單例模式管理SQLSessionFactory,(工廠一旦被建立,使用一個例項)。將來mybatis與spring整合後,使用單例模式來管理sqlSessionFactory。

    sqlSession是執行緒不安全的,在sqlsession中不但存在操作資料庫的方法,還有資料域屬性。sqlSession最佳應用場合,是在方法體內,定義成區域性變數使用。

   2.Mapper代理的方式:

            mapper動態代理實現的原理:

    mapper介面開發方式,只需要程式設計師編寫mapper介面(相當於Dao介面),有mybatis框架根據介面定義建立介面的動態代理物件,代理的方法體與上面Dao實現類中的方法體相類似

 Mapper介面開發要符合一下規範:

     1.Mapper.xml中namespace路徑與mapper介面路徑相同

     2.mapper介面中的方法名,與Mapper.xml中對應statement的id相同

     3.mapper介面中方法的輸入引數型別和mapper.xml中定義的對應sql的ParameterType的型別相同

     4.mapper介面中方法的返回值型別和mapper.xml中定義的對應sql的ResultType的型別相同

   1.Mapper.xml寫法:(與上面User.xml不同的是namespace做了定義)

<?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:名稱空間,作用就是對sql進行分類化管理,sql隔離
		注意:在使用mapper的代理方法開發時,有重要作用  
				namespace命名必須與Mapper介面的路徑相同 -->
<mapper namespace="cn.edu.hpu.ssm.mapper.UserMapper">

	
	
	<!-- 按照id查詢 -->
	<!-- 將sql語句封裝到MapperStatement中,所以也將id 成為statement的Id -->
	<!-- paramerType:指定輸入引數的型別。
			#{ } :代表佔位符。
			#{id }:表示接受輸入引數id的值,如果輸入引數是簡單型別,#{ }中的引數名可以任意
					 ,可以是value或是其他值
					 
			resultType:表示sql輸出結果的所對映的Javabean的物件型別,resultType指定將單條記錄對映成Java對像-->
	<select id="findUserById" parameterType="int"  resultType="User">
		SELECT * FROM USER WHERE id = #{value}
	</select>
</mapper>


    2.mapper.java(介面檔案)

package cn.edu.hpu.ssm.mapper;

import java.util.List;
import java.util.Map;

import cn.edu.hpu.ssm.po.User;
import cn.edu.hpu.ssm.po.UserCustom;
import cn.edu.hpu.ssm.po.UserQueryVo;

public interface UserMapper {
	
	//返回值型別必須與mapper.xml中resultType型別相同
	//形參必須與mapper.xml中的parameterType型別相同
	//mapper.java介面中的方法名和mapper.xml中statement的id一致
	public User findUserById(int id) throws Exception;
	}

    
     3.測試檔案:(通過junit)

public class MapperTest {
 private SqlSessionFactory sqlSessionFactory;
 @Before
 public void setUp() throws Exception {
  String resource = "SqlMapConfig.xml";
  InputStream input = Resources.getResourceAsStream(resource);
  sqlSessionFactory = new SqlSessionFactoryBuilder().build(input);
 }
/**
  * 通過id查詢
  * @throws Exception
  */
 @Test
 public void testFindUserById() throws Exception {
  SqlSession session = sqlSessionFactory.openSession();
  
  //通過session自動建立mapper代理物件
  UserMapper userMap = session.getMapper(UserMapper.class);
  
  User user = userMap.findUserById(1);
  System.out.println(user);
 }
}


     4.對Mapper動態代理的一個小結:

        1.使用mapper代理時,輸入引數型別可以使用pojo的包裝物件,或是mapper物件,保證dao的同性。

        2.selectOne和selectList

           動態代理物件通過sqlsession.selectOne和sqlsession.selectList,是通過對返回值型別進行判斷而選擇呼叫哪一個方法。如果返回單個物件則呼叫selectOne,返回集合物件則呼叫selectList