原始dao開發方法
程序員寫代碼的時候,需要寫dao
接口和dao
實現類。而且還需要向dao實現類中注入SqlSessionFactory
,在方法體內通過SqlSessionFactory
創建SqlSession
。下面舉個栗子:
dao的接口
package cn.itcast.mybatis.dao;
import java.util.List;
import cn.itcast.mybatis.po.User;
/**
* dao接口,用戶管理
* @author Administrator
*
*/
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;
}
dao的實現類
package cn.itcast.mybatis.dao;
/**
* dao接口實現類
*/
import java.util.Date;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import cn.itcast.mybatis.mapper.UserMapper;
import cn.itcast.mybatis.po.User;
public class UserDaoImpl implements UserDao {
//需要向dao實現類中注入SqlSessionFactory
//這裏通過構造方法注入
private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory=sqlSessionFactory;
}
public User findUserById(int id) throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=sqlSession.selectOne("test.findUserById",id);
sqlSession.close();
return user;
}
public List<User> findUserByName(String name) throws Exception{
SqlSession sqlSession=sqlSessionFactory.openSession();
List<User> list=sqlSession.selectList("test.findUserByName",name);
sqlSession.close();
return list;
}
public void insertUser(User user) throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser",user);
//提交事務
sqlSession.commit();
sqlSession.close();
}
public void deleteUser(int id) throws Exception {
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.insert("test.deleteUser",id);
//提交事務
sqlSession.commit();
sqlSession.close();
}
}
測試程序
package cn.itcast.mybatis.dao;
import static org.junit.Assert.*;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import cn.itcast.mybatis.po.User;
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
//配置文件
String resource="SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream=Resources.getResourceAsStream(resource);
// 使用SqlSessionFactoryBuilder從xml配置文件中創建SqlSessionFactory
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() throws Exception{
//構造UserDao對象
UserDao userDao=new UserDaoImpl(sqlSessionFactory);
//調用UserDao的方法
User user=userDao.findUserById(1);
System.out.println(user);
}
}
原始dao開發問題
- 在dao的接口實現類中出現大量的模板方法,比如上面的例子中每個方法中都有opensession,closesession的方法。
- 調用SqlSession方法時,將statement的Id硬編碼了,每個方法中都需要寫statement Id,如果名稱發生變化,不利於修改。
- 調用SqlSession方法時,由於sqlSession的方法(selectOne,selectList…)使用泛型,即使傳入的變量類型錯誤,在編譯階段也不報錯。不利於開發。
Mapper代理方法
Mapper接口開發方法只需要開發Mapper接口(相當於Dao接口),由Mybatis框架根據接口定義創建接口的動態代理對象,代理對象的方法體,同上邊Dao接口實現類方法。
Mapper接口開發需要遵循以下規範:
1、 Mapper.xml文件中的namespace與mapper接口的類路徑相同。
2、 Mapper接口方法名和Mapper.xml中定義的每個statement的id相同
3、Mapper接口方法的輸入參數類型和mapper.xml中定義的每個sql 的parameterType的類型相同
4、 Mapper接口方法的輸出參數類型和mapper.xml中定義的每個sql的resultType的類型相同
以上的規範主要是對下邊的代碼進行統一生成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
Mapper.xml(映射文件)
定義mapper
映射文件UserMapper.xml
(內容同Users.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">
<mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
Mapper.java(接口文檔)
/**
* 用戶管理mapper
*/
Public interface UserMapper {
//根據用戶id查詢用戶信息
public User findUserById(int id) throws Exception;
//查詢用戶列表
public List<User> findUserByUsername(String username) throws Exception;
//添加用戶信息
public void insertUser(User user)throws Exception;
}
接口的定義有如下特點:
- Mapper接口方法名和Mapper.xml中定義的statement的id相同
- Mapper接口方法的輸入參數類型和mapper.xml中定義的statement的parameterType的類型相同
- Mapper接口方法的輸出參數類型和mapper.xml中定義的statement的resultType的類型相同
加載UserMapper.xml文件
修改SqlMapConfig.xml文件:
<!-- 加載映射文件 -->
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
測試
Public class UserMapperTest extends TestCase {
private SqlSessionFactory sqlSessionFactory;
protected void setUp() throws Exception {
//mybatis配置文件
String resource = "sqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//使用SqlSessionFactoryBuilder創建sessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
Public void testFindUserById() throws Exception {
//獲取session
SqlSession session = sqlSessionFactory.openSession();
//獲取mapper接口的代理對象
UserMapper userMapper = session.getMapper(UserMapper.class);
//調用代理對象方法
User user = userMapper.findUserById(1);
System.out.println(user);
//關閉session
session.close();
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> list = userMapper.findUserByUsername("張");
System.out.println(list.size());
}
Public void testInsertUser() throws Exception {
//獲取session
SqlSession session = sqlSessionFactory.openSession();
//獲取mapper接口的代理對象
UserMapper userMapper = session.getMapper(UserMapper.class);
//要添加的數據
User user = new User();
user.setUsername("張三");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("北京市");
//通過mapper接口添加用戶
userMapper.insertUser(user);
//提交
session.commit();
//關閉session
session.close();
}
}