mybatis学习总结

一、浅析mybatis

前段时间学习了jdbc、mybatis两个框架,又做了个不大不小的项目,就来这给大家班门弄斧总结下,如有不足还请温柔指正。
什么是mybatis? 官网给的答案是这样的https://mybatis.org/mybatis-3/zh/index.html

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。

说人话就是连接数据库和java的工具,他有很强的可控性,体现在它操作数据库、存储数据的sql语句都是由程序员自己写在xml文件里,再将xml文件映射到对应的Mapper接口。

二、项目结构(以下内容均是在有了数据库的前提下操作)

这个就不用太多文字来描述了,直接上图

三、配置pom.xml

这个文件里面的内容都是各种依赖,例如:log4j,sql,junit等等。(根据项目所需自行添加,这里展示的是我用到的)
上代码

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>uolab</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>
        <!--mybatis-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.0</version>
        </dependency>
        <!--mysql-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <version>RELEASE</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.h2database</groupId>
            <artifactId>h2</artifactId>
            <version>1.4.200</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.junit.platform</groupId>
            <artifactId>junit-platform-runner</artifactId>
            <version>1.5.1</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13-rc-2</version>
            <scope>test</scope>
        </dependency>

    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>6</source>
                    <target>6</target>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

四、编写mybatis工具类(我这里叫DBUtil)

mybatis工具类的主要任务就是使用SqlSessionFactoryBuilder创建SqlSessionFactory。使用SqlSessionFactory创建SqlSession。SqlSession可以通过Sql Mapper.class进行数据库操作,或者直接使用SqlSession的方法输入SqlMapper.方法()进行数据库操作,使用完要关闭。
上代码

package com.ychs.util;


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.apache.log4j.Logger;

import java.io.InputStream;

public class DBUtil {

    /**
     * 单元测试用
     **/
    private SqlSession session;

    private static boolean closeFlag = false;
    //    创建一个Log4j的对象
    private Logger logger = Logger.getLogger(DBUtil.class);
//    工具类 单例模式  23种设计模式 只有一个实例 单例模式
//    单例模式 不让你new 对象 直接私有
    /**
     * @Author hp
     * @Description
     * 单例对象,饿汉模式 系统加载内存时,已经初始化了
     * @Date 15:59 2021/5/18
     * @Param
     * @return
     **/
    //   private static MyDBUtil dbUtil = new MyDBUtil();
    /**
     * @Author hp
     * @Description
     * 懒汉模式,单例对象
     * @Date 16:03 2021/5/18
     * @Param
     * @return
     **/
    private static  DBUtil dbUtil;
    private SqlSessionFactory factory;
    /**
     * @Author hp
     * @Description
     * 私有化构造方法 是为了单例做准备
     * @Date 15:56 2021/5/18
     * @Param []
     * @return
     **/
    private DBUtil(){
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis-cfg.xml");
//            logger.debug("is = " + is);
//            logger.info("info is = " + is);
//            logger.error("error is = "+ is);
            factory = new SqlSessionFactoryBuilder().build(is);
        } catch (Exception e) {
//            logger.error("初始化时出错了", e);
            e.printStackTrace();
        }
    }
    /**
     * @Author hp
     * @Description
     * 单例模式对外提供出口,返回自身单例对象
     * @Date 15:58 2021/5/18
     * @Param []
     * @return com.ychs.DBUtil.MyDBUtil
     **/
    public static  DBUtil getInstance(){
//        饿汉模式
//        return dbUtil;
        if (dbUtil == null){
//            不能再懒了,此时必须要初始化
            dbUtil = new DBUtil();
        }
        return dbUtil;
    }
//    静态特别占用资源 释放不了
//    MyDBUtil.getInstance().getSqlSession();
    /**
     * 获取session会话,当数据库链接异常时,会返回null对象
     * @return sesson 会话
     **/
    public  SqlSession getSqlSession(){
//        if (factory != null){
//            return factory.openSession();
//        }
//        return null;
        // h2单元测试

        if (session == null){
            session = factory.openSession();
        }
        return session;
    }

    public static void close(SqlSession session){
        if (closeFlag){
            session.close();
        }
    }
}

五、entity层(实体类 这一层不同的人叫法不同)

在日常的Java项目开发中,entity(实体类)是必不可少的,它们一般都有很多的属性,并有相应的setter和getter方法。entity(实体类)的作用一般是和数据表做映射。
说人话就是把数据库里的每个表写成一个实力类,表里的每个字段原封不动(为了后期方便,尽量同名)的写成类属性。
上代码

package com.ychs.entity;

import java.util.List;

