mybatis09
1mybatis开发dao的方法 1.1SqlSession作用范围 是使用局部变量、成员变量,还是形参? 1.1.1SqlSessionFactoryBuilder SqlSessionFactoryBuilder不是单例是以工具类方式来使用,用来创建sqlSessionFactory,需要创建sqlSessionFactory就new一个SqlSessionFactoryBuilder,之后就一直没用了。 1.1.2sqlSessionFactory 正常开发时,new一次,以单例方式管理sqlSessionFactory,整个系统运行过程中sqlSessionFactory只有一个实例,将来和spring整合后由spring以单例方式管理sqlSessionFactory。 1.1.3SqlSession sqlSession是一个面向用户(程序员)的接口,程序员调用sqlSession的接口方法进行操作数据库。 sqlSession能否以单例 方式使用?? 由于sqlSession的成员变量有数据字段,多线程是共享成员变量的数据,是线程不安全,所以sqlSession最佳应用范围在方法体内,如果sqlSession定义成成员变量则多个线程会共享该成员变量,在方法体内定义局部变量使用sqlSession,因为每个线程对于方法中的内存空间是互不影响的。
1原始dao开发方式
1. 程序员需要写dao接口和dao 的实现 类 1.1.1dao接口
package cn.itcast.mybatis.dao; import java.util.List; import cn.itcast.mybatis.po.User; public interface UserDao { //根据id查询用户信息,异常抛给了service public User findUserById(int id) throws Exception; //根据用户名称模糊查询用户列表 public List<User> findUserByUsername(String username) throws Exception; //插入用户 public void insertUser(User user) throws Exception; }
dao接口实现
package cn.itcast.mybatis.dao; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import cn.itcast.mybatis.po.User; public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory; // spring将SqlSessionFactory注入 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { // 创建SqlSession,SqlSession有sql语句,所以要在方法内部才能没有线程安全问题。 SqlSession sqlSession = sqlSessionFactory.openSession(); // 根据id查询用户信息 User user = sqlSession.selectOne("test.findUserById", id); //与spring整合之后不需要手动关闭 sqlSession.close(); return user; } @Override public List<User> findUserByUsername(String username) throws Exception { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> list = sqlSession.selectList("test.findUserByName", username); sqlSession.close(); return list; } @Override public void insertUser(User user) throws Exception { // 创建SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert("test.insertUser", user); // sqlSession.commit(); sqlSession.close(); } }
测试:
package cn.itcast.mybatis.dao; import java.io.IOException; 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 init() throws IOException { // 配置文件(SqlMapConfig.xml) String resource = "SqlMapConfig.xml"; // 加载配置文件到输入 流 InputStream inputStream = Resources.getResourceAsStream(resource); // 创建会话工厂 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() throws Exception { UserDao userDao = new UserDaoImpl(sqlSessionFactory); User user = userDao.findUserById(1); System.out.println(user); } }
问题:
1.1.1上边原始dao开发方式的问题 1 dao的实现类中存在重复代码,整个mybatis操作的过程的整个代码模板就重复了(先创建sqlsession、调用sqlsession的方法、关闭sqlsession)都是这3中模版。 2、dao的实现 类中存在硬编码,调用sqlsession方法时将statement的id硬编码(sqlSession.selectList("test.findUserByName", username)的test.findUserByName硬编码 )不利于系统维护。
mapper代理的方式解决的问题,
程序员只需要写dao接口,dao接口实现对象由mybatis自动生成代理对象,不用程序员写了,就不存在重复代码,实现类不用写可以封装了,将重代码封装起来。
本身dao在三层架构中就是一个通用的接口。Service不是通用的接口。