[MyBatis]DAO層只寫接口,不用寫實現類


團隊開發一個項目,由老大架了一個框架,遇到了DAO層不用寫接口了,我也是用了2次才記住這個事的,因為自己一直都是習慣於寫DAO層的實現類,所以,習慣性的還是寫了個實現類。於是遇到錯誤了。

找不到那個方法。問了團隊的人才知道,方法名和Mapper中配置的id名必須一樣。

實現:

一、配置Spring集成MyBatis:

<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"... ------------------------------------------------- <!-- 配置數據源 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" ... ------------------------------------------------- <!-- 產生sqlsessionfactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="configLocation" value="classpath:mybatis-config.xml" /> </bean> --------------------------------------------------

要實現對數據庫的操作必須要有sqlSession,而sqlSession是由sqlSessionFactory創建的。我們可以在spring配置好bean。

<!-- 自動掃描mapper接口--> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer" p:basePackage="com.xiaojuzi.chaojijuhui.**.dao" p:sqlSessionFactoryBeanName="sqlSessionFactory" />

這個配置就是配置映射文件的路徑,這樣做的好處就是不用再寫Dao的實現類了,也就是說,我們寫好接口,寫好配置文件,會自動映射到對應的方法和sql語句。

二、開發mapper.xml映射文件

<mapper namespace="com.xiaojuzi.chaojijuhui.user.dao.UserDao"> -------------------------------------------------------

在這里只有一個UserDao(被代理的接口)。 
user.mapper.xml–namespace配置的就是UserDao的包全名。

三、開發mapper.java的接口

     /** * 根據用戶的用戶名查詢用戶 * @param user * @return */ User queryUserByLoginName (String loginName); /** * 用戶通過手機號碼去修改密碼 * @param userModel * @return */ Boolean updatePasswordByMobile(UserModel userModel); 

如果需要特定類型的參數,就自己再造一個POJO類(例如:UserModel)。

 <sql id="userColumns"> u.id, u.login_name as "loginName", u.head_img as "headImg", ... --------------------------------------------- <select id="queryUserByLoginName" resultType="User" parameterType="User"> SELECT <include refid="userColumns" /> FROM juhui_user u WHERE u.login_name = #{loginName} and u.del_flag = #{DEL_FLAG_NORMAL} </select> <update id="updatePasswordByMobile" parameterType="UserModel"> update juhui_user set update_date=DATE_FORMAT(#{updateDate}, '%Y-%m-%d %H:%i:%S'), salt = #{salt}, password = #{password} where mobile = #{mobile} </update>

這里mapper.xml的(select、insert、update..)標簽的id必須和DAO接口的方法名一樣!

Mapper開發規則

1、 在mapper.xml中將namespace設置為mapper.Java的全限定名 
2、 將mapper.java接口的方法名和mapper.xml中statement的id保持一致。 
3、 將mapper.java接口的方法輸入參數類型和mapper.xml中statement的parameterType保持一致 
4、 將mapper.java接口的方法輸出 結果類型和mapper.xml中statement的resultType保持一致

注意遵循上邊四點規范!

這樣拋棄Dao實現類的寫法: 
具有更好的可擴展性,提高了靈活度。

原理

再根據網上的一些知識點,講一下原理:

mybatis通過JDK的動態代理方式,在啟動加載配置文件時,根據配置mapper的xml去生成Dao的實現。

session.getMapper()使用了代理,當調用一次此方法,都會產生一個代理class的instance,看看這個代理class的實現.

public class MapperProxy implements InvocationHandler { ... public static <T> T newMapperProxy(Class<T> mapperInterface, SqlSession sqlSession) { ClassLoader classLoader = mapperInterface.getClassLoader(); Class<?>[] interfaces = new Class[]{mapperInterface}; MapperProxy proxy = new MapperProxy(sqlSession); return (T) Proxy.newProxyInstance(classLoader, interfaces, proxy); } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { if (!OBJECT_METHODS.contains(method.getName())) { final Class<?> declaringInterface = findDeclaringInterface(proxy, method); final MapperMethod mapperMethod = new MapperMethod(declaringInterface, method, sqlSession); final Object result = mapperMethod.execute(args); if (result == null && method.getReturnType().isPrimitive()) { throw new BindingException("Mapper method '" + method.getName() + "' (" + method.getDeclaringClass() + ") attempted to return null from a method with a primitive return type (" + method.getReturnType() + ")."); } return result; } return null; } 

這里是用到了JDK的代理Proxy。 newMapperProxy()可以取得實現interfaces 的class的代理類的實例。

當執行interfaces中的方法的時候,會自動執行invoke()方法,其中public Object invoke(Object proxy, Method method, Object[] args)中 method參數就代表你要執行的方法.

MapperMethod類會使用method方法的methodName 和declaringInterface去取 sqlMapxml 取得對應的sql,也就是拿declaringInterface的類全名加上 sql-id..

總結: 
這個就是利用JDK的代理類實現的。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM