1、mybatis开发dao的方法:
(1)SqlSession使用范围
通过SqlSessionFactoryBuilder创建会话工SqlSessionFactory
将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder
在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可
通过SqlSessionFactory创建SqlSession,使用单例模式管理(工厂一旦创建,使用一个实例)。
将mybatis和spring整合后,使用单例模式管理SqlSessionFactory
SqlSession:
SqlSession是一个面向用户(程序员)的接口。
SqlSession中提供了很多操作数据库的方法,如:selectOne(返回单个对象),selectList(返回单个或多个对象)
SqlSession是线程不安全,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性
SqlSession最佳应用场合在方法体内,定义成局部变量。
2、原始dao开发方法(程序员需要写dao接口和dao实现类)
(1) 程序员需要写dao接口和dao实现类
(2) 需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession
2.1 dao接口
//查询用户
public abstract User findUser(int id);
//添加用户
public abstract void insertUser(User user);
//删除用户
public abstract void delectUser(int id);
2.2 dao接口实现类
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById",id);
//释放资源
sqlSession.close();
return user;
2.3 测试:
项目右键-new resrouce folder-创建test 在UserDaoImpl中选择一个方法进行测试
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
/**
* Test method for {@link edu.tjut.dao.UserDaoImpl#findUser(int)}.
* @throws IOException
*/
//此方法是在执行testFindUser()之前执行
@Before
public void setUp() throws IOException {
//创建sqlSessionFactory
//mybatis配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUser() {
//创建UserDao的对象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
//调用UserDao的方法
User user = userDao.findUser(1);
System.out.println(user);
}
}
2.4 总结:
1)dao接口实现类方法中存在大量的模板方法,设想是否将这些代码提取出来,大大减轻程序员的工作量。
2)调用sqlSession方法时将statement的id硬编码了
3)调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发
2.5 总结原始dao开发问题
(1) dao接口实现类方法中存在大量模板方法。设想能否将这些代码
(2)调用SqlSession方法时将statement的id硬编码了。
(3)调用SqlSession方法时传入的变量,由于SqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
3、mapper代理方法(程序员只需要mapper接口,相当于dao接口)
3.1 思路:
3.1.1 程序员只需要编写mapper.xml映射文件
3.1.2 程序员只需要编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
开发规范:
1、在mapper.xml中namespace等于mapper接口地址
namespace命名空间,作用就是对SQL进行分类话管理,理解成SQL隔离
注意:使用mapper代理方法开发,namespace有特殊的重要作用,namespace等于mapper接口地址
<mapper namespace="edu.tjut.mapper.UserMapper">
2、mapper.java接口中的方法名和mapper.xml中statement的id一致
3、mapper.java接口中的方法输入的参数类型和mapper.xml中statement的parameterType指定的类型一致
4、mapper.java接口中的方法返回值的类型和mapper.xml中statement的resultType指定的类型一致。
(2)mapper.xml
<select id="findUserById" parameterType="int" resultType="edu.tjut.pojo.User">
select * from user where id = #{id}
</select>
(3) mapper.java
//根据id查询用户
public User findUserById(int id) throws Exception;
总结:
以上开发规范主要是对下面的代码进行统一生成
User user = sqlSession.selectOne(“test.findUserById”,id);
sqlSession.insert(“test.insertUser”, user);
……
其实,就是通过上述的规范代码生成mapper接口实现类的代理对象(也就是UserDaoImpl的内容)
4、测试:
注意SqlMapConfig中加载映射文件:
<!-- 加载映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>
测试代码:
@Test
public void testFindUserById() {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user = userMapper.findUserById(7);
System.out.println(user);
}
5、代理对象内部调用selectOne或selectList
如果mapper方法返回单个的pojo对象,代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库
6、mapper 接口方法参数只能有一个,系统是否不利于扩展维护
系统框架中,dao层的代码是被业务层公用的
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求
注意:持久层方法的参数可以包装类型、map…,service方法中建议不要使用包装类型(不利于业务层的可扩展性)
共有条评论 网友评论