了解MyBatis——一篇就够了

目录

 

MyBatis的概念及优缺点 

运行环境

 MyBatis创建流程

映射(*)

MyBatis的使用 


MyBatis的概念及优缺点 

MyBatis是一个半自动映射的框架。这里所谓的"半自动"是相对于Hibernate全表映射而言的,MyBatis需要手动匹配提供POJO、SQL和映射关系,而Hibernate只需提供POJO和映射关系即可。

缺点:

MyBatis手动编写SQL,工作量大。
优点:

可以配置动态SQL并优化SQL
可以通过配置决定SQL的映射规则
支持存储过程
对于一些复杂的和需要优化性能的项目来说,显示使用MyBatis更加合适。

运行环境

idea:2018-2

mysql:5.6

使用maven管理jar包

数据库名为test,表为emp和dept,表数据如下

 MyBatis创建流程

1、利用idea建立一个maven工程,在pom.xml中引入jar包

<!--mybatis核心包 -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.5</version>
        </dependency>
        <!--mysql驱动包 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.29</version>
        </dependency>
        <!-- 日志文件管理包 -->
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.12</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.12</version>
        </dependency>

避免配置文件发布到tomcat服务器失败,添加都build标签里

<!--把xml,properties配置文件强制性的部署到tomcat服务器上-->
<resources>
  <resource>
    <directory>src/main/java</directory>
    <includes>
      <include>**/*.properties</include>
      <include>**/*.xml</include>
    </includes>
    <filtering>false</filtering>
  </resource>
  <resource>
    <directory>src/main/resources</directory>
    <includes>
      <include>**/*.properties</include>
      <include>**/*.xml</include>
    </includes>
    <filtering>false</filtering>
  </resource>
</resources>

2、在resources里添加日志文件log4j.porperties(文件名不可更改)

### jibie mudidi  ###
log4j.rootLogger=debug, stdout,logfile
### kongzhitai  ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
### wenjian ###
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=jbit.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %l %F %p %m%n

3、在resources里添加mybatis配置文件

编写db.properties

jdbc_driver=com.mysql.jdbc.Driver
jdbc_url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
jdbc_username=root
jdbc_password=root

编写mybatis-config.xml

<?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="db.properties"></properties>
    <!--别名,可以直接使用类名,不用加全限定类名-->
    <typeAliases>
        <package name="cn.sdut.mybatis.po"></package>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <!-- 配置数据库连接信息 -->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc_driver}" />
                <property name="url" value="${jdbc_url}" />
                <property name="username" value="${jdbc_username}" />
                <property name="password" value="${jdbc_password}" />
            </dataSource>
        </environment>
    </environments>
</configuration>

 

4.编写数据库实体类

Dept

package cn.sdut.mybatis.po;

public class Dept {

    private int deptno;
    private String dname;
    private String loc;

    public Dept() {
    }

    public Dept(int deptno, String dname, String loc) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
    }

    public int getDeptno() {
        return deptno;
    }

    public void setDeptno(int 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 + '\'' +
                '}';
    }
}

5.编写dao接口

package cn.sdut.mybatis.dao;

import cn.sdut.mybatis.po.Dept;

import java.util.List;

public interface DeptDao {

    //查询
    Dept selectById(int deptno);

    //增加
    int insertDept(Dept dept);

    //删除
    int deleteDeptById(int deptno);

    //更新
    int updateDept(Dept dept);

    List<Dept> selectAll();
}

