【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