侧边栏壁纸
博主头像
Epoch

Java开发、Python爬虫、微服务、分布式、前端

  • 累计撰写 94 篇文章
  • 累计创建 111 个标签
  • 累计收到 8 条评论

目 录CONTENT

文章目录

Mybatis三种DAO层使用玩法

Epoch
2021-02-20 / 0 评论 / 0 点赞 / 376 阅读 / 2,107 字 / 正在检测是否收录...

Mybatis三种DAO层使用玩法

第一种使用namespace.id来使用Mybatis进行操作

配置类中注册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>
    <settings>
        <!--开启驼峰命名转换 form_id -> formId-->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>
    <environments default="dev">
        <!--开发环境配置-->
        <environment id="dev">
            <!--事务管理器采用JDBC方式-->
            <transactionManager type="JDBC"></transactionManager>
            <!--利用Mybatis自带连接池管理连接
            <dataSource type="POOLED">-->
            <!--MyBatis与Druid的整合-->
            <dataSource type="com.xmaven.oa.datasource.DruidDataSourceFactory">
                <!--JDBC连接属性-->
                <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/ambition-oa?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=Asia/Shanghai&amp;allowPublicKeyRetrieval=true"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
                <!--连接池初始连接数-->
                <property name="initialSize" value="20"/>
                <!--连接池最大连接数-->
                <property name="maxActive" value="20"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mappers/test.xml"/>
        <mapper resource="mappers/user.xml"/>
        <mapper resource="mappers/rbac.xml"/>
        <mapper resource="mappers/employee.xml"/>
        <mapper resource="mappers/department.xml"/>
    </mappers>
</configuration>

以user.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="usermapper">
    <select id="selectByUsername" parameterType="string" resultType="com.xmaven.oa.entity.User">
        select * from sys_user where username = #{value}
    </select>
</mapper>

编写我们的Mybatis的工具类使用了java8新特性Lambda编写的工具

package com.xmaven.oa.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.Reader;
import java.util.function.Function;

/**
 * @ClassName MybatisUtils
 * @Description TODO MyBatisUtils工具类,创建全局唯一的SqlSessionFactory对象
 * @Author Ambition
 * @Date 2021/2/19 13:46
 * @Version 1.0.0
 **/
public class MybatisUtils {

    //利用static(静态)属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;
    //利用静态块在初始化类时实例化sqlSessionFactory
    static{
        Reader reader = null;
        try{
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        }catch(IOException e){
            //初始化错误时,通过抛出异常ExceptionInInitializerError通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * 执行SELECT查询SQL
     * @param func 要执行查询语句的代码块
     * @return 查询结果
     */
    public static Object executeQuery(Function<SqlSession,Object> func){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            Object obj = func.apply(sqlSession);
            return obj;
        }finally {
            sqlSession.close();
        }
    }

    /**
     * 执行INSERT/UPDATE/DELETE写操作SQL
     * @param func 要执行的写操作代码块
     * @return 写操作后返回的结果
     */
    public static Object executeUpdate(Function<SqlSession,Object> func){
        // 设置sqlsession是否自动提交
        SqlSession sqlSession = sqlSessionFactory.openSession(false);
        try {
            Object obj = func.apply(sqlSession);
            sqlSession.commit();
            return obj;
        }catch (RuntimeException e){
            sqlSession.rollback();
            throw e;
        }finally{
            sqlSession.close();
        }
    }

}

编写dao层

package com.xmaven.oa.dao;

import com.xmaven.oa.entity.User;
import com.xmaven.oa.utils.MybatisUtils;

/**
 * @ClassName UserDao
 * @Description TODO 用户表Dao
 * @Author Ambition
 * @Date 2021/2/20 10:33
 * @Version 1.0.0
 **/
public class UserDao {
    /**
     * 按照用户名查找用户表
     * @param username  用户名
     * @return  User对象包含的用户信息,null则表示对象不存在
     */
    public User SelectByUsername(String username){
        User user = (User) MybatisUtils.executeQuery(sqlSession -> sqlSession.selectOne("usermapper.selectByUsername",username));
        return user;
    }

}

编写Service层

package com.xmaven.oa.service;

import com.xmaven.oa.dao.RbacDao;
import com.xmaven.oa.dao.UserDao;
import com.xmaven.oa.entity.Node;
import com.xmaven.oa.entity.User;
import com.xmaven.oa.service.exception.BussinessException;

import java.util.List;

/**
 * @ClassName UserService
 * @Description TODO 用户服务
 * @Author Ambition
 * @Date 2021/2/20 10:38
 * @Version 1.0.0
 **/
public class UserService {