6.编写DeptDao.xml文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--对应哪个dao接口-->
<mapper namespace="cn.sdut.mybatis.dao.DeptDao">
    <!--查询的时候会用到resultMap-->
    <resultMap id="deptMap" type="Dept">
        <id column="deptno" property="deptno"></id>
        <result column="dname" property="dname"></result>
        <result column="loc" property="loc"></result>
    </resultMap>
    <!-- -查询-->
    <select id="selectById" parameterType="int" resultMap="deptMap">
        select * from dept where deptno=#{deptno}
    </select>
    <insert id="insertDept" parameterType="Dept">
        insert into dept value(null,#{dname},#{loc})
    </insert>
    <delete id="deleteDeptById" parameterType="int">
        delete from dept where deptno=#{deptno}
    </delete>
    <update id="updateDept" parameterType="Dept">
        update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
    </update>

    <select id="selectAll" resultMap="deptMap">
        select * from dept
    </select>
</mapper>

在mybatis配置文件mybatis-config.xml里,装配dao,configuration标签里

 <mappers>
        <mapper class="cn.sdut.mybatis.dao.DeptDao"></mapper>
    </mappers>

6.编写测试类

package cn.test.test;

import cn.sdut.mybatis.dao.DeptDao;
import cn.sdut.mybatis.po.Dept;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;
import java.util.List;

public class Test {

    @org.junit.Test
    public void test(){

        //将主配置文件读取转化为文件流
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //获取sqlSessionFactory工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        //获得dao对象
        DeptDao deptDao = session.getMapper(DeptDao.class);

        //精确查找
        deptDao.selectById(10);
        //插入
        deptDao.insertDept(new Dept(0,"后勤部","青岛"));
        //删除
        deptDao.deleteDeptById(42);
        //修改
        deptDao.updateDept(new Dept(42,"行政部","青岛"));
        //查询所有
        List<Dept> list = deptDao.selectAll();
        for (Dept d:list) {
            System.out.println(d.toString());
        }
        //如果不提交,则只修改内存中的,虽然日志返回正确,但是数据库中的数据并没有修改
        session.commit();
    }
}

运行结果

先删除后修改竟然成功了,脏数据,成功了。

映射(*)

多对一,在多的一方添加一的一方的对象

例如:根据员工id查询部门信息

因为dept和emp表中都有deptno,所以Emp中吧deptno删掉就可以了

package cn.sdut.mybatis.po;

/**
 * @author:hydra
 * @date:2019/11/29
 */
public class Emp {

    private int id;
    private String name;
    private String job;
    private int sal;
    private Dept dept;

    public Emp() {
    }


    public Emp(int id, String name, String job, int sal, int deptno, Dept dept) {
        this.id = id;
        this.name = name;
        this.job = job;
        this.sal = sal;
        this.dept = dept;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public String getJob() {
        return job;
    }

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

    public int getSal() {
        return sal;
    }

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


    @Override
    public String toString() {
        return "Emp{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", job='" + job + '\'' +
                ", sal=" + sal +
                ", dept=" + dept +
                '}';
    }
}

编写EmpDao.xml 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="cn.sdut.mybatis.dao.EmpDao">
    <resultMap id="empMap" type="Emp">
        <id property="id" column="id"></id>
        <result property="name" column="name"></result>
        <result property="job" column="job"></result>
        <result property="sal" column="sal"></result>
        <result property="deptno" column="deptno"></result>
        <!--多对一的时候用association,dept为属性名称,Dept为属性类型-->
        <association property="dept" javaType="Dept">
            <!--配置属性-->
            <id column="deptno" property="deptno"></id>
            <result column="dname" property="dname"></result>
            <result column="loc" property="loc"></result>
        </association>
    </resultMap>
    <insert id="insert" parameterType="Emp">
        insert into emp value(null,#{name},#{job},#{sal},#{deptno})
    </insert>
    <!--连表查询-->
    <select id="select" resultMap="empMap">
        select * from emp join dept on emp.deptno=dept.deptno where id=#{id}
    </select>
</mapper>

MyBatis的使用 

在使用MyBatis框架的时候,主要涉及两个核心对象:SQLSessionFactory和SQLSession。

SQLSessionFactory

  • 它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。
    • SqlSessionFactory则可以通过SqlSessionFactoryBuilder对象来创建
    • 而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory实例。
  • SqlSessionFactory是线程安全的
    • SqlSessionFactory一旦被创建,整个应用执行期间都会存在。
    • 如果多次创建同一个数据库的SQLSessionFactory,name数据库资源很容易被耗尽。
    • 为了解决这个问题,通常每一个数据库只会对于一个SQLSessionFactory,所以构建SqlSessionFactory实例时,建议使用单例模式。

SqlSession

  • 它是应用程序与持久层之间执行交互操作的一个单线程对象,其作用主要是执行持久化操作。
  • SqlSession对象包含了数据库中所有执行SQL操作的方法,由于底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句
  • SqlSession实例线程不安全,使用范围最好在一个请求或者一个方法中

测试类

 @org.junit.Test
    public void test1(){
        //将主配置文件读取转化为文件流
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //获取sqlSessionFactory工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        //获得dao对象
        EmpDao empDao = session.getMapper(EmpDao.class);

//        empDao.insert(new Emp(0,"hydra","ceo",500000,20));

        Emp emp = empDao.select(7936);
        System.out.println(emp);
    }

查询成功 

 

一对多

事例:查询研发部所有的部门员工

修改emp

package cn.sdut.mybatis.po;

import java.util.List;

public class Dept {

    private int deptno;
    private String dname;
    private String loc;
    private List<Emp> emps;

    public Dept() {
    }

    public Dept(int deptno, String dname, String loc) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
    }

    public Dept(int deptno, String dname, String loc, List<Emp> emps) {
        this.deptno = deptno;
        this.dname = dname;
        this.loc = loc;
        this.emps = emps;
    }

    public int getDeptno() {
        return deptno;
    }

    public void setDeptno(int 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;
    }

    public List<Emp> getEmps() {
        return emps;
    }

    public void setEmps(List<Emp> emps) {
        this.emps = emps;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "deptno=" + deptno +
                ", dname='" + dname + '\'' +
                ", loc='" + loc + '\'' +
                ", emps=" + emps +
                '}';
    }
}

 修改EmpDao.xml

在resultMap中添加collection标签,添加emps的属性

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://www.mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--对应哪个dao接口-->
<mapper namespace="cn.sdut.mybatis.dao.DeptDao">
    <!--查询的时候会用到resultMap-->
    <resultMap id="deptMap" type="Dept">
        <id column="deptno" property="deptno"></id>
        <result column="dname" property="dname"></result>
        <result column="loc" property="loc"></result>
        <!--一对多的时候为collection,属性名为emps,ofType代表数据类型-->
        <collection property="emps" ofType="Emp">
            <id property="id" column="id"></id>
            <result property="name" column="name"></result>
            <result property="job" column="job"></result>
            <result property="sal" column="sal"></result>
            <result property="deptno" column="deptno"></result>
        </collection>
    </resultMap>
    <!-- -查询-->
    <select id="selectById" parameterType="int" resultMap="deptMap">
        select * from dept join emp on dept.deptno=emp.deptno where dept.deptno=#{deptno}
    </select>
    <insert id="insertDept" parameterType="Dept">
        insert into dept value(null,#{dname},#{loc})
    </insert>
    <delete id="deleteDeptById" parameterType="int">
        delete from dept where deptno=#{deptno}
    </delete>
    <update id="updateDept" parameterType="Dept">
        update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
    </update>

    <select id="selectAll" resultMap="deptMap">
        select * from dept
    </select>
</mapper>

测试类

  @org.junit.Test
    public void test2(){
        //将主配置文件读取转化为文件流
        InputStream inputStream = Test.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
        //获取sqlSessionFactory工厂
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        SqlSession session = sqlSessionFactory.openSession();
        //获得dao对象
        DeptDao deptDao = session.getMapper(DeptDao.class);

        Dept dept = deptDao.selectById(20);
        System.out.println(dept.getDname());
        List<Emp> emps =dept.getEmps();
        for (Emp emp: emps) {
            System.out.println(emp);
        }
    }

总结:走了一遍流程,最重要的还是映射!映射!!映射!!! 

  • 10
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值