原始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 + '\'' + '}'; } }
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); }
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或者包裝類型pojo,hashmap
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); } }