日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

原始dao和Mapper动态代理的开放方式---Mybatis学习笔记(六)

發布時間:2023/12/20 编程问答 25 豆豆
生活随笔 收集整理的這篇文章主要介紹了 原始dao和Mapper动态代理的开放方式---Mybatis学习笔记(六) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

1.原始Dao開發方式

原始Dao開發方法需要程序員編寫Dao接口和Dao實現類。
1.映射文件:(user.xml)

<?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語句,后面會講另一層非常重要的作用。 --> <mapper namespace="test"><!-- 根據Id獲取用戶信息 ,返回一條數據--> <!-- 通過<select>進行數據庫查詢 id:標識映射文件中的sql 將sql語句封裝到mappedStatement對象中,所以將id稱為statement的id parameterType:指定輸入參數的類型 #{}:表示一個占位符 #{id}:其中的id表示接收輸入的參數,參數的名稱就是id,如果輸入參數為簡單類型,#{}中的參數名可以任意,可以value也可以其它名稱。 resultType:指定sql輸出結果的所映射的java對象類型。select指定resultType表示將單條記錄映射成的java對象。--> <select id="findUserById" parameterType="int" resultType="com.huihui.pojo.User">select * from user where id=#{id} </select> <!-- 自定義條件查詢用戶列表,可能返回多條 --> <!-- ${}:表示拼接sql串,將接收到的參數的內容不加任何修飾拼接到sql中。 使用${}拼接sql,可能引起sql注入 ${value}:接收輸入參數的內容,如果傳入的類型是簡單類型,${}中只能使用value--> <select id="findUserByUsername" parameterType="java.lang.String" resultType="com.huihui.pojo.User">select * from user where username like '%${value}%' </select><!-- 添加用戶 --> <!-- parameterType:指定輸入參數類型為pojo #{}中指定pojo的屬性名,接收到pojo對象的屬性值--> <insert id="insertUser" parameterType="com.huihui.pojo.User" >insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})<!-- selectKey將主鍵返回,需要再返回 --><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select LAST_INSERT_ID()</selectKey> </insert><!-- 刪除用戶 --> <!-- 根據id刪除用戶,需要輸入id值 --> <delete id="deleteUser" parameterType="java.lang.Integer">delete from user where id = #{id} </delete><!-- 更新用戶 --> <!-- 根據id更新用戶,需要傳入用戶的id和用戶的更新信息(也就是傳入User對象,但是user對象中的id必須存在) --> <update id="updateUser" parameterType="com.huihui.pojo.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> </mapper>

2.Dao接口:

