Java学习笔记24-MyBatis框架

Posted JanuaryFM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java学习笔记24-MyBatis框架相关的知识,希望对你有一定的参考价值。

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

1.MyBatis使用步骤

  • 1.下载jar包
  • 2.jar包资源拿到项目中,add as lib... mybatis核心jar包 mybatis依赖jar包 数据库的驱动jar包
  • 3.定义mybatis核心配置文件--> 参考文档+官网
  • 4.定义sql映射文件 定义要执行的sql语句
  • 5.jar类中进行测试 加载核心配置文件 构建工厂 获取回话 执行sql 处理结果 关闭回话

三个常用查询方法:

  • selectOne() 执行指定sql,得到一个结果
  • selectList() 执行指定sql,得到一个list集合,如果没查到,返回List中没有数据,但是不是null
  • selectMap() 执行指定sql,得到一个Map集合,如果没查到,返回空map

核心配置文件:

<?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>

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">
<!--
    映射配置:
        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="com.yjxxt.entity.Dept" >
        select * from dept
  </select>

    <!--根据部门编号查询部门对象-->
    <select id="queryDeptByNo" parameterType="int" resultType="com.yjxxt.entity.Dept">
        select * from dept where deptno = #deptno
    </select>
</mapper>

运行测试程序: 

//实例代码-基本Mybatis使用流程
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")
        //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");
        //5.处理结果
        list.forEach(System.out::println);
        System.out.println(dept);
        System.out.println(map);
        //6.关闭回话
        session.close();
    

2.properties标签和typeAliases标签

(1)properties标签

        通过properties标签实现软编码,src下定义配置文件db.properties,mybatis核心配置文件中添加properties标签,指定加载外部的properties文件,注意定义位置。

获取properties文件中数据时候,要通过$的方式获取

(2)typeAliases标签

作用:用于给java类型定义别名,方便在配置文件中使用(以下三种)

  • 给User类定义别名为u
  • 省略alias属性, 表示类别名为类名, 大小写不敏感
  • 可以通过package标签给整个包下的所有类定义别名,别名为类名
//实例代码-Mybatis核心配置文件
<?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>
        <package name="com.xjm.entity"/>
    </typeAliases>
    <!--环境配置-->
    <environments default="ev">
        <environment id="ev">
            <transactionManager type="JDBC"/>
            <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映射配置加载-->
    <mappers>
        <package name="com.xjm.mappers"/>
    </mappers>
</configuration>

3.parameterType入参类型

        如果执行的是条件查询,DML,需要在调用方法的时候传递参数,此时, 可以在sql标签中通过 parameterType属性指定参数的类型(别名|权限定名). 而在sql语句,通过#的方式获取参数。

parameterType: 基本数据类型(四类八种) 包装类 String Date Javabean Map List 数组

(1)一个参数的查询

SQL映射文件的配置:

//根据员工姓名查询员工数据,返回类型为emp
<?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>
</mapper>

 运行程序文件:

//实例代码-一个参数类型的查询
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);
            list3.forEach(System.out::println);
         catch (IOException e) 
            e.printStackTrace();
         catch (ParseException e) 
            e.printStackTrace();
         finally 
            //3.关闭回话
            if(session!=null)
                session.close();
            
        
    

 (2)多个参数查询

        多个参数传递时, 由于sqlSession中提供的查询方法,只允许传递一个sql参数, 因此可以对多个参数进行 封装,可以对象,集合,数组

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.yjxxt.mappers.EmpMapper">
    <!--
        入参类型: 基本数据类型 包装类  String Date Javabean 数组 List Map
    -->

    <!--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>

运行程序文件:

//实例代码-多个参数查询
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
            //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();
            
        
    

4.增删改更新操作

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.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();
            
        
    

5. 接口绑定方案

        Myabaits会自动将接口与xml文件进行绑定,实际上就是Mybatis互根据接口和对应的xml文件创建一个接 口的实现类,换言之,就是可以得到接口类型的一个对象,方便方法的调用。

(1)定义接口

public interface EmpMapper 
    //查询所有的员工数据
    public List<Emp> queryAllEmp();


(2)SQL映射文件配置

(测试接口绑定方案下的sql映射文件):

  • 1.接口与sql映射文件在同一个包中
  • 2.接口与sql映射文件同名
  • 3.sql映射文件的命名空间namespace,要求定义为接口的包名.接口名(权限定名)
  • 4.sql标签的id属性值定义为与其对应的接口中抽象方法名
  • 5.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">
<!-- sql映射文件的命名空间namespace,要求定义为接口的包名.接口名(权限定名)-->
<mapper namespace="com.yjxxt.mappers.EmpMapper">
    <!--查询所有的员工数据  || sql标签的id属性值定义为与其对应的接口中抽象方法名-->
    <!--sql的返回值与参数要求与抽象方法的返回值与参数保持一致-->
    <select id="queryAllEmp" resultType="emp">
            select * from  emp
   </select>
</mapper>

(3)运行程序文件

在使用时,通过SqlSession的getMapper() 方法,返回接口代理对象,从而调用以实现的抽象方法

//sqlSession回话的封装工具类-SSessionUtils
//工具类中封装了加载配置文件和获取回话的方法
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();
    

6.接口绑定实现基本CRUD操作

        1.定义接口文件

//实例代码-接口文件定义增删改除的方法
public interface EmpMapper 
    //查询所有的员工数据
    public List<Emp> queryAllEmp();

    //根据员工编号查询员工信息
    public Emp queryEmpByNo(int empno);

    //根据员工薪资与部门查询满足条件的员工姓名
    public List<String> queryNameBySalDeptno(@Param("sal") double sal, @Param("deptno") int deptno);

    //删除
    public int deleteEmpByEmpno(int empno);

    //插入
    public int addEmp(Emp emp);

2.SQL映射文件配置

//实例代码-SQL映射文件增删改除语句
<mapper namespace="com.yjxxt.mappers.EmpMapper">
    <!--查询所有的员工数据-->
    <select id="queryAllEmp" resultType="emp">
            select * from  emp
   </select>
    <select id="queryEmpByNo" parameterType="int" resultType="emp">
        select * from emp where empno = #empno
    </select>

    <select id="queryNameBySalDeptno" resultType="string">
        select ename from emp where sal>#sal and deptno = #deptno  /*[arg1, arg0, param1, param2]  匹配参数抽象方法的列表*/
    </select>

    <delete id="deleteEmpByEmpno" parameterType="int">
        delete from emp where empno = #empno
    </delete>

    <insert id="addEmp" parameterType="emp">
        insert into emp(empno,ename,deptno) values(#empno,#ename,#deptno)
    </insert>
</mapper>

以上是关于Java学习笔记24-MyBatis框架的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记:Spring框架

Java培训学习笔记分享:SpringMVC框架

Java框架spring Boot学习笔记:注入对象类型属性

JUnitJava 单元测试框架 | 学习笔记

Java学习笔记——浅谈数据结构与Java集合框架(第一篇List)

Java学习笔记29(集合框架三:泛型)