Mybatis----开发dao

4.mybatis开发dao的方法

4.1SqlSession使用范围

4.1.1SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory。

将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

4.1.2SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例)。

将来mybatis和spring整合后,使用单例模式管理SqlSessionFactory。

4.1.3SqlSession

SqlSession是一个面向用户(程序员)的接口。

SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。

SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

4.2原始dao开发方法(程序员需要写dao接口和dao实现类)

4.2.1思路

程序员需要写dao接口和dao实现类。

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession。

4.2.2 dao接口

package com.xjs.mybatis.dao;

import com.xjs.mybatis.po.User;

/**
 * dao接口,用户管理
 * @author hp
 *
 */
public interface UserDao {
    
    //根据id查询用户信息
    public User findUserById(int id) throws Exception;
    
    //添加用户信息
    public void insertUser(User user) throws Exception;
    
    //删除用户信息
    public void deleteUser(int id) throws Exception;
}

4.2.3 dao接口实现类

package com.xjs.mybatis.dao;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

import com.xjs.mybatis.po.User;

/**
 * dao接口实现类
 * @author hp
 *
 */
public class UserDaoImpl implements UserDao{

    //需要向dao实现类中注入SqlSessionFactory
    //这里通过构造函数注入
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
        this.sqlSessionFactory=sqlSessionFactory;
    }
    
    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        User user = sqlSession.selectOne("test.findUserById", 35);
        //释放资源
        sqlSession.close();
        return user;
    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.insert("test.insertUser", user);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUser", id);
        sqlSession.commit();
        sqlSession.close();
    }
}

4.2.4单元测试

package com.xjs.mybatis.dao;

import static org.junit.Assert.*;

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 com.xjs.mybatis.po.User;

public class UserDaoImplTest {

    private SqlSessionFactory sqlSessionFactory;
    
    //此方法在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        //创建SqlSessionFactory
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }

    //单元测试
    @Test
    public void testFindUserById() throws Exception {
        //创建UserDao的对象
        UserDao userDao=new UserDaoImpl(sqlSessionFactory);
        
        //调用UserDao的方法
        User user = userDao.findUserById(1);
        System.out.println(user);
    }

}

4.2.5总结原始dao开发问题

1、dao接口实现类方法中存在大量的模板方法(例:SqlSession sqlSession=sqlSessionFactory.openSession();),设想能否将这些代码提取出来,减轻程序员的工作量。

2、调用sqlSession方法时将statement的id硬编码了。

3、调用sqlSession方法时传入的变量,由于sqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

4.3mapper代理方法(程序员只需要写mapper接口(相当于dao接口))

4.3.1思路(mapper代理开发规范)

程序员还需要编写mapper.xml映射文件。

 程序员编写mapper接口(相当于dao接口),需要遵循的一些开发规范。mybatis可以自动生成mapper接口实现类代理对象

开发规范:

1、在mapper.xml中namespace等于mapper(dao)接口地址。

2、mapper.java(dao)接口中的方法名很mapper.xml(映射文件)中statement的id一致。

3、mapper.java(dao)接口中的方法输入参数类型和mapper.xml(映射文件)中statement的parameterType指定的类型一致。

4、mapper.java(dao)接口中的方法返回值类型和mapper.xml(映射文件)中statement的resultType指定的类型一致。

总结:

以上开发规范主要是对下边的代码进行统一生成:

User user = sqlSession.selectOne("test.findUserById", 35);

 sqlSession.insert("test.insertUser", user);

等。。。

 4.3.2userMapper.java(dao接口)

package com.xjs.mybatis.mapper;

import java.util.List;

import com.xjs.mybatis.po.User;

/**
 * Mapper接口,相当于dao接口,用户管理
 * @author hp
 *
 */
public interface UserMapper {
    //根据id查询用户信息
    public User findUserById(int id)throws Exception;
    
    //根据用户名查询用户列表
    public List<User> findUserByName(String name)throws Exception;
    
    //添加用户信息
    public void insertUser(User user)throws Exception;
    
    //删除用户信息
    public void deleteUser(int id)throws Exception;
    
}

 4.3.3UserMapper.xml映射文件

    <select id="findUserByName" parameterType="java.lang.String" resultType="com.xjs.mybatis.po.User">
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>

 4.3.4在SqlMapConfig.xml配置文件中加载映射文件

 4.3.5测试

private SqlSessionFactory sqlSessionFactory;
    
    //此方法在执行testFindUserById之前执行
    @Before
    public void setUp() throws Exception {
        //创建SqlSessionFactory
        String resource = "SqlMapConfig.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void testFindUserByName() throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        
        //创建UserMapper(dao接口)对象,mybatis自动生成dao接口实现类的代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        
        //调用userMapper的方法
        List<User> list = userMapper.findUserByName("小明");
        sqlSession.close();
        System.out.println(list);
    }

 4.3.6一些问题的总结

 4.3.6.1代理对象内部调用selectOne或selectList

如果mapper(dao接口)中方法返回单个POJO对象(非集合对象),代理类对象内部通过selectOne查询数据库。

如果mapper(dao接口)中方法返回集合对象,代理类对象内部通过selectList查询数据库。 

 4.3.6.2 mapper接口方法参数只能有一个是否影响系统开发

mapper(dao)接口方法参数只能有一个,系统是否不利于扩展维护。

系统框架中,dao层的代码是被业务层公用的。

即使mapper接口只有一个参数,可以使用包装类型的POJO满足不同的业务方法的需求。

注意:持久层方法的参数可以是包装类型,service方法中建议不要使用包装类型(不利于业务层的可扩展)

原文地址:https://www.cnblogs.com/xjs1874704478/p/11234033.html