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不是通用的接口
原文地址:https://www.cnblogs.com/yaowen/p/4869358.html