public class User {
    /**
     * id
     */
    private int id;
    /**
     * 性别
     */
    private int sex;
    /**
     * 院系
     */
    private College college;
    /**
     * 专业
     */
    private Major major;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 角色
     */
    private Role role;
    /**
     * 状态
     */
    private String state;
    /**
     * 真实姓名
     */
    private String name;
    /**
     * 年级
     */
    private int grade;
    /**
     * 班级
     */
    private String clazz;
    /**
     * 职务
     */
    private String schoolJob;
    /**
     * 电话
     */
    private String phone;
    /**
     * QQ
     */
    private String QQ;
    /**
     * 备注
     */
    private String remark;

    public int getId() {
        return id;
    }

    public int getSex() {
        return sex;
    }

    public void setSex(int sex) {
        this.sex = sex;
    }

    public void setId(int id) {
        this.id = id;
    }

    public College getCollege() {
        return college;
    }

    public void setCollege(College college) {
        this.college = college;
    }

    public Major getMajor() {
        return major;
    }

    public void setMajor(Major major) {
        this.major = major;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public Role getRole() {
        return role;
    }

    public void setRole(Role role) {
        this.role = role;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getGrade() {
        return grade;
    }

    public void setGrade(int grade) {
        this.grade = grade;
    }

    public String getClazz() {
        return clazz;
    }

    public void setClazz(String clazz) {
        this.clazz = clazz;
    }

    public String getSchoolJob() {
        return schoolJob;
    }

    public void setSchoolJob(String schoolJob) {
        this.schoolJob = schoolJob;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public String getQQ() {
        return QQ;
    }

    public void setQQ(String QQ) {
        this.QQ = QQ;
    }

    public String getRemark() {
        return remark;
    }

    public void setRemark(String remark) {
        this.remark = remark;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                "sex=" + sex +
                ", college=" + college +
                ", major=" + major +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", role='" + role + '\'' +
                ", state='" + state + '\'' +
                ", name='" + name + '\'' +
                ", grade=" + grade +
                ", clazz='" + clazz + '\'' +
                ", school_job='" + schoolJob + '\'' +
                ", phone='" + phone + '\'' +
                ", QQ='" + QQ + '\'' +
                ", remark='" + remark + '\'' +
                '}';
    }
}

六、创建Dao层接口

Dao接口负责定义service层(服务层)要用到的方法(比如增删改查)
上代码

package com.ychs.dao;

import java.util.List;
import java.util.Map;

public interface BaseMapper<T> {
    // insert update delete select selectById

    /**
     * 插入记录
     * @param t
     * @return 影响的行数
     */
    int insert(T t);

    /**
     * 更新记录
     * @param t
     * @return 影响的行数
     */
    int update(T t);

    /**
     * 删除记录
     * @param
     * @return 影响的行数
     */
    int delete(int id);

    /**
     * 查询单个记录
     * @param id 主键
     * @return 对象
     */
    T selectById(int id);

    /**
     * 返回满足条件的记录
     * @param conditions 查询条件
     * @return 多条记录
     */
    List<T> selectByCondition(Map<String,Object> conditions);
}

七、创建Mapper.xml映射文件(有些人选择把映射文件放入resource文件夹,这里我把它也放在Dao层)

Mapper.xml文件是mybatis项目的核心
最上面一段复制官网https://mybatis.org/mybatis-3/zh/getting-started.html “ 探究以映射的sql语句 ” 下的第一段代码。然后把他的sqlect标签里面的内容换成自己的项目功能所需的sql代码
上代码

<?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.ychs.dao.CollegeMapper">
    <!--parameterType可以省略-->
    <!--#{对象的属性名}-->
    <!--添加院系-->
    <insert id="insert" parameterType="com.ychs.entity.College">
        insert into college (code, name, updatetime)
        values (#{code}, #{name}, sysdate())
    </insert>
    <!--按照条件查询-->
    <select id="selectByCondition" resultType="College" parameterType="map">
        select name ,code from college
        <where>
            <if test="id!=null">
                and id = #{id}
            </if>
            <if test="name!=null">
                and name like '%${name}%'
            </if>
            <if test="code!=null">
                and code = #{code}
            </if>
        </where>
    </select>
    <!--删除院系-->
    <delete id="delete">
        delete
        from college
        where id = #{id}
    </delete>
    <!--修改院系-->
    <update id="update" parameterType="college">
        update college
        set code=#{code},
            name=#{name},
            updatetime=sysdate()
        where id=#{id}
    </update>
    <!--按照id查询-->
    <select id="selectById" resultType="college">
        select *
        from college
        where id = #{id}
    </select>
</mapper>

八、service层(业务逻辑层)

service层是一个相对独立的功能模块,主要负责业务逻辑应用设计。我们可以在应用中调用service接口进行业务处理。service层业务实现,具体调用到已经定义的Dao的接口,封装service层的业务逻辑有利于通用的业务逻辑的独立性和重复利用性 。
说人话就是写项目需要的方法(例如增删改查)
上代码

package com.ychs.service;

import com.ychs.dao.UserMapper;
import com.ychs.entity.User;
import com.ychs.util.Constants;
import com.ychs.util.DBUtil;
import org.apache.ibatis.session.SqlSession;

import java.util.List;
import java.util.Map;

public class UserService implements IBaseService<User> {
    @Override
    public boolean add(User user) {
        SqlSession session = DBUtil.getInstance().getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int result = mapper.insert(user);
        session.commit();
        DBUtil.close(session);
        return result == Constants.UPDATE_SUCCESS;
    }


    @Override
    public boolean modify(User user) {
        SqlSession session = DBUtil.getInstance().getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int result = mapper.update(user);
        session.commit();
        DBUtil.close(session);
        return result == Constants.UPDATE_SUCCESS;
    }

    @Override
    public User searchById(int id) {
        SqlSession session = DBUtil.getInstance().getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        User result = mapper.selectById(id);
        DBUtil.close(session);
        return result;
    }

    @Override
    public List<User> search(Map map) {
        SqlSession session = DBUtil.getInstance().getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        List<User> result = mapper.selectByCondition(map);
        DBUtil.close(session);
        return result;
    }

    @Override
    public boolean remove(int id) {
        SqlSession session = DBUtil.getInstance().getSqlSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        int result = mapper.delete(id);
        session.commit();
        DBUtil.close(session);
        return result==Constants.UPDATE_SUCCESS;
    }
}

九、Test(测试)

选中需要测试的类名用快捷键(shift+ctrl+T)创建Test测试文件(千万不要手动创建),选择对应的junit版本,现在一般都是用junit4或者junit5,然后把要测试的类都选中点确定,
好了,现在只差数据了。我们可以在初始化数据库表的时候将测试数据插入,但相对于每一个测试来说,数据不够细,且这些数据不好维护。我更倾向于在测试类中初始化相应的数据。具体的用法这些就得自己去看了,这里给个简单的例子,上代码

package com.ychs.service;

import com.ychs.entity.College;
import com.ychs.entity.Major;
import com.ychs.entity.Role;
import com.ychs.entity.User;
import org.junit.jupiter.api.MethodOrderer;
import org.junit.jupiter.api.Order;
import org.junit.jupiter.api.TestMethodOrder;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;

import static org.junit.jupiter.api.Assertions.*;

@TestMethodOrder(MethodOrderer.OrderAnnotation.class)
public class UserServiceTest {
    UserService service = new UserService();
    Logger logger = Logger.getLogger("UserServiceTest.class");
    @org.junit.jupiter.api.Test
    @Order(1)
    void add() {
        User user = new User();
        College college = new College();
        Major major = new Major();
        college.setId(1);
        college.setName("北京大学");
        college.setCode(0351);
        user.setCollege(college);
        major.setId(1);
        user.setId(1);
        major.setName("软件工程");
        major.setCode(100);
        user.setClazz("562");
        user.setGrade(2018);
        user.setName("李大侠");
        user.setUsername("秃头");
        user.setSex(0);
        user.setPassword("123456");
        user.setPhone("187323");
        user.setQQ("2946799");
        Role role = new Role();
        role.setId(1);
        user.setRole(role);
        user.setState("在线");
        user.setSchoolJob("班长");
        user.setRemark("备注");
        boolean result = service.add(user);
        assertTrue(result);

    }

    @org.junit.jupiter.api.Test
    @Order(2)
    void modify() {
        User user = new User();
        College college = new College();
        college.setId(1);
        college.setName("清华大学");
        college.setCode(0351);
        Major major = new Major();
        major.setId(1);
        major.setName("软件工程");
        major.setCode(100);

        user.setId(1);
        user.setCollege(college);
        user.setMajor(major);
        user.setClazz("561");
        user.setGrade(2020);
        user.setName("光头");
        user.setSex(1);
        user.setUsername("胖子");
        user.setPassword("123456");
        user.setPhone("10088");
        user.setQQ("294629");
        Role role = new Role();
        role.setId(1);
        user.setRole(role);
        user.setState("在线");
        user.setSchoolJob("班长");
        user.setRemark("备注");
        boolean result = service.modify(user);
        assertTrue(result);
    }

    @org.junit.jupiter.api.Test
    @Order(3)
    void selectById() {
        User user = service.searchById(1);
        assertNotNull(user);
    }

    @org.junit.jupiter.api.Test
    @Order(4)
    void search() {
        Map map = new HashMap();
        map.put("id","1");
        map.put("grade","2020");
        map.put("name","大黄");
        List<User> users = service.search(map);
        assertNotNull(users);
    }

    /*@org.junit.jupiter.api.Test
    @Order(5)
    void remove() {
        boolean result = service.remove(1);
        assertTrue(result);
    }*/
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值