Mybatis 开发dao方法

本文介绍了Mybatis中SqlSession的使用,包括SqlSessionFactoryBuilder和SqlSessionFactory的创建,以及SqlSession作为线程不安全接口的应用。讨论了原始DAO开发方法存在的问题,如重复编码和硬编码ID,然后详细阐述了Mapper代理方法的开发规范,如namespace与接口地址匹配,方法名与statement ID一致,以及参数和返回类型的对应,以提高开发效率和代码可维护性。

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

首先,SqlSession 使用范围:

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

原始dao开发方法:

原始dao开发方法,程序员需要编写dao接口和dao实现类,在dao接口的实现类中注入SqlsessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

(1)dao接口:
与mapper映射中的id一一对应,声明出接口,那个简单地例子来说:

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;
}

(2)dao接口的实现类:实现dao接口的方法,并将SqlsessionFactory注入:

public class UserDaoImpl implements UserDao{
    //需要向dao实现类中注入SqlSessionFactory
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sessionFactory) {
        this.sqlSessionFactory = sessionFactory;
    }
    @Override
    public User findUserById(int 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.selectOne("test.InsertUser",user);
        //提交事务
        sqlSession.commit();
        //释放资源
        sqlSession.close();

    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        //执行插入操作
        sqlSession.selectOne("test.deleteUser",36);

        sqlSession.commit();

        sqlSession.close();
    }

从上述可以看出在mybatis中存在的问题:
首先,在dao的实现方法中存在重复编码,每次都需要重新定义sqlsession.
其次,调用sqlsession的数据库操作方法存在硬编码,需要指定statement的id,这样不利于开发维护。
还有就是在调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
比如:

sqlSession.selectOne("test.deleteUser",36);

这块36传入参数的话就属于是泛型,这块接收的是object对象,所以你即使对象类型传入错误也不会报错。

mapper代理方法

针对上面出现的问题,我们可以用mapper代理的方法来返回进行处理。

mapper代理方法开发规范

1、在mapper.xml中namespace等于mapper接口地址

<mapper namespace="com.mapper.UserMapper">

2、mapper.java接口中的方法名和mapper.xml中statement的id一致
就是说在userMapper.java中的方法名应该和userMapper.xml中的statement id一致

<select id="findUserByID" parameterType="int" resultType="com.po.User">

//根据id查询用户信息
public User findUserByID(int id) throws Exception;

3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
这两句话的比较好理解,就是要保证参数类型和返回结果类型一致。

比较完整的代码:
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="com.dy.mapper.UserMapper">

<select id="findUserByID" parameterType="int" resultType="com.dy.po.User">
select * from user
where id = #{id}
</select>
</mapper>

简单java对象:User

package com.dy.po;

import java.util.Date;

public class User {
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public Date getBirthday() {
        return birthday;
    }
    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString(){
        return "id : " + id + "userName : " + username ;
    } 

}

UserMapper.java接口:

package com.dy.mapper;

import com.dy.po.User;

public interface UserMapper {
    //根据id查询用户信息
    public User findUserByID(int id) throws Exception;

}

测试文件:

package com.dy.test;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import com.dy.mapper.UserMapper;
import com.dy.po.User;

public class UserMapperTest {

    private SqlSessionFactory sessionFactory;
    @Before
    public void setUp() throws Exception{
        //此方法实在testFindUserById之前执行的

        //创建SqlSessionFactory

        String resource = "SqlMapConfig.xml";

        InputStream inputStream = Resources.getResourceAsStream(resource);

        sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

    }

    @Test
    public void test() throws Exception {

        SqlSession sqlSession = sessionFactory.openSession();

        //创建userMapper对象,mybatis自动生成mapper代理对象
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //调用UserMapper的方法
        User user = userMapper.findUserByID(1);
        //代理对象内部调用selectOne查询数据库
        System.out.println(user);

    }

}

最重要的,在SqlMapConfig.xml中加载映射文件:

<!-- 加载映射文件  -->
        <mapper resource = "com/dy/sqlMapper/userMapper.xml"/>
    </mappers>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值