mybatis学习

介绍

MyBatis是一个支持普通SQL查询、存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Pain Old java Objects,普通的Java对象) 映射成数据库中的记录。

mybatis的功能架构分为三层:

API接口层

数据处理层

基础支撑层

mybatis特点:属于持久层ORM框架

        1.持久层:讲内存中对象数据,转移到数据库中的过程持久层

        2.ORM Object Relational Mapping 对象关系映射框架

                类          表

                属性       字段

                对象       记录

        3.半自化 自动化

                mybatis 半自动化

                        表需要手动进行设计

                        提供sql

                        依赖与数据库平台

                        优点:学习使用简单,优化灵活,适合做互联网项目

                hibernate 自动化ORM框架

                        表可以通过框架自动创建

                        省略一些基本的sql

                        不依赖与数据库平台

                        缺点:学生成本高,优化难度大,适合于传统框架,不适合做大型互联网项目

mybatis环境搭建

1.创建项目

2.下载jar包

3.jar包资源拿到项目中,add  as  lib...

        核心jar包,依赖jar包,数据库的驱动jar包

4.定义sql映射文件:定义要执行的sql语句

5.java 类中进行测试

        1)、加载核心配置文件

        2)、构建工厂SqlSessionFactory

        3)、获取会话

        4)、执行sql,得到结果    selectList("命名空间.id")

        5)、处理结果

        6)、关闭会话

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>
    <!--
        环境配置
        default : 要使用的环境的id值
    -->
    <environments default="ev">
        <!--environment : 一个环境的配置    id: 当前环境的唯一标识 -->
        <environment id="ev">
            <!--transactionManager 事务管理器   type="JDBC" :选择与jdbc相同的事务管理机制 -->
            <transactionManager type="JDBC"/>
            <!--数据源配置  type="POOLED" :  通过数据库连接池管理连接-->
            <dataSource type="POOLED">
                <property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
                <property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"/>
                <property name="username" value="SCOTT"/>
                <property name="password" value="TIGER"/>
            </dataSource>
        </environment>
    </environments>
    <!--sql映射配置加载 : 定义sql语句的配置文件-->
    <mappers>
        <mapper resource="com/yjxxt/mappers/DeptMapper.xml"/>
    </mappers>
</configuration>

Dept:

package com.yjxxt.entity;

import java.util.Objects;

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 boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Dept dept = (Dept) o;
        return deptno == dept.deptno &&
                Objects.equals(dname, dept.dname) &&
                Objects.equals(loc, dept.loc);
    }

    @Override
    public int hashCode() {
        return Objects.hash(deptno, dname, loc);
    }

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

DeptMpapper.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">
<!--
    映射配置:
        namespace 命名空间  -> 是sql映射文件的唯一标识
            1) 不能重复,随便写->不推荐
            2) 建议设置为当前的表名.文件名(不加后缀)

-->
<mapper namespace="com.yjxxt.mappers.DeptMapper">
    <!--
        select 定义查询语句
        标签对中定义查询语句
        id : sql语句的唯一标识
        resultType : 结果类型
        parameterType : 入参类型
    -->
    <select id="queryAll" resultType="com.yjxxt.entity.Dept" >
        select * from dept
  </select>
</mapper>

测试类:

public class Class001_Dept {
    public static void main(String[] args) throws IOException {
        //1.加载mybatis的核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //2.构建SqlSessionFactory
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);

        //3.根据工厂构建回话
        SqlSession session = factory.openSession();

        //4.执行sql,得到结果
        //selectList("命名空间.id")
        List<Dept> list =  session.selectList("com.yjxxt.mappers.DeptMapper.queryAll");

        //5.处理结果
        list.forEach(System.out::println);

        //5.关闭回话
        session.close();
    }
}
三个常用的查询方法 :
    selectOne() 执行指定sql,得到一个结果
    selectList() 执行指定sql,得到一个list集合,如果没查到,返回List中没有数据,但是不是null
    selectMap() 执行指定sql,得到一个Map集合,如果没查到,返回空map
