承接上一篇 mybatis入門基礎(一)
看過上一篇的朋友,肯定可以看出,裡面的MybatisService中存在大量的重複程式碼,看起來不是很清楚,但第一次那樣寫,是為了解mybatis的執行步驟,先苦後甜嘛!
一:原始dao開發方法
概要:1.在上篇中搭建好的框價中編寫dao介面和dao實現類
2.向dao介面實現類中注入SqlSessionFactory,在方法體內通過SqlSessionFactory建立sqlSession.
- DAO介面類UserDAO.java
package com.mybatis.dao;
import java.util.List;
import com.mybatis.entity.User;
/**
*
* @ClassName: UserDAO
* @Description: TODO(使用者管理DAO介面)
* @author warcaft
* @date 2015-6-27 下午10:23:42
*
*/
public interface UserDAO {
/** 根據ID查詢使用者資訊*/
public User findUserById(Integer id);
/**根據使用者名稱稱模糊查詢使用者資訊*/
public List<User> findUserByName(String username);
/** 新增使用者*/
public void insertUser(User user);
/** 根據ID刪除使用者*/
public void deleteUser(Integer id);
/** 根據ID更新使用者*/
public void updateUser(User user);
}
- dao實現類UserDaoImpl.java
package com.mybatis.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.mybatis.entity.User;
/**
*
* @ClassName: UserDaoImpl
* @Description: TODO(使用者管理介面的實現類)
* @author warcaft
* @date 2015-6-27 下午10:29:35
*
*/
public class UserDaoImpl implements UserDAO {
private SqlSessionFactory sqlSessionFactory;
// 需要向dao實現類中注入SqlSessionFactory
// 通過構造方法注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
// 釋放資源
sqlSession.close();
return user;
}
@Override
public List<User> findUserByName(String username) {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession
.selectList("test.findUserByName", username);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 執行插入操作
sqlSession.insert("test.insertUser", user);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
@Override
public void deleteUser(Integer id) {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 執行插入操作
sqlSession.delete("test.deleteUser", id);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
@Override
public void updateUser(User user) {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 執行插入操作
sqlSession.update("test.updateUser", user);
// 提交事務
sqlSession.commit();
// 釋放資源
sqlSession.close();
}
}
- JunitTest測試UserDaoImplTest.java
package com.mybatis.dao.test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
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 com.mybatis.dao.UserDaoImpl;
import com.mybatis.entity.User;
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserByIdTest() {
UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(1);
System.out.println(user);
}
@Test
public void findUserByNameTest() {
UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
List<User> list = userDao.findUserByName("小");
System.out.println(list);
}
@Test
public void insertUserTest() {
UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
User user = new User();
user.setUsername("張三丰");
user.setSex("1");
user.setBirthday(new Date());
user.setAddress("武當山");
userDao.insertUser(user);
}
@Test
public void deleteUserTest() {
UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
userDao.deleteUser(8);
}
@Test
public void updateUserTest() {
UserDaoImpl userDao = new UserDaoImpl(sqlSessionFactory);
User user = new User();
user.setId(1);
user.setUsername("王六");
user.setSex("2");
user.setAddress("天津");
user.setBirthday(new Date());
userDao.updateUser(user);
}
}
才上面的程式碼可以看出,比起之前那個MybatisService.java類裡面的內容稍微清晰了點吧。但依然存在以下幾個問題:
1.dao介面中存在大量模版方法,能否把這些程式碼提出來,減少我們的工作量
2.呼叫sqlSession方法時將statement的id硬編碼了
3.呼叫sqlSession傳入的變數,由於sqlSession方法使用泛型,即使變數型別傳入錯誤,在編譯階段也不報錯,不利於程式開發。
所以我們帶著這幾個問題看看mapper代理開發的方法,是否能解決這些問題呢?
二:mapper代理方法(只需要mapper介面,相當於dao介面)
1.概要:(1).編寫XXXmapper.xml的對映檔案
(2).編寫mapper介面需要遵循一些開發規範,mybatis可以自動生成mapper介面實現類代理物件。
2.開發規範:
(1).在XXXmapper.xml中namespace等於mapper介面地址;
(2).XXXmapper.java介面中的方法和mapper.xml中的statement的Id一致。
(3).mapper.java介面中的方法輸入引數和mapper.xml中statement的parameterType指定的型別一致。
(4).mapper.java介面中的方法的返回值型別和mapper.xml中statement的resultType指定的型別一致。
小結:以上的開發規範主要是對下面的程式碼進行統一生成
SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", id);
......
3.UserMapper.java類程式碼
package com.mybatis.mapper;
import java.util.List;
import com.mybatis.entity.User;
/**
*
* @ClassName: UserDAO
* @Description: TODO(使用者管理mapper介面)
* @author warcaft
* @date 2015-6-27 下午10:23:42
*
*/
public interface UserMapper {
/** 根據ID查詢使用者資訊 */
public User findUserById(int id);
/** 根據使用者名稱稱模糊查詢使用者資訊 */
public List<User> findUserByName(String username);
/** 新增使用者 */
public void insertUser(User user);
/** 根據ID刪除使用者 */
public void deleteUser(Integer id);
/** 根據ID更新使用者 */
public void updateUser(User user);
}
4.將原來的User.xml拷貝修改名稱為UserMapper.xml,只需修改此行程式碼即可
<!-- namespace名稱空間,作用就是對sql進行分類化的管理,理解為sql隔離
注意:使用mapper代理開發時,namespace有特殊作用,namespace等於mapper介面地址
-->
<mapper namespace="com.mybatis.mapper.UserMapper">
5.在SqlMapConfig.xml中載入UserMapper.xml
<!-- 載入對映檔案 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
6.Junit測試UserMapperTest.java
package com.mybatis.dao.test;
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.mybatis.entity.User;
import com.mybatis.mapper.UserMapper;
public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
// 此方法是在執行findUserByIdTest之前執行
@Before
public void setUp() throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
// 建立SqlSessionFcatory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 建立Usermapper物件,mybatis自動生成mapper代理物件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void testFindUserByName() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 建立Usermapper物件,mybatis自動生成mapper代理物件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.findUserByName("小");
System.out.println(list);
sqlSession.close();
}
@Test
public void testDeleteUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 建立Usermapper物件,mybatis自動生成mapper代理物件
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(6);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testInsertUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 建立Usermapper物件,mybatis自動生成mapper代理物件
User user = new User();
user.setUsername("者別");
user.setSex("1");
user.setAddress("蒙古乞顏部落");
user.setBirthday(new Date());
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testUpdateUser() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 建立Usermapper物件,mybatis自動生成mapper代理物件
User user = new User();
user.setId(11);//必須設定Id
user.setUsername("神箭手者別");
user.setSex("1");
user.setAddress("蒙古乞顏部落");
user.setBirthday(new Date());
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
mapper.updateUser(user);
sqlSession.commit();
sqlSession.close();
}
}
7.小結
(1).代理物件內部呼叫selectOne()和selectList():如果mapper物件返回單個pojo物件(非集合物件)代理物件內部通過selectOne查詢資料庫,如果mapper方法返回集合物件,代理物件內部通過selectList查詢資料庫。
(2).mapper介面中的方法引數只能有一個是否影響系統開發:
mapper介面方法引數只能有一個,系統是否不利於維護?
回答:系統框架中,dao層的程式碼是被業務層公用的。機試mapper介面只有一個引數,可以使用包裝型別的pojo滿足不同的業務方法的需求。