从上一篇可以看出,MybatisService中存在大量的重复代码
userDao.java
package com.imau.dao;
import com.imau.entity.User;
import java.util.List;
public interface UserDao {
/** 根据ID查询用户信息*/
public User findUserById(Integer id);
/**根据用户名称模糊查询用户信息*/
public List findUserByName(String username);
/** 添加用户*/
public void insertUser(User user);
/** 根据ID删除用户*/
public void deleteUser(Integer id);
/** 根据ID更新用户*/
public void updateUser(User user);
}
UserDaoImpl.java
package com.imau.dao;
import com.imau.entity.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import java.util.List;
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
// 需要向dao实现类中注入SqlSessionFactory
// 通过构造方法注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
super();
this.sqlSessionFactory=sqlSessionFactory;
}
@Override
public User findUserById(Integer id) {
// 创建SqlSession
SqlSession sqlSession=this.sqlSessionFactory.openSession();
// 执行查询逻辑
User user=sqlSession.selectOne("test.findUserById",id);
// 释放资源
sqlSession.close();
return user;
}
@Override
public List findUserByName(String username) {
SqlSession sqlSession=this.sqlSessionFactory.openSession();
List list=sqlSession.selectList("test.findUserByName",username);
sqlSession.commit();
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) {
SqlSession sqlSession=this.sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void deleteUser(Integer id) {
SqlSession sqlSession=this.sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser",id);
sqlSession.commit();
sqlSession.close();
}
@Override
public void updateUser(User user) {
SqlSession sqlSession=this.sqlSessionFactory.openSession();
sqlSession.delete("test.updateUser",user);
sqlSession.commit();
sqlSession.close();
}
}
UserDaoImplTest.java
package com.imau.test;
import com.imau.dao.UserDaoImpl;
import com.imau.entity.User;
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 java.io.InputStream;
import java.util.Date;
import java.util.List;
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 list=userDao.findUserByName("张");
System.out.println(list);
}
@Test
public void insertUserTest(){
UserDaoImpl userDao=new UserDaoImpl(sqlSessionFactory);
User user=new User();
user.setUsername("赵小刀");
user.setSex("女");
user.setBirthday(new Date());
user.setAddress("河北");
userDao.insertUser(user);
}
@Test
public void deleteUserTest(){
UserDaoImpl userDao=new UserDaoImpl(sqlSessionFactory);
userDao.deleteUser(26);
}
@Test
public void updateUserTest(){
UserDaoImpl userDao=new UserDaoImpl(sqlSessionFactory);
User user=new User();
user.setId(10);
user.setUsername("张思");
user.setSex("男");
user.setAddress("张家口");
user.setBirthday(new Date());
userDao.updateUser(user);
}
}
从上述代码可以看出,比起之前那个MybatisService.java类里面的内容稍微清晰了点,但依然存在以下几个问题:
1. dao接口中存在大量模版方法,能否把这些代码提出来,减少我们的工作量
2. 调用sqlSession方法时将statement的id硬编码了
3. 调用sqlSession传入的变量,由于sqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序开发。
所以我们带着这几个问题看看mapper代理开发的方法,是否能解决这些问题呢?
1.概要:(1).编写XXXmapper.xml的映射文件
(2).编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
2.开发规范:
UserMapper.java
package com.imau.mapper;
import com.imau.entity.User;
import java.util.List;
public interface UserMapper {
/** 根据ID查询用户信息 */
public User findUserById(int id);
/** 根据用户名称模糊查询用户信息 */
public List findUserByName(String username);
/** 添加用户 */
public void insertUser(User user);
/** 根据ID删除用户 */
public void deleteUser(Integer id);
/** 根据ID更新用户 */
public void updateUser(User user);
}
将原来的User.xml拷贝修改名称为UserMapper.xml,只需修改此行代码即可
<mapper namespace="com.imau.mapper.UserMapper">
在SqlMapConfig.xml中加载UserMapper.xml
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
UserMapperTest.java
package com.imau.test;
import com.imau.entity.User;
import com.imau.mapper.UserMapper;
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 java.io.InputStream;
import java.io.PushbackInputStream;
import java.util.Date;
import java.util.List;
public class UserMapperTest {
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 testFindUserById(){
SqlSession sqlSession=sqlSessionFactory.openSession();
// 创建Usermapper对象,mybatis自动生成mapper代理对象
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
User user=mapper.findUserById(16);
System.out.println(user);
sqlSession.close();
}
@Test
public void testFindUserByName(){
SqlSession sqlSession=sqlSessionFactory.openSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
List list=mapper.findUserByName("张");
System.out.println(list);
sqlSession.close();
}
@Test
public void testDeleteUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.deleteUser(22);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testInsertUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=new User();
user.setId(35);
user.setUsername("魏珍");
user.setSex("女");
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();
User user=new User();
user.setId(25);
user.setUsername("李溪芮");
user.setSex("女");
user.setAddress("大连市");
user.setBirthday(new Date());
UserMapper mapper=sqlSession.getMapper(UserMapper.class);
mapper.updateUser(user);
sqlSession.commit();
sqlSession.close();
}
}
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。