MybatisDao層開發的二種方式


原始DAO開發

 

SqlSession使用范圍

SqlSessionFactoryBuilder

  • 通過SqlSessionFactoryBuilder創建會話工廠SqlSessionFactory
  • 將SqlSessionFactoryBuilder當成一個工具類使用即可,不需要使用單例管理SqlSessionFactoryBuilder。
  • 在需要創建SqlSessionFactory時候,只需要new一次SqlSessionFactoryBuilder即可。

SqlSessionFactory

  • 通過SqlSessionFactory創建SqlSession,使用單例模式管理sqlSessionFactory(工廠一旦創建,使用一個實例)。
  • 將來mybatis和spring整合后,使用單例模式管理sqlSessionFactory。

SqlSession

  • SqlSession是一個面向用戶(程序員)的接口。
  • SqlSession中提供了很多操作數據庫的方法:如:selectOne(返回單個對象)、selectList(返回單個或多個對象)、。
  • SqlSession是線程不安全的,在SqlSesion實現類中除了有接口中的方法(操作數據庫的方法)還有數據域屬性。
  • SqlSession最佳應用場合在方法體內,定義成局部變量使用。
public class User {
   // private String id;
   private Integer id;
    private String username;// 用戶姓名
    private String sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址

   /* public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }*/

public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" + "id=" + id + ", username='" + username + '\'' + ", sex='" + sex + '\'' + ", birthday=" + birthday + ", address='" + address + '\'' + '}';
    }
}
POJO
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語句進行分類化管理,隔離 paramterType:參數類型 java類型 pojo(保存的時候) resultType:結果類型 數據庫的字段名必須和實體類的屬性名一致 #{id}:一個占位符 --> <mapper namespace="test"> <!-- id:標識配置文件中唯一的sql 一般稱為statement的id --> <select id="findUserById" parameterType="int" resultType="b_dao_origin.pojo.User"> SELECT * FROM USER WHERE id=#{id} </select> </mapper>
public interface UserDao {
    /**
     * 根據id查詢
     * @param id
     * @return
     */
    public User getUserById(Integer id);
}
UserDao
UserDaoImpl
 1 public class UserDaoImpl implements UserDao {
 2     private SqlSessionFactory sqlSessionFactory;
 3   //通過構造方法注入sqlSessionFactory
 4     public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
 5         this.sqlSessionFactory = sqlSessionFactory;
 6     }
 7 
 8     /**
 9      * 根據id查詢
10      * @param id
11      * @return
12      */
13     @Override
14     public User getUserById(Integer id) {
15         SqlSession sqlSession = sqlSessionFactory.openSession();
16         User user = sqlSession.selectOne("test.findUserById", id);
17         return user;
18     }
19 }
public class Demo {
    SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void before() throws IOException {
        //通過流的方式得到核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("b_dao_origin/sqlMapConfig.xml");
        //通過配置文件創建session工廠
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test(){
        //如果使用代理增強了方法就不能用UserDaoImpl  要用UserDao
        UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
        User userById = userDao.getUserById(1);
        System.out.println(userById);
    }
}
測試類

存在的問題:

1.如果DAO層有很多方法,實現類中就會出現很多重復的代碼。

2.調用sqlsession方法時將statemnt的id硬編碼了,不利於維護。

3.調用sqlsession方法時傳入的變量,由於sqlsession方法使用泛型,即使變量類型傳入錯誤,在編譯階段也不報錯,不利於程序員開發。

 

Mapper動態代理方式

實現原理:

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

需要遵循的規范:

(1)Mapper接口和Mapper.xml需要放置在一個目錄下,且同名

(2)Mapper.xml中的namespace值等於Mapper接口的全路徑

(3)Mapper接口的方法名和statement Id一致

(4)Mapper接口的參數類型和statement paramterType類型一致

(5)Mapper接口的返回值和statement resultType類型一致(注意:返回值可能是list)

注意:mapper接口只能傳遞一個參數(盡量保證原子操作)、當需要傳遞多個參數的時候,可以使用pojo或者包裝類型pojohashmap

Mapper接口:

public interface UserMapper {
    /**
     * 根據id查詢
     * @param id
     * @return
     */
    public List<User> getUserById(Integer id);

    /**
     * 通過姓氏進行模糊查詢
     * @param name
     * @return
     */
    public List<User> getUsersByName(String name);
}

UserMapper.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:mapper接口的全路徑
paramterType:參數類型  java類型  pojo(保存的時候)
resultType:結果類型  數據庫的字段名必須和實體類的屬性名一致
#{id}:一個占位符
-->
<mapper namespace="c_dao_mapper.mapper.UserMapper">

    <select id="getUserById" parameterType="int" resultType="user">
      SELECT * FROM USER WHERE id=#{id}
    </select>

    <select id="getUsersByName" parameterType="string" resultType="user">
        SELECT * FROM USER WHERE username LIKE #{value}"%"
    </select>
</mapper>

在sqlMapConfig.xml中配置別名和引入映射文件UserMapper.xml

<typeAliases>
        <!--
        type:類型的全路徑
        alias:對應類型的別名   建議類名首字母小寫
        -->
       <!-- <typeAlias type="c_dao_mapper.pojo.User" alias="user"></typeAlias>-->

        <!--
        掃描指定的包名  別名:類名,默認首字母小寫
        -->
        <package name="c_dao_mapper.pojo"></package>
 </typeAliases>


<!--引入映射文件-->
    <mappers>
       <!-- <mapper resource="c_dao_mapper/mapper/UserMapper.xml"></mapper>
        可以通過xml文件找到class<mapper class="c_dao_mapper.mapper.UserMapper"></mapper>-->

        <!--批量加載 只能在mapper方式開發的時候用-->
        <package name="c_dao_mapper.mapper"></package>
    </mappers>

測試類:

public class Demo {
    SqlSessionFactory sqlSessionFactory = null;
    @Before
    public void before() throws IOException {
        //通過流的方式得到核心配置文件
        InputStream inputStream = Resources.getResourceAsStream("c_dao_mapper/sqlMapConfig.xml");
        //通過配置文件創建session工廠
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void test(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        //生成usermapper代理對象 會實現UserMapper接口里面的方法
        //如果public User getUserById(Integer id);
        //代理對象就會調用selectone方法
        //如果public List<User> getUserById(Integer id);
        //代理對象就會調用selectList方法
        List<User> userById = mapper.getUserById(1);
        System.out.println(userById);
    }

    //模糊查詢
    @Test
    public void test2(){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> userList = mapper.getUsersByName("w");
        System.out.println(userList);
    }

}

 


免責聲明!

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



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