    private UserDao userDao = new UserDao();

    /**
     * 根据前台输入数据进行登录校验
     * @param username 前台输入的用户名
     * @param password 前台输入的密码
     * @return 校验通过后返回对应User实体类
     * @throws BussinessException L001-用户不存在,L002-密码错误
     */
    public User checkLogin(String username, String password) {
        User user = userDao.SelectByUsername(username);
        if (user == null) {
            // 抛出用户不存在异常
            throw new BussinessException("L001", "用户名不存在");
        }
        if (!password.equals(user.getPassword())) {
            throw new BussinessException("L002", "密码错误");
        }
        return user;
    }

}

第二种就是常用的接口实现

主要是namespace和我们写的接口类关联起来

先编写Dao层

package com.xmaven.oa.dao;

import com.xmaven.oa.entity.Employee;

/**
 * @ClassName EmployeeDao
 * @Description TODO
 * @Author Ambition
 * @Date 2021/2/20 15:48
 * @Version 1.0.0
 **/
public interface EmployeeDao {

    public Employee selectById(Long employeeId);

}

以我编写的employee.xml为例解释一下

这个需要把接口名和这个xml的namespace要对应起来

还有里面的id也要和接口的方法名对应起来

<?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">
<!--namespace需要和包名一致-->
<mapper namespace="com.xmaven.oa.dao.EmployeeDao">
    <!--  id与方法名对应
         parameterType与方法参数类型对应
         resultType与方法返回类型对应
         -->
    <select id="selectById" parameterType="Long" resultType="com.xmaven.oa.entity.Employee">
        select * from adm_employee where employee_id = #{value}
    </select>
</mapper>

接下来编写serveice层

package com.xmaven.oa.service;

import com.xmaven.oa.dao.EmployeeDao;
import com.xmaven.oa.entity.Employee;
import com.xmaven.oa.utils.MybatisUtils;

/**
 * @ClassName EmployeeService
 * @Description TODO 员工服务
 * @Author Ambition
 * @Date 2021/2/20 15:53
 * @Version 1.0.0
 **/
public class EmployeeService {

