MyBatis的Dao层开发

本文详细介绍了MyBatis框架中SQLSession、SqlSessionFactoryBuilder和SqlSessionFactory的作用及使用方式。探讨了原始DAO开发方法的问题,并引入Mapper动态代理方式简化开发流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SqlSession使用范围

SqlSessionFactoryBuilder
  • 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
  • 将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
  • 在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
SqlSessionFactory
  • 通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。
  • 将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
SqlSession
  • SqlSession是一个面向用户(程序员)的接口。
  • SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。
  • SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
  • SqlSession最佳应用场合在方法体内,定义成局部变量使用。

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

思路

程序员需要写dao接口和dao实现类。
需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

dao接口
public interface UserDao {
    public User findUserById(Integer id) throws Exception;
    public void insertUser(User user) throws Exception;
    public void deleteUserById(Integer id)throws Exception;
}
dao接口实现类
public class UserDaoImpl implements UserDao {
    private SqlSessionFactory sqlSessionFactory;

    //通过构造方法注入sqlSessionFactory
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
        this.sqlSessionFactory=sqlSessionFactory;
    }
    //通过id查找用户
    @Override
    public User findUserById(Integer id) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        User user=sqlSession.selectOne("test.findUserByid", id);
        sqlSession.close();
        return user;
    }
    //添加用户
    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.insert("test.insertSingleUser", user);
        sqlSession.commit();
        sqlSession.close();
    }

    //通过id删除用户
    @Override
    public void deleteUserById(Integer id) throws Exception {
        SqlSession sqlSession=sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUser", id);
        sqlSession.commit();
        sqlSession.close();
    }

}

测试代码:

public class UserDaoTest {
    private UserDao userDao;

    @Before
    public void setUp() throws IOException {
        //以流的方式获取MyBatis的配置文件
        InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");
        //创建会话工厂,传入MyBatis的配置文件信息
        SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);

        //创建UserDao对象,注入sqlSessionFactory
        userDao=new UserDaoImpl(sqlSessionFactory);
    }

    @Test
    public void testFindUserById() throws Exception{
        System.out.println(userDao.findUserById(27));
    }

    @Test
    public void testDeleteUserById() throws Exception{
        userDao.deleteUserById(31);
    }

    @Test
    public void testInsertUser() throws Exception{
        User user=new User("秦维", new Date(), 2, "南充市");
        userDao.insertUser(user);
    }
}

总结原始 dao开发问题

1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statement的id硬编码了,不得于开发维护。

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

Mapper动态代理方式

实现原理:

Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

思路
  • 程序员需要编写mapper.xml映射文件
  • 程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

第一步:

开发规范:

1.在mapper.xml中namespace等于mapper接口的全路径地址

2.mapper.java接口中的方法名和mapper.xml中statement的id一致

3.mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

4.mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径。将UserMapper.xml放在Dao包里面

定义接口代码:

public interface UserMapper {
    /**
     *  定义增删改查接口
     */
    public void addUser(User user) throws Exception;
    public void deleteUser(Integer id) throws Exception;
    public void updateUser(User user) throws Exception;
    public List<User> findUsers() throws Exception;
}

配置UserMapper.xml文件:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.domarvel.dao.UserMapper">
    <insert id="addUser" parameterType="cn.domarvel.entity.User">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>
    <delete id="deleteUser" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>
    <update id="updateUser" parameterType="cn.domarvel.entity.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
    <select id="findUsers" resultType="cn.domarvel.entity.User">
        select * from user
    </select>
</mapper>

第二步:

在SqlMapConfig.xml中加载mapper.xml

    <!-- 加载映射文件 -->
    <mappers>
        <mapper resource="cn/domarvel/dao/UserMapper.xml"></mapper>
    </mappers>

测试代码:

public class UserMapperTest {
    SqlSessionFactory sqlSessionFactory;

    @Before
    public void init() throws IOException{
        InputStream inputStream=Resources.getResourceAsStream("sqlMapConfig.xml");

        sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
    }

    @Test
    public void addUser() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

        userMapper.addUser(new User("Mapper", new Date(), 1, "南充市"));

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void deleteUser() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

        userMapper.deleteUser(39);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void updateUser() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

        User user=new User("FireBrower", new Date(), 1, "上海市");
        user.setId(27);
        userMapper.updateUser(user);

        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void findUsers() throws Exception{
        SqlSession sqlSession=sqlSessionFactory.openSession();
        UserMapper userMapper=sqlSession.getMapper(UserMapper.class);

        List<User> users=userMapper.findUsers();
        for(User i:users){
            System.out.println(i);
        }

    }
}

/**
* 增删改 必须手动提交事务,否则代码不会生效的。
* 
*/

总结:

selectOne和selectList

动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

namespace

mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。

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

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

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

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

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值