Mybatis DAO开发

使用Mybatis开发Dao,通常有两个方法,即

  1. 原始Dao开发方法
  2. Mapper代理开发方法

原始DAO开发方式

原始Dao开发方法需要程序员编写Dao接口和Dao实现类,无非就是在Dao实现类里面调用映射文件里面定义的sql而已。

工具类

package org.example.utils;

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 java.io.IOException;
import java.io.InputStream;

/**
 * Mybatis工具类
 */
public class MybatisUtil {
    private MybatisUtil(){}

    /**
     * SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理
     */
    private static SqlSessionFactory sqlSessionFactory = null;

    static {
        //1.读取Mybatis的全局配置文件
        try {
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //2.获取SqlSessionFactory
            //SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder对象了
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 获取SqlSession的方法
     */
    public static SqlSession getSession(){
        return sqlSessionFactory.openSession(true);
    } //true表示自动提交事务

}

实体类

package org.example.entity;

/**
* Dept实体类
*/
public class Dept {
private Integer deptno;
private String dname;
private String loc;
public Integer getDeptno() {
return deptno;
}
public void setDeptno(Integer deptno) {
this.deptno = deptno;
}
    public String getDname() {
        return dname;
    }
    public void setDname(String dname) {
        this.dname = dname;
    }
    public String getLoc() {
        return loc;
    }
    public void setLoc(String loc) {
        this.loc = loc;
    }
    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                '}';
    }
}

接口

Mapper接口中各个方法的形参就是要长给SQL语句的参数。

Mapper接口中查询方法的返回值就是SQL语句的输出参数映射。

package org.example.dao;

import org.example.entity.Dept;
import java.util.List;

public interface DeptDao {
    /**
     * 查询所有部门
     * @return
     */
    List<Dept> select();

    /**
     * 根据id查询部门信息
     * @param deptno
     * @return
     */
    Dept selectById(Integer deptno);

    /**
     * 新增部门信息
     * @param dept
     * @return
     */
    int insert(Dept dept);

    /**
     * 更新部门信息
     * @param dept
     * @return
     */
    int update(Dept dept);

    /**
     * 根据id删除部门信息
     * @param deptno
     * @return
     */
    int delete(Integer deptno);
}

实现类 

package org.example.dao.impl;

import org.apache.ibatis.session.SqlSession;
import org.example.dao.DeptDao;
import org.example.entity.Dept;
import org.example.utils.MybatisUtil;

import java.util.List;

public class DeptDaoImpl implements DeptDao {
    @Override
    public List<Dept> select() {
        SqlSession sqlSession = MybatisUtil.getSession();
        List<Dept> depts = sqlSession.selectList("dept.select");
        sqlSession.close();
        return depts;
    }

    @Override
    public Dept selectById(Integer deptno) {
        SqlSession sqlSession = MybatisUtil.getSession();
        Dept dept = sqlSession.selectOne("dept.selectById", 10);
        sqlSession.close();
        return dept;
    }

    @Override
    public int insert(Dept dept) {
        SqlSession sqlSession = MybatisUtil.getSession();
        int result = sqlSession.insert("dept.insert", dept);
        sqlSession.close();
        return result;
    }

    @Override
    public int update(Dept dept) {
        SqlSession sqlSession = MybatisUtil.getSession();
        int result = sqlSession.update("dept.update", dept);
        sqlSession.close();
        return result;
    }

    @Override
    public int delete(Integer deptno) {
        SqlSession sqlSession = MybatisUtil.getSession();
        int result = sqlSession.delete("dept.delete", deptno);
        sqlSession.close();
        return result;
    }
}

mapper文件

<?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="dept">

    <select id="select" resultType="org.example.entity.Dept">
        select deptno,dname,loc from dept
    </select>

    <select id="selectById" parameterType="java.lang.Integer"
            resultType="org.example.entity.Dept">
        select deptno,dname,loc from dept where deptno=#{deptno}
    </select>