    public Employee selectById(Long employeeId) {
        return (Employee) MybatisUtils.executeQuery(sqlSession -> {
            // 根据传入的接口,自动实现接口的实现类
            EmployeeDao employeeDao = sqlSession.getMapper(EmployeeDao.class);
            return employeeDao.selectById(employeeId);
        });
    }

}

注意还有一点,这个也需要注册Mapper

第三种就是我们常用的注解形式

package com.xmaven.mybatis.dao;

import com.xmaven.mybatis.dto.GoodsDTO;
import com.xmaven.mybatis.entity.Goods;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface GoodsDAO {
    @Select("select * from t_goods where current_price between  #{min} and #{max} order by current_price limit 0,#{limt}")
    public List<Goods> selectByPriceRange(@Param("min") Float min ,@Param("max") Float max ,@Param("limt") Integer limt);

    @Insert("INSERT INTO t_goods(title, sub_title, original_cost, current_price, discount, is_free_delivery, category_id) VALUES (#{title} , #{subTitle} , #{originalCost}, #{currentPrice}, #{discount}, #{isFreeDelivery}, #{categoryId})")
    //<selectKey>
    @SelectKey(statement = "select last_insert_id()" , before = false , keyProperty = "goodsId" , resultType = Integer.class)
    public int insert(Goods goods);

    @Select("select * from t_goods")
    //<resultMap>
    @Results({
            //<id>
          @Result(column = "goods_id" ,property = "goodsId" , id = true) ,
            //<result>
            @Result(column = "title" ,property = "title"),
            @Result(column = "current_price" ,property = "currentPrice")
    })
    public List<GoodsDTO> selectAll();
}

这个使用这个工具类

package com.xmaven.mybatis.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.Reader;

/**
 * MyBatisUtils工具类,创建全局唯一的SqlSessionFactory对象
 */
public class MyBatisUtils {
    //利用static(静态)属于类不属于对象,且全局唯一
    private static SqlSessionFactory sqlSessionFactory = null;
    //利用静态块在初始化类时实例化sqlSessionFactory
    static {
        Reader reader = null;
        try {
            reader = Resources.getResourceAsReader("mybatis-config.xml");
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
        } catch (IOException e) {
            e.printStackTrace();
            //初始化错误时,通过抛出异常ExceptionInInitializerError通知调用者
            throw new ExceptionInInitializerError(e);
        }
    }

    /**
     * openSession 创建一个新的SqlSession对象
     * @return SqlSession对象
     */
    public static SqlSession openSession(){
        //默认SqlSession对自动提交事务数据(commit)
        //设置false代表关闭自动提交,改为手动提交事务数据
        return sqlSessionFactory.openSession(false);
    }

    /**
     * 释放一个有效的SqlSession对象
     * @param session 准备释放SqlSession对象
     */
    public static void closeSession(SqlSession session){
        if(session != null){
            session.close();
        }
    }
}

编写一个测试类

package com.xmaven.mybatis;

import com.xmaven.mybatis.dao.GoodsDAO;
import com.xmaven.mybatis.dto.GoodsDTO;
import com.xmaven.mybatis.entity.Goods;
import com.xmaven.mybatis.utils.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

//JUNIT单元测试类
public class MyBatisTestor {

    @Test
    public void testSelectByPriceRange() throws Exception {
        SqlSession session = null;
        try{
            session = MyBatisUtils.openSession();
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            List<Goods> list = goodsDAO.selectByPriceRange(100f, 500f, 20);
            System.out.println(list.size());
        }catch (Exception e){
            throw e;
        } finally {
            MyBatisUtils.closeSession(session);

        }
    }

    /**
     * 新增数据
     * @throws Exception
     */
    @Test
    public void testInsert() throws Exception {
        SqlSession session = null;
        try{
            session = MyBatisUtils.openSession();
            Goods goods = new Goods();
            goods.setTitle("测试商品");
            goods.setSubTitle("测试子标题");
            goods.setOriginalCost(200f);
            goods.setCurrentPrice(100f);
            goods.setDiscount(0.5f);
            goods.setIsFreeDelivery(1);
            goods.setCategoryId(43);
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            //insert()方法返回值代表本次成功插入的记录总数
            int num = goodsDAO.insert(goods);
            session.commit();//提交事务数据
            System.out.println(goods.getGoodsId());
        }catch (Exception e){
            if(session != null){
                session.rollback();//回滚事务
            }
            throw e;
        }finally {
            MyBatisUtils.closeSession(session);
        }
    }

    @Test
    public void testSelectAll() throws Exception {
        SqlSession session = null;
        try{
            session = MyBatisUtils.openSession();
            GoodsDAO goodsDAO = session.getMapper(GoodsDAO.class);
            List<GoodsDTO> list = goodsDAO.selectAll();
            System.out.println(list.size());
        }catch (Exception e){
            throw e;
        } finally {
            MyBatisUtils.closeSession(session);

        }
    }
}

基本来说接口注解和非注解形式,使用没啥太大差异,看个人喜好

0

评论区