//selectList("命名空间.id")
//selectList("命名空间.id",sql语句的实参)
List<Dept> list =  session.selectList("com.yjxxt.mappers.DeptMapper.queryAll");

//session.selectOne("命名空间.id");
//session.selectOne("命名空间.id",sql语句的实参);
Dept dept = session.selectOne("com.yjxxt.mappers.DeptMapper.queryDeptByNo",20);

//session.selectMap("命名空间.id","作为key的字段名")
//session.selectMap("命名空间.id",sql语句的实参,"作为key的字段名")
Map<String,Dept> map = session.selectMap("com.yjxxt.mappers.DeptMapper.queryAll","dname");
<!-- 加载外部的properties文件 -->
<properties resource="db.properties" />

<!--配置别名,别名不区分大小写-->
<typeAliases>
    <!--<typeAlias type="com.yjxxt.entity.Dept" alias="Dept"/>-->
    <package name="com.yjxxt.entity"/> <!--为包下所有的javabean类添加别名,默认表名,不区分大小写-->
</typeAliases>

优化后:

<?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文件 -->
    <properties resource="db.properties" />

    <!--配置别名,别名不区分大小写-->
    <typeAliases>
        <!--<typeAlias type="com.yjxxt.entity.Dept" alias="Dept"/>-->
        <package name="com.yjxxt.entity"/> <!--为包下所有的javabean类添加别名,默认表名,不区分大小写-->
    </typeAliases>
    <!--
        环境配置
        default : 要使用的环境的id值
    -->
    <environments default="ev">
        <!--environment : 一个环境的配置    id: 当前环境的唯一标识 -->
        <environment id="ev">
            <!--transactionManager 事务管理器   type="JDBC" :选择与jdbc相同的事务管理机制 -->
            <transactionManager type="JDBC"/>
            <!--数据源配置  type="POOLED" :  通过数据库连接池管理连接-->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <!--sql映射配置加载 : 定义sql语句的配置文件-->
    <mappers>
        <mapper resource="com/yjxxt/mappers/DeptMapper.xml"/>
    </mappers>
</configuration>
<?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 命名空间  -> 是sql映射文件的唯一标识
            1) 不能重复,随便写->不推荐
            2) 建议设置为当前的表名.文件名(不加后缀)

-->
<mapper namespace="com.yjxxt.mappers.DeptMapper">
    <!--
        select 定义查询语句
        标签对中定义查询语句
        id : sql语句的唯一标识
        resultType : 结果类型 :  基本数据类型|包装类  String  Date  Javabean  List  Map
        parameterType : 入参类型 : 基本数据类型|包装类  String  Date  Javabean 数组  List  Map
    -->
    <select id="queryAll" resultType="dept" >
        select * from dept
  </select>

    <!--根据部门编号查询部门对象-->
    <select id="queryDeptByNo" parameterType="_int" resultType="Dept">
        select * from dept where deptno = #{deptno}
    </select>
</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="com.yjxxt.mappers.EmpMapper">
    <!--
        入参类型: 基本数据类型 包装类  String Date Javabean 数组 List Map
    -->
    <!--String : 根据员工想命名查询员工数据-->
    <select id="queryEmpByName" resultType="Emp" parameterType="string">
        select * from emp where ename = #{haha}
  </select>

    <!--Date : 根据员工的入职日期查询员工信息-->
    <select id="queryEmpByDate" parameterType="date" resultType="emp">
        select * from emp where hiredate = #{0}
    </select>

    <!--JAVABEAN : 根据员工姓名,员工部门编号同时查询员工信息-->
    <select id="queryEmpByNameDeptno" parameterType="emp" resultType="emp">
        select * from emp where ename=#{ename} and deptno = #{deptno}  /*如果参数为javabean对象,占位符的名字需要与对应属性名保持一致*/
    </select>

    <!--数组|list : 根据员工编号查询多个员工数据-->
    <select id="queryEmpByEmpnoSome" resultType="emp">
        select * from emp where empno in
        <foreach collection="array" item="item" open="(" close=")" separator=",">
            #{item}
        </foreach>
    </select>

    <!--Map : 查询薪资>1500或者部门在30部门的员工信息-->
    <select id="queryEmpBySalDeptno" resultType="emp" parameterType="map">
        select * from emp where sal> #{sal}  or deptno = #{deptno} /*如果入参为map,占位符的名字要对象键值对的key,根据key获取value*/
    </select>