    <insert id="insert" parameterType="org.example.entity.Dept">
        insert into dept(dname,loc) values(#{dname},#{loc})
    </insert>

    <update id="update" parameterType="org.example.entity.Dept">
        update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
    </update>

    <delete id="delete" parameterType="java.lang.Integer">
        delete from dept where deptno=#{deptno}
    </delete>
</mapper>

在核心配置文件中加载mapper文件

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties resource=""/>
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/DeptMapper.xml"/>
    </mappers>
</configuration>

测试

package org.example;

import org.example.dao.DeptDao;
import org.example.dao.impl.DeptDaoImpl;
import org.example.entity.Dept;
import org.junit.Test;

import java.util.List;

public class DaoTest {
    private DeptDao deptDao = new DeptDaoImpl();

    @Test
    public void testSelect() {
        List<Dept> list = deptDao.select();
        for (Dept dept : list) {
            System.out.println(dept);
        }
    }

    @Test
    public void testSelectById() {
        Dept dept = deptDao.selectById(20);
        System.out.println(dept);
    }

    @Test
    public void testInsert() {
        Dept dept = new Dept();
        dept.setDname("企划部");
        dept.setLoc("深圳");
        int result = deptDao.insert(dept);
        System.out.println("影响数据库的条数:" + result);
    }

    @Test
    public void testUpdate() {
        Dept dept = new Dept();
        dept.setDeptno(41);
        dept.setDname("生产部");
        dept.setLoc("杭州");
        int result = deptDao.update(dept);
        System.out.println("影响数据库的条数:" + result);
    }

    @Test
    public void testDelete() {
        int result = deptDao.delete(41);
        System.out.println("影响数据库的条数:" + result);
    }
}

原始DAO开发问题

  • Dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
  • 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不利于开发维护。
  • 调用SqlSession方法时传入的变量,由于SqlSession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

注:原始Dao开发和我们Web阶段讲解的Dao开发基本类似,都是有Dao接口和Dao实现类,无非Web阶段的Dao实现类中通过DBUtils来操作SQL;现在Mybatis的原始Dao开发,把SQL分离出去了,写在的XML映射文件里面而已。

Mapper代理方式

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

程序员编写Mapper接口需要遵循一些开发规范,MyBatis可以自动生成Mapper接口实现类代理对象。

开发规范

1、Mapper.xml文件中的namespace与mapper接口的类路径相同。
2、Mapper.xml中定义的每个标签的id与Mapper接口方法名相同。
3、Mapper.xml中定义的每个sql的parameterType的类型与Mapper接口方法的参数类型相同。
4、Mapper.xml中定义的每个sql的resultType的类型与Mapper接口方法返回值类型相同。

注:Mapper.xml映射文件最好和Mapper接口名称一致。

实体类

package org.example.entity;

import java.util.Date;

public class Emp {
    private Integer empno;
    private String ename;
    private String job;
    private Integer mgr;
    private Date hiredate;
    private Double sal;
    private Double comm;
    private Integer deptno;

    public Integer getEmpno() {
        return empno;
    }

    public void setEmpno(Integer empno) {
        this.empno = empno;
    }

    public String getEname() {
        return ename;
    }

    public void setEname(String ename) {
        this.ename = ename;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    public Integer getMgr() {
        return mgr;
    }

    public void setMgr(Integer mgr) {
        this.mgr = mgr;
    }

    public Date getHiredate() {
        return hiredate;
    }

    public void setHiredate(Date hiredate) {
        this.hiredate = hiredate;
    }

    public Double getSal() {
        return sal;
    }

    public void setSal(Double sal) {
        this.sal = sal;
    }

    public Double getComm() {
        return comm;
    }

    public void setComm(Double comm) {
        this.comm = comm;
    }

    public Integer getDeptno() {
        return deptno;
    }

    public void setDeptno(Integer deptno) {
        this.deptno = deptno;
    }

    @Override
    public String toString() {
        return "Emp{" +
                "empno=" + empno +
                ", ename='" + ename + '\'' +
                ", job='" + job + '\'' +
                ", mgr=" + mgr +
                ", hiredate=" + hiredate +
                ", sal=" + sal +
                ", comm=" + comm +
                ", deptno=" + deptno +
                '}';
    }
}

Mapper接口

Mapper接口相当于我们之前写的Dao接口,只是在Mybatis里面我们习惯这么写而已。

package org.example.mapper;

import org.example.entity.Emp;

import java.util.List;

/*
 * Mapper接口相当于我们之前写的Dao接口,只是在Mybatis里面我们习惯这么写而已。
 */
public interface EmpMapper {
    List<Emp> select();

    Emp selectById(Integer empno);

    /**
     * 方法返回值为void,表示SqlSession对象中insert,update,delete方法的返回值不做任何处
     * 理。
     * @param emp
     */
    void insert(Emp emp);


    /**
     * 方法返回值为int类型,表示SqlSession对象中insert,update,delete方法的返回值直接返
     * 回。
     * @param emp
     */
    int update(Emp emp);

    /**
     * 方法返回值为boolean类型,表示根据SqlSession对象中的insert,update,delete方法返回
     * 值(影响数据库的条数)判断操作是否成功,如果影响数据库的条数大于0条,表示成功,否
     * 则表示失败。
     * @param empno
     * @return
     */
    boolean delete(Integer empno);
}

mapper文件

<?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="org.example.mapper.EmpMapper">

    <select id="select" resultType="org.example.entity.Emp">
        select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
    </select>

    <select id="selectById" parameterType="java.lang.Integer"
            resultType="org.example.entity.Emp">
        select empno,ename,job,hiredate,mgr,sal,comm,deptno from emp where
            empno=#{empno}
    </select>

    <insert id="insert" parameterType="org.example.entity.Emp">
        insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
        values(#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
    </insert>

    <update id="update" parameterType="org.example.entity.Emp">
        update emp set
            ename=#{ename},job=#{job},mgr=#{mgr},hiredate=#{hiredate},sal=#
            {sal},comm=#{comm},deptno=#{deptno}
        where empno=#{empno}
    </update>

    <delete id="delete" parameterType="java.lang.Integer">
        delete from emp where empno=#{empno}
    </delete>
</mapper>

在核心配置文件中加载mapper文件

<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
    <properties resource=""/>
    <typeAliases>
        <package name=""/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <mapper resource="mapper/EmpMapper.xml"/>
    </mappers>
</configuration>

测试

package org.example;

import org.apache.ibatis.session.SqlSession;
import org.example.entity.Emp;
import org.example.mapper.EmpMapper;
import org.example.utils.MybatisUtil;
import org.junit.Test;

import java.util.List;

public class MapperTest {
    @Test
    public void testMapper(){
        SqlSession sqlSession = MybatisUtil.getSession();
        //获取Mapper接口的代理对象(实现类对象)
        //告诉mtbatis生成哪个接口的实现类对象
        EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
        List<Emp> emps = empMapper.select();
        for (Emp emp:emps){
            System.out.println(emp);
        }
    }
}

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

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值