MyBatis知識三 DAO開發模式
首先,我們應該先了解一下介面與類:
介面與類
SqlSessionFactoryBuilder類,用來建立SqlSessionFactory介面的類,其中在這個SqlSessionFactoryBuilder類中,過載 了許多的builder方法。他會根據我們傳入的流建立一個XMLConfigBuilder類,然後會呼叫parse()方法,返回一個Configuration物件,最後我們通過DefaultSqlSessionFactory(config),將我們的Configuration進行解析,返回我們最終需要的SqlSessionFactory。【點進去原始碼進行觀察】。
通過SqlSessionFactoryBuilder建立會話工廠SqlSessionFactory,將SqlSessionFactoryBuilder當成一個工具類使用即可,不需要使用單例管理SqlSessionFactoryBuilder。在需要建立SqlSessionFactory時候,只需要new一次SqlSessionFactoryBuilder即可。
SqlSessionFactory介面:SqlSessionFactory是一個介面,其具體實現類是DefaultSqlSessionFactory,通過類名我們可以看到SqlSessionFactory是一個SqlSession工廠,用來生產SqlSession物件,SqlSession中有我們進行資料庫操作的增刪改查介面。通過SqlSessionFactory建立SqlSession,使用單例模式管理sqlSessionFactory(工廠一旦建立,使用一個例項)。
SqlSession介面:SqlSession是一個介面其具體實現類為DefaultSqlSession,SqlSession介面主要定義了一些增刪改查方法,DefaultSQLSession是對SqlSession介面的具體實現,SqlSession是一個面向使用者(程式設計師)的介面。SqlSession是執行緒不安全的,在SqlSesion實現類中除了有介面中的方法(操作資料庫的方法)還有資料域屬性。
SqlSession最佳應用場合在方法體內,定義成區域性變數使用。
MyBatis 原始開發DAO步驟:
1、編寫DAO介面
2、編寫DAO實現
// 1、編寫DAO介面
public interface UserDao {
public User seleteById(int id);
public List<User> selectByName(String name);
public void insertUser(User user);
public void deleteUserById(int id);
public void updateuserwithid(User user);
}
// 2、編寫DAO實現
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlsessionfactory;
public UserDaoImpl(SqlSessionFactory sqlsessionfactory) {
this.sqlsessionfactory = sqlsessionfactory;
}
@Override
public User seleteById(int id) {
SqlSession session = sqlsessionfactory.openSession();
User user = session.selectOne("user.selectById", id);
session.close();
return user;
}
@Override
public List<User> selectByName(String name) {
SqlSession session = sqlsessionfactory.openSession();
List<User> users = session.selectList("user.selectByName", name);
session.close();
return users;
}
}
3、單元測試
public class UserTest {
private SqlSessionFactory sqlsessionfactory;
private UserDao userdao;
@Before
public void testbefore(){
try {
InputStream input = Resources.getResourceAsStream("mybatis.xml");
sqlsessionfactory = new SqlSessionFactoryBuilder().build(input);
userdao = new UserDaoImpl(sqlsessionfactory);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testSeleteById() {
User user = userdao.seleteById(1);
System.out.println(user.getUsername());
}
@Test
public void testSelectByName() {
List<User> users = userdao.selectByName("張三");
for(User user: users){
System.out.println(user.getUsername());
}
}
說明:
1、此時我們的配置檔案的mapper中的namespace仍然沒有規則,是我們隨意命名的。
2、對於介面中的方法名,此時也是和我們的配置檔案中的id名稱沒有一一對應,沒有規則的。
3、對於介面的實現類中,我們要設定屬性 SqlSessionFactory ,這是因為SqlSessionFactory 是可以共用的,而且,在於我們的Spring整合之後,其可以設計問單例模式。
4、對於SqlSession 則是宣告定義在我們的方法中。
5、在利用單元測試時,我們理由註解@Before 進行我們的載入配置檔案,生成sqlsessionfactory ,然後在初始化我們的DAO介面實現時,將我們的sqlsessionfactory 引數傳遞到方法中。
MyBatis Mapper代理開發DAO步驟:
利用Mapper代理開發DAO,就是通過一些規範,將我們的DAO介面和我們的Mapper配置檔案通過一定的關聯建立起聯絡。
利用Mapper代理開發DAO,可以省去我們寫DAO實現的程式碼,但是在省力的同時,我們也必須遵循MyBatis給我們提供的Mapper代理開發規範,這樣的話,我們的MyBatis就可以自動生成mapper介面實現類代理物件:
1、 在mapper.xml中namespace等於mapper介面地址,這裡我們的namespace就有了嚴格的定義:必須為我們的介面的類的全路徑。
2、在我們的 mapper.java介面中的方法名和mapper.xml中statement的id必須嚴格保持一致。
3、mapper.java介面中的方法輸入引數型別和mapper.xml中statement的parameterType指定的型別一致。
4、mapper.java介面中的方法返回值型別和mapper.xml中statement的resultType指定的型別一致。
注意:
1、介面引數只能是一個,因為在配置檔案中只能存在一個parameterType。
2、對於select返回單個物件或者是List集合時,是根據介面的返回值進行呼叫selectOne和selectList方法的。
步驟:
1、編寫DAO介面
2、編寫mapper.xml配置檔案
// mapper介面 編寫
public interface UserDaoMapper {
public User selectById(int id);
public List<User> selectByName(String name);
public void insertUser(User user);
public void deleteUserWithID(int id);
public void updateUserWithID(User user);
}
// 配置檔案 編寫
<?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">
<mapper namespace="com.wf.dao.UserDaoMapper">
<select id="selectById" parameterType="int" resultType="com.wf.model.User">
select * from User where id = #{id}
</select>
<select id="selectByName" parameterType="java.lang.String" resultType="com.wf.model.User">
select * from User where username like '%${value}%'
</select>
<delete id="deleteUserWithID" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
</mapper>
// 測試程式碼
public class UserDaoMapperTest {
private SqlSessionFactory sqlsessionfactory;
@Before
public void testBefore() {
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("mybatis.xml");
sqlsessionfactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void test() {
SqlSession session = sqlsessionfactory.openSession();
UserDaoMapper userDaoMapper = session.getMapper(UserDaoMapper.class);
User user = userDaoMapper.selectById(1);
System.out.println(user.getUsername());
}
}
說明:
1、 namespace按照規範進行設定為介面類的全路徑
2、id屬性一定要和方法名保持一致,
3、由於我們利用了代理模式,所以在獲取資料庫操作時是利用Session的getMapper方法,得到我們的代理物件,然後再利用代理物件去呼叫介面中的方法,而不是,Session的相關selectOne或者selectList方法。,注意上面的測試程式碼中的相關方式。
4、mapper介面方法引數只能有一個,所以對於多參傳遞較為複雜的語句,我們使用的是包裝物件進行開發的。