</mapper>
package com.yjxxt.test;

import com.yjxxt.pojo.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Map;

//测试入参类型
public class Class001_EmpTest {
    public static void main(String[] args) {
        //1.获取回话
        SqlSession session = null;
        try {
            session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();
            //2.执行sql
            //String 根据员工想命名查询员工数据
            List<Emp> list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByName","SMITH");
            list.forEach(System.out::println);

            System.out.println("--------------------------------");

            //Date 根据员工的入职日期查询员工信息 1981/12/3
            Date date = new SimpleDateFormat("yyyy/MM/dd").parse("1981/12/3");
            List<Emp> list2 = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDate",date);
            list2.forEach(System.out::println);

            System.out.println("--------------------------------");

            //JAVABEAN : 根据员工姓名,员工部门编号同时查询员工信息
            Emp emp = new Emp();
            emp.setEname("SMITH");
            emp.setDeptno(20);
            Emp e = session.selectOne("com.yjxxt.mappers.EmpMapper.queryEmpByNameDeptno",emp);
            System.out.println(e);

            System.out.println("--------------------------------");

            //数组|list : 根据员工编号查询多个员工数据
            Map<Integer,Emp> map = session.selectMap("com.yjxxt.mappers.EmpMapper.queryEmpByEmpnoSome",new int[]{7369,7902},"empno");
            System.out.println(map);

            System.out.println("--------------------------------");

            //Map : 查询薪资>1500或者部门在30部门的员工信息
            List<Emp> list3 = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpBySalDeptno",Map.of("sal",1500,"deptno",30));
            list3.forEach(System.out::println);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ParseException e) {
            e.printStackTrace();
        } finally {
            //3.关闭回话
            if(session!=null){
                session.close();
            }
        }
    }
}
增删改更新操作
<?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.yjxxt.mappers.EmpMapper2">
    <!--增删改默认结果类型为影响行数-->
    <insert id="addEmp" parameterType="emp">
        insert into emp(empno,ename,sal,deptno) values(#{empno},#{ename},#{sal},#{deptno})
    </insert>

    <update id="updateEnameByEmpno" parameterType="Emp">
        update emp set ename = #{ename} where empno  = #{empno}
    </update>

    <delete id="deleteEmpSome">
        delete from emp where empno in(
        <foreach collection="list" item="item" separator=",">
            #{item}
        </foreach>
        )
    </delete>
</mapper>
//测试增删改更新操作
public class Class002_EmpTest {
    public static void main(String[] args) {
        //1.获取回话
        SqlSession session = null;
        try {
            session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession(); /*openSession(true) 自动提交事务,默认手动提交*/
            //2.执行sql
            //insert
            Emp emp = new Emp();
            emp.setEmpno(9999);
            emp.setEname("胡歌");
            emp.setSal(2000);
            emp.setDeptno(40);
            /*int rows = session.insert("com.yjxxt.mappers.EmpMapper2.addEmp",emp);
            if(rows>0){
                session.commit();  //事务提交
            }else{
                session.rollback(); //事务回滚
            }
            System.out.println(rows>0?"跟新成功":"更新失败");*/

            //update
            /*emp.setEname("彭于晏");
            int rows = session.update("com.yjxxt.mappers.EmpMapper2.updateEnameByEmpno",emp);
            if(rows>0){
                session.commit();
                System.out.println("更新成功");
            }else{
                session.rollback();
                System.out.println("更新失败");
            }*/

            //delete
            int rows = session.delete("com.yjxxt.mappers.EmpMapper2.deleteEmpSome",List.of(9999,7999));
            if(rows>0){
                session.commit();
                System.out.println("更新成功");
            }else{
                session.rollback();
                System.out.println("更新失败");
            }

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.关闭回话
            if(session!=null){
                session.close();
            }
        }
    }
}

结果类型

<?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">
<!--测试结果类型 : 基本数据类型 | 包装类  javabean  date  String  List  Map  List<Map>
    如果结果为 集合,添加集合的泛型类型
    Map当结果类型为map,把一条数据的每一个字段作为map中的一个键值对,一个map展示一条数据
    List<Map>如果有多条数据,每一个调数据作为一个map放入list中
-->
<mapper namespace="com.yjxxt.mappers.EmpMapper3">
    <!--double : 根据员工编号查询员工薪资-->
    <select id="querySalByNo" parameterType="int" resultType="double">
        select sal from emp where empno = #{empno}
    </select>

    <!--date : 根据员工信息查询员工的入职日期-->
    <select id="queryDateByName" parameterType="string" resultType="date">
        select hiredate from emp where ename = #{name}
    </select>

    <!--map : 根据员工的编号,查询员工信息-->
    <select id="queryMapByNo" parameterType="int" resultType="map">
        select * from emp where empno = #{empno}
    </select>

    <!--List<Map> : 根据员工姓名模糊匹配员工数据-->
    <select id="queryListMap" parameterType="string" resultType="map">
        select * from emp where ename like '%'||#{ename}||'%'
    </select>
</mapper>
//测试结果类型
public class Class003_EmpTest {
    public static void main(String[] args) {
        //1.获取回话
        SqlSession session = null;
        try {
            session = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession(); /*openSession(true) 自动提交事务,默认手动提交*/
            //2.执行sql
            //double : 根据员工编号查询员工薪资
            double sal = session.selectOne("com.yjxxt.mappers.EmpMapper3.querySalByNo",7369);
            System.out.println(sal);

            //date : 根据员工信息查询员工的入职日期
            Date date = session.selectOne("com.yjxxt.mappers.EmpMapper3.queryDateByName","KING");
            System.out.println(date);

            // <!--map : 根据员工的编号,查询员工信息-->
            Map<String,Object> map = session.selectOne("com.yjxxt.mappers.EmpMapper3.queryMapByNo",7369);
            System.out.println(map);

            System.out.println("---------------------------");

            /*List<Map> : 根据员工姓名模糊匹配员工数据*/
            List<Map<String,Object>> listMap =  session.selectList("com.yjxxt.mappers.EmpMapper3.queryListMap","A");
            listMap.forEach(System.out::println);

        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            //3.关闭回话
            if(session!=null){
                session.close();
            }
        }
    }
}
接口绑定方案

封装:
    sqlSession回话的封装工具类

public class SessionUtils {
    private static SqlSessionFactory factory = null;

    static{
        try {
            factory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取回话
    public static SqlSession getSession(){
        SqlSession session = null;
        if(factory!=null){
            session = factory.openSession(true);
        }
        return session;
    }
}
    测试接口绑定方案:
        1.定义接口
            定义抽象方法(业务)
        2.与接口相关联的sql映射文件
        3.测试使用
 
public interface EmpMapper {
    //查询所有的员工数据
    public List<Emp> queryAllEmp();
}
<?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">
<!--
    测试接口绑定方案下的sql映射文件:
        1.接口与sql映射文件在同一个包中
        2.接口与sql映射文件同名
        3.sql映射文件的命名空间namespace,要求定义为接口的包名.接口名(权限定名)
        4.sql标签的id属性值定义为与其对应的接口中抽象方法名
        5.sql的返回值与参数要求与抽象方法的返回值与参数保持一致

-->
<mapper namespace="com.yjxxt.mappers.EmpMapper">
    <!--查询所有的员工数据-->
    <select id="queryAllEmp" resultType="emp">
            select * from  emp
   </select>
</mapper>
/*
    测试接口绑定方案的基本使用
 */
public class Class001_interface_bind {
    public static void main(String[] args) {
        //1.获取回话
        SqlSession session = SessionUtils.getSession();
        //2.获取接口的实现类对象
        //接口多态
        EmpMapper mapper = session.getMapper(EmpMapper.class);
        //3.调用功能
        List<Emp> list = mapper.queryAllEmp();
        list.forEach(System.out::println);
        //4.关闭回话
        session.close();
    }
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值