在【004】中,细心的同学可能会发现,在增删改查几个函数中,存在大量的重复的代码,如下这段代码。
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 释放资源
sqlSession.close();
上面的这段代码,在四个函数中,均存在。介绍mybatis开发DAO之前,先介绍下SqlSession的使用。
1. SqlSessionFactoryBuilder
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
2. SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
3. SqlSession
SqlSession是一个面向用户(程序员)的接口。SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。
SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。SqlSession最佳应用场合在方法体内,定义成局部变量使用。
————————————————————————————————————————————————————————————————————
现在,介绍mybatis开发DAO的原始开发方法,所谓原始开发方法是指程序员需要写dao接口和dao实现类,简单的思路就是:需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。
首先,来看下,前几章下来后,我们的项目代码结构,本章,将在过去的基础上继续开发。
【1】创建dao接口,路径为:src\main\java\dao\UserDao.java,代码如 下:
//根据id查询用户信息
User findUserById(int id) throws Exception;
//根据id插入用户
void insertUserById(User user) throws Exception;
//根据id修改用户信息
void deleteUserById(int id) throws Exception;
【2】创建接口实现类UserDaoImpl.java。路径为:src\main\java\dao\UserDaoImpl.java,代码如下:
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
// 需要向dao实现类中注入SqlSessionFactory
// 这里通过构造方法注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserById(int id) throws Exception{
// 通过工厂得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过SqlSession操作数据库
// 第一个参数:映射文件中statement的id,等于=namespace+"."+statement的id
// 第二个参数:指定和映射文件中所匹配的parameterType类型的参数
// sqlSession.selectOne结果 是与映射文件中所匹配的resultType类型的对象
// selectOne查询出一条记录
User user = sqlSession.selectOne("test.findUserById",id);
// 释放资源
sqlSession.close();
return user;
}
public List<User> findUserByUsername(String name)throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByUsername",name);
// 释放资源
sqlSession.close();
return list;
}
public void insertUserById(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
sqlSession.insert("test.insertUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
public void deleteUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行插入操作
sqlSession.insert("test.deleteUser", id);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
【3】完成以上两个部分后,开始创建测试代码,进行测试,这里,我们只对findUserById()进行测试。在测试文件中,写入如下代码:
public class UserDaoImplTest {
//创建sqlsessionfactory工厂
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void findUserById() throws Exception {
//创建UserDao对象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
// 调用UserDao的方法
User user = userDao.findUserById(22);
System.out.println(user);
}
}
以上代码将会查询id=22的用户信息。
大功告成了,剩下的测试方法跟之前章节的是一个道理。
下面简单总结原始方法开发dao的问题。
【总结】
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2、调用sqlsession方法时将statement的id硬编码了
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
在下一章中,我们将会介绍mybatis开发DAO的另外一种方式,基于mapper代理的开发方式。