package com.huihui.dao;import java.util.List;import com.huihui.pojo.User;public interface UserDao {//根據id查詢用戶信息public User findUserById(int id) throws Exception;//根據用戶的名稱查詢用戶的信息public List<User> findUserByName(String name) throws Exception;//添加用戶信息public void insertUser(User user) throws Exception;//刪除用戶信息public void deleteUser(int id) throws Exception;}

3.Dao接口實現類:

package com.huihui.dao;import java.util.List;import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory;import com.huihui.pojo.User;public class UserDaoImpl implements UserDao{//需要向dao實現類中注入SqlSessionFactory//這里通過構造方法注入private SqlSessionFactory sqlSessionFactory;public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {this.sqlSessionFactory = sqlSessionFactory;}@Overridepublic User findUserById(int id) throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();User user = sqlSession.selectOne("test.findUserById", id);//釋放資源sqlSession.close();return user;}@Overridepublic void insertUser(User user) throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.insert("test.insertUser", user);//提交事務sqlSession.commit();//釋放資源sqlSession.close();}@Overridepublic void deleteUser(int id) throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.delete("test.deleteUser", id);//提交事務sqlSession.commit();//釋放資源sqlSession.close();}@Overridepublic List<User> findUserByName(String name) throws Exception {SqlSession sqlSession = sqlSessionFactory.openSession();sqlSession.selectList("test.findUserByUsername", name);//釋放資源sqlSession.close();return null;}}

4.加載user.xml文件
修改SqlMapConfig.xml文件:

<!-- 加載映射文件 --><mappers><mapper resource="sqlmap/user.xml"/></mappers>

5.測試代碼:

public class UserDaoImplTest {private SqlSessionFactory sqlSessionFactory;@Before//此方法是運行下面的測試用例的方法之前執行的public void setUp() throws Exception{//創建sqlSessionFactory//mybatis配置文件路徑String resource = "SqlMapConfig.xml";//得到配置文件流InputStream inputStream = Resources.getResourceAsStream(resource);//創建會話工廠,傳入mybatis的配置文件信息sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void testFindUserById() throws Exception{//創建一個userDao的對象UserDao userDao = new UserDaoImpl(sqlSessionFactory);//調用UserDao方法User user = userDao.findUserById(1);System.out.println(user);}@Testpublic void testFindUserByName() throws Exception{//創建一個userDao對象UserDao userDao = new UserDaoImpl(sqlSessionFactory);//調用UserDao方法List<User> list = userDao.findUserByName("張");System.out.println(list.size());} }

分析原始Dao開發方式存在的問題:

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

  • Dao方法體存在重復代碼:通過SqlSessionFactory創建SqlSession,調用SqlSession的數據庫操作方法
  • 調用sqlSession的數據庫操作方法需要指定statement的id,這里存在硬編碼,不利于開發維護。
  • 調用sqlsession方法時傳入的變量,由于sqlsession方法使用泛型,即使變量類型傳入錯誤,在編譯階段也不報錯,不利于程序員開發。
  • 2.mapper動態代理的方法

    實現原理
    Mapper接口開發方法只需要程序員編寫Mapper接口(相當于Dao接口),由Mybatis框架根據接口定義創建接口的動態代理對象,代理對象的方法體同上邊Dao接口實現類方法。

    Mapper接口開發需要遵循以下規范:

  • Mapper.xml文件中的namespace與mapper接口的類路徑相同。
  • Mapper接口方法名和Mapper.xml中定義的每個statement的id相同
  • Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
  • Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
  • 只有遵循以上規范,mybatis才可以自動生成mapper接口的實現類代理對象。
    其實以上的規范主要為了相對于dao實現類中的以下方法進行了自動生成:

    User user = sqlSession.selectOne("test.findUserById", id);sqlSession.insert("test.insertUser", user);sqlSession.delete("test.deleteUser", id);sqlSession.selectList("test.findUserByUsername", name); ...

    1.映射文件(UserMapper.xml文件):
    定義mapper映射文件UserMapper.xml(內容同User.xml一樣),需要修改namespace的值為UserMapper接口路徑。將UserMapper.xml放在classpath下mapper目錄下。

    <?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語句,后面會講另一層非常重要的作用(需要修改namespace的值為UserMapper接口路徑)。 --> <mapper namespace="com.huihui.mapper.UserMapper"><!-- 根據Id獲取用戶信息 ,返回一條數據--> <!-- 通過<select>進行數據庫查詢 id:標識映射文件中的sql 將sql語句封裝到mappedStatement對象中,所以將id稱為statement的id parameterType:指定輸入參數的類型 #{}:表示一個占位符 #{id}:其中的id表示接收輸入的參數,參數的名稱就是id,如果輸入參數為簡單類型,#{}中的參數名可以任意,可以value也可以其它名稱。 resultType:指定sql輸出結果的所映射的java對象類型。select指定resultType表示將單條記錄映射成的java對象。--> <select id="findUserById" parameterType="java.lang.Integer" resultType="com.huihui.pojo.User">select * from user where id=#{id} </select> <!-- 自定義條件查詢用戶列表,可能返回多條 --> <!-- ${}:表示拼接sql串,將接收到的參數的內容不加任何修飾拼接到sql中。 使用${}拼接sql,可能引起sql注入 ${value}:接收輸入參數的內容,如果傳入的類型是簡單類型,${}中只能使用value--> <select id="findUserByUsername" parameterType="java.lang.String" resultType="com.huihui.pojo.User">select * from user where username like '%${value}%' </select><!-- 添加用戶 --> <!-- parameterType:指定輸入參數類型為pojo #{}中指定pojo的屬性名,接收到pojo對象的屬性值--> <insert id="insertUser" parameterType="com.huihui.pojo.User" >insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})<!-- selectKey將主鍵返回,需要再返回 --><selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">select LAST_INSERT_ID()</selectKey> </insert><!-- 刪除用戶 --> <!-- 根據id刪除用戶,需要輸入id值 --> <delete id="deleteUser" parameterType="java.lang.Integer">delete from user where id = #{id} </delete><!-- 更新用戶 --> <!-- 根據id更新用戶,需要傳入用戶的id和用戶的更新信息(也就是傳入User對象,但是user對象中的id必須存在) --> <update id="updateUser" parameterType="com.huihui.pojo.User">update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> </mapper>

    2.接口(UserMapper.java文件)
    接口定義有如下特點:

  • Mapper接口方法名和Mapper.xml中定義的statement的id相同
  • Mapper接口方法的輸入參數類型和mapper.xml中定義的statement的parameterType的類型相同
  • Mapper接口方法的輸出參數類型和mapper.xml中定義的statement的resultType的類型相同
  • package com.huihui.mapper;import java.util.List;import com.huihui.pojo.User;/*** mapper接口,相當于dao接口* 用戶管理* @author 62347**/ public interface UserMapper {//根據id查詢用戶信息public User findUserById(int id) throws Exception;//根據用戶名列查詢用戶列表public List<User> findUserByUsername(String name) throws Exception;//添加用戶信息public void insertUser(User user) throws Exception;//刪除用戶信息public void deleteUser(int id) throws Exception;}

    3.加載UserMapper.xml文件

    <!-- 加載映射文件 --><mappers><mapper resource="mapper/UserMapper.xml"/></mappers>

    4.測試代碼:

    package com.huihui.mapper;import java.io.InputStream; import java.util.Date; import java.util.List;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.Before; import org.junit.Test;import com.huihui.pojo.User;public class UserMapperTest {private SqlSessionFactory sqlSessionFactory;@Before//此方法是運行下面的測試用例的方法之前執行的public void setUp() throws Exception{//創建sqlSessionFactory//mybatis配置文件路徑String resource = "SqlMapConfig.xml";//得到配置文件流InputStream inputStream = Resources.getResourceAsStream(resource);//創建會話工廠,傳入mybatis的配置文件信息sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);}@Testpublic void testFindUserById() throws Exception {//通過會話工廠得到會話SqlSession sqlSession = sqlSessionFactory.openSession();//創建UserMapper對象,mybatis自動生成mapper代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = userMapper.findUserById(30);System.out.println(user);sqlSession.close();}@Testpublic void testFindUserByName() throws Exception {//通過會話工廠得到會話SqlSession sqlSession = sqlSessionFactory.openSession();//創建UserMapper對象,mybatis自動生成mapper代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);List<User> list = userMapper.findUserByUsername("張");System.out.println(list.size());sqlSession.close();}@Testpublic void testInsertUser() throws Exception {//通過會話工廠得到會話SqlSession sqlSession = sqlSessionFactory.openSession();//創建UserMapper對象,mybatis自動生成mapper代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();user.setSex("2");user.setBirthday(new Date());user.setAddress("北京豐臺");user.setUsername("噠噠噠");userMapper.insertUser(user);sqlSession.commit();//提交事務sqlSession.close();}@Testpublic void testDeleteUser() throws Exception {//通過會話工廠得到會話SqlSession sqlSession = sqlSessionFactory.openSession();//創建UserMapper對象,mybatis自動生成mapper代理對象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);userMapper.deleteUser(30);sqlSession.commit();//提交事務sqlSession.close();}}

    重點說明:

  • selectOne和selectList
    動態代理對象調用sqlSession.selectOne()和sqlSession.selectList()是根據mapper接口方法的返回值決定,如果返回list則調用selectList方法,如果返回單個對象則調用selectOne方法。
  • mapper接口輸入參數只能有一個,是否不利于系統擴展維護?
    系統框架中,dao層的代碼是被業務層公用的。即使mapper接口中只有一個參數,也可以使用包裝類型的pojo滿足不同的業務方法的需求。
    注意:持久層中方法的參數可以是包裝類型(eg:map,…..),但是service方法中不建議使用包裝類型(原因:不利于業務層的可擴展)。
  • 總結

    以上是生活随笔為你收集整理的原始dao和Mapper动态代理的开放方式---Mybatis学习笔记(六)的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。