MyBatis

本文详细介绍了 MyBatis 框架的特点、环境搭建步骤,包括核心配置文件、SQL映射文件的配置,并解析了配置文件的各项元素。通过实例展示了如何使用 MyBatis 连接数据库、执行 SQL 语句,以及事务管理和入参类型。此外,还探讨了接口绑定方案和多参数传递方法。
摘要由CSDN通过智能技术生成

1.MyBatis:基于持久层的orm框架

Mybatis特点

属于持久层ORM框架

  1. 对原生JDBC的封装
  2. 半自动化框架
  3. 学习成本低,使用简单,适合做一些业务多变的互联网项目

环境搭建

1)下载资源jar包
2)项目下新建lib路径,需要的jar包放入lib路径下,选中右键add as lib..
3)编写代码程序

1.核心配置文件 : 做mybatis使用的核心基本配置
                数据库的连接信息
                是否使用连接池技术
                SQL映射文件的扫描
                ----
2.SQL映射文件 : 定义SQL语句
3.测试执行使用mybatis框架连接数据库,执行SQL语句,得到结果

2.Mybatis配置文件

mybatis提供两种配置文件, 核心配置文件 mybatisconfig.xml|mybatis.xml 与 SQL映射文件
mapper.xml

核心配置文件添加

是一个xml文件,命名无要求,位置无要求,一般成为mybatis.xml,放在src路径下

1.1. dtd
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
1.2. mybatis.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">
<!-- mybatis的全局配置文件 -->
<configuration>
<!--
用于指明使用哪一个开发环境
default : 用于指定使用的环境的id属性值
-->
<environments default="ev">
<!-- 用户配置开发环境 id: 环境的唯一标识 -->
<environment id="ev">
<!--
事务管理器
JBDC : 表示采用JDBC一样的事务管理方式
-->
<transactionManager type="JDBC"/>
<!--
用于配置数据库连接吃和数据库连接参数
POOLED : 表示mybatis采用连接池技术
-->
<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映射文件配置 -->
<mappers>
<!-- 指明SQL映射文件路径 resource : 包路径 com/.../xxxMapper.xml-->
<mapper resource="com/yjxxt/mappers/UserMapper.xml"/>
</mappers>
</configuration>

Mybatis SQL映射文件

在Mybatis中,推荐使用mappers作为包名,我们只需要写一个映射配置文件就可以,UserMapper.xml,用于
定义要执行的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: 命名空间
-->
<mapper namespace="com.yjxxt.mappers.UserMapper">
<!--
查询标签: select 用于编写查询语句
id : 当前文件中保证唯一
resultType : 结果的类型
parameterType : 入参类型
-->
     <select id="queryAll" resultType="com.yjxxt.pojo.User">
      select * from t_user
  </select>
</mapper>

注意:不要忘记mybatis核心xml文件中的mapper配置

测试

public class TestUser {
public static void main(String[] args) throws IOException {
//1.加载mybatis全局核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis.xml");
//2.构建SqlSessionFactory对象
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3.通过工厂获取会话SqlSession
SqlSession session = factory.openSession();
//4.通过session调用方法执行查询
//selectList() 查到的数据返回一个list集合,没查到返回空的list
//selectList 的第一个参数为statement: 命名空间+id
List<User> list =
session.selectList("com.yjxxt.mappers.UserMapper.queryAll");
System.out.println(list);
//5.关闭会话资源
session.close();
}
}

3.Mybatis配置文件详解

1. 核心配置文件

1.configuration
配置文件的根元素,所有其他的元素都要在这个标签下使用(dtd文件规定)
2.environments default=“environment”
用于管理所有环境, 并可以指定默认使用那个环境,通过defualt属性来指定
3.environment
用来配置环境,id属性用于唯一标识当前环境
4.transactionManager type=“JDBC”

用户配置事务管理器

type属性
	用来指定Mybatis采用何种方式管理事务
	JDBC : 表示采用与原生JDBC一致方式管理事务
	MANAGED: 表示讲事务管理交给其他容器进行, Spring
5.dataSource type=“POOLED”

用于配置数据源, 设置Myabtis是否使用连接池技术,并且配置数据库的四个连接参数

type属性:
		POOLED : 表示采用连接池技术
		UNPOOLED: 表示每次都会开启和关闭连接, 不采用连接池技术
		JNDI : 使用其他容器提供数据源
6.property
用于配置数据库连接参数 (driver,url,username,password)
7.Mappers
用于配置扫描sql映射文件

2. SQL映射文件(mapper)

SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):

resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语句

查询语句是 MyBatis 中最常用的元素之一(映射文件配置见代码)

1.mapper

SQL映射文件的根元素

namespace 属性
	用于指定命名空间, mydatis通过namespace+id的方式用来定位sql语句,所以必须要指定namespace,通过被配置为权限定路径 包名+xml文件名(不带后缀名)
2.select

用来定义查询语句 update insert delete

id 属性
	用阿里唯一表示当前sql语句,在当前的命名空间中唯一,不能重复 , 类型方法名
resultType 属性
	用于设定查询返回的结果的数据类型,要写类型的权限定名(包名+类名),如果返回值的是集合类型,要定义集合的泛型类型

4.通过properties标签实现软编码

<?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>
        <!--alias 设置别名-->
        <!--<typeAlias type="com.yjxxt.pojo.Dept" alias="Dept"/>-->
        <!--没有定义alias属性,默认别名为类型,不缺分大小写-->
        <!--<typeAlias type="com.yjxxt.pojo.Dept"/>-->
        <!--设置一个包下所有的类型定义别名,别名默认类名,不区分大小写-->
        <package name="com.yjxxt.pojo"/>
    </typeAliases>

    <!--
        mybatis使用环境配置
        default : 选择要使用的环境
                  属性值定义为环境的id值
    -->
    <environments default="dev">
        <!--environment 定义环境配置    id : 环境的唯一标识-->
        <environment id="dev">
            <!--transactionManager事务管理机制 : type="JDBC"选择使用JDBC项目的事务管理机制-->
            <transactionManager type="JDBC"/>
            <!--dataSource : 数据源配置|是否使用来连接池技术-->
            <!--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映射文件-->
    <mappers>
        <!--一个SQL映射文件的加载 : resource指定SQL映射文件在项目中的路径-->
        <mapper resource="com/yjxxt/mappers/DeptMapper.xml"/>
        <mapper resource="com/yjxxt/mappers/EmpMapper.xml"/>
    </mappers>
</configuration>

5.三个查询方法

  1. selectList(“命名空间.id”) 用户查询多条数据情况,返回一个List集合, 没有查到数据返回空集合,不是null
  2. selectOne(“命名空间.id”) 用于查询单条数据,返回一个数据, 如果没有查到返回null
  3. selectMap(“命名空间.id”,key的字段名) 用于查询多条记录情况, 返回Map集合, 需要指定那个属性作为key, sql查询结果作为value,指定的字段值作为key, 如果查不到, 返回一个空map集合,不是null
/*
   测试3个查询方法
    selectOne("命名空间.id")  查询一个数据,返回对应类型的一个结果,如果没有查询到返回null
    selectOne("命名空间.id",Object) 第二个参数为sql语句的入参
    selectList("命名空间.id") 查询多个数据,返回一个List集合,如果没有查询到返回空的List
    selectList("命名空间.id",Object) 第二个参数为sql语句的入参
    selectMap("命名空间.id","作为key的字段名") 查询多个数据,返回一个Map集合,如果没有查询到返回空的Map
    selectMap("命名空间.id",Object,"作为key的字段名") 第二个参数为sql语句的入参,第三个参数返回Map集合中每条数据作为key的字段名

 */
public class Class002_Method {
    public static void main(String[] args) throws IOException {
        //1.加载XML核心配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        //2.创建SqlSessionFactory实例
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        //3.通过工厂获取回话SqlSession-->相当于Connection
        SqlSession session = factory.openSession();
        //4.执行指定的SQL语句
        Emp emp = session.selectOne("com.yjxxt.mappers.EmpMapper.queryEmpByNo",7369);

        List<Emp> list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDeptno",30);

        Map<Integer,Emp> map =  session.selectMap("com.yjxxt.mappers.EmpMapper.queryEmpByDeptno",20,"empno");


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

        //6.关闭回话
        session.close();
    }
}

6.SqlSession封装

/*
    对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(); //默认手动 提交事务
            //session = factory.openSession(true); //设置自动 提交事务
        }
        return  session;
    }
}

7.事务(Transaction)

  1. 事务是数据库操作的最小单位,有着ACID的特性,应该保证一个事务下的多条SQL语句要么都成功,要么都失败.
  2. Mybatis中配置了事务管理器,type属性设置JDBC,表示Mybatis采用和原生JDBC相同的事务管理机制
  3. 在Myabatis执行操作的开始,将自动提交功能关闭了,需要我们在执行DML操作时候,手动提交设置|设置自动提交

手动提交:

session.commit(); //事务提交

设置自动提交事务:

public static SqlSession getSession() {
SqlSession session =null;
if(factory!=null) {
//session = factory.openSession(); //默认手动提交事务
session = factory.openSession(true); //自动提交
}
return session;
}

增删改操作

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.DeptMapper">
   <!--查询-->
    <select id="queryAll" resultType="Dept">
        select * from dept
    </select>
    <!--insert-->
    <insert id="addDept">
        insert into dept values(88,'haha','shanghai')
    </insert>

    <delete id="deleteDept" parameterType="int">
        delete from dept where deptno = #{0}
    </delete>
</mapper>

Java测试类

/*
    测试增删改
    事务:
        默认手动提交
 */
public class Class001_Test {
    public static void main(String[] args) throws IOException {
        //获取回话
        SqlSession session = SessionUtils.getSession();
        //执行sql
        //int rows = session.insert("com.yjxxt.mappers.DeptMapper.addDept");

        int rows = session.delete("com.yjxxt.mappers.DeptMapper.deleteDept",87);
        //得到结果处理结果
        if(rows>0){
            session.commit();
        }else{
            session.rollback();
        }
        //关闭回话
        session.close();
    }
}

8.入参类型parameterType

基本数据类型|包装类 String Date JAVABEAN 数组 List Map

JAVABEAN : 当sql需要的参数存在多个,并且为一个对象的不同属性,可以先把对个参数封装成javabean对象,然后作为一个入参传递
                   sql中占位符的名字需要匹配入参对象的属性名
数组|list :sql需要的多个参数是同种类型,一个字段的多个值,适合使用数组|list
              sql语句中需要使用foreach标签进行遍历
Map : sql需要的多个参数,不属于一个对象的不不同属性值,可以封装为Map集合中的不同键值对
sql中占位符的名字需要匹配键值对的key

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">
    <!--基本数据类型|包装类: 根据部门编号查询-->
    <select id="queryEmpByDeptno" parameterType="int" resultType="Emp">
        select * from emp where deptno = #{deptno}
    </select>

    <!--String: 根据员工姓名查询-->
    <select id="queryEmpByName" parameterType="String" resultType="Emp">
        select * from emp where ename = #{ename}
    </select>

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

    <!--JAVABEAN: 根据员工姓名与部门编号同时查询-->
    <select id="queryEmpByNameDeptno" parameterType="emp" resultType="Emp">
        select * from emp where ename=#{ename} and deptno = #{deptno}
    </select>

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

    <!--Map: 根据员工薪资或者员工所在部门编号查询-->
    <select id="queryEmpBySalDeptno" parameterType="map" resultType="Emp">
       select * from emp where sal>#{sal} or deptno=#{deptno}
    </select>
</mapper>

Java测试类

/*
    测试入参类型
 */
public class Class002_Param {
    public static void main(String[] args) throws IOException, ParseException {
        //获取回话
        SqlSession session = SessionUtils.getSession();
        //执行sql
        List<Emp> list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDeptno",20);

        //list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByName","SMITH");

        //Date  1981/12/3
        //Date date = new SimpleDateFormat("yyyy/MM/dd").parse("1981/12/3");
        //list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByDate",date);

        //JAVABEAN
        Emp emp = new Emp();
        emp.setEname("SMITH");
        emp.setDeptno(20);
        //Emp emp1 = session.selectOne("com.yjxxt.mappers.EmpMapper.queryEmpByNameDeptno",emp);

        //System.out.println(emp1);

        //数组|List
        //list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpByidSome",new int[]{7369,7499});

        //Map
        Map map = Map.of("sal",1500,"deptno","10");
        list = session.selectList("com.yjxxt.mappers.EmpMapper.queryEmpBySalDeptno",map);

        list.forEach(System.out::println);

        //关闭回话
        session.close();
    }
}

9.结果类型 resultType

定义:查询到的结果集中的每一个数据的类型

 基本数据类型|包装类 String  Date  JAVABEAN  List  Map  List<Map>

如果结果类型为List,resultType设置的为集合的泛型类型
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">
    <!--基本数据类型|包装类 : 根据员工姓名模糊查询员工编号-->
    <select id="queryIdByNameLike" parameterType="String" resultType="int">
        select empno from emp where ename like '%'||#{ename}||'%'
    </select>

    <!--Date : 根据员工编号查询员工入职日期-->
    <select id="queryDateById" parameterType="int" resultType="Date">
        select hiredate from emp where empno = #{empno}
    </select>

    <!--Map : 根据员工编号查询员工信息 -->
    <!--查询到一条数据,返回一个Map,一条数据的不同字段值作为Map集合中的不同键值对-->
    <select id="queryMapById" parameterType="int" resultType="Map">
        select * from emp where empno = #{empno}
    </select>

    <!--List<Map> : 根据薪资查询员工信息-->
    <select id="queryMapBySal" parameterType="map" resultType="Map">
        select empno,ename,sal,comm,deptno  from emp where sal between #{low} and #{high}
    </select>
</mapper>

Java测试类

/*
    测试结果类型
 */
public class Class003_Result {
    public static void main(String[] args) throws IOException, ParseException {
        //获取回话
        SqlSession session = SessionUtils.getSession();
        //执行sql
        //int
        /*List<Integer> list1 = session.selectList("com.yjxxt.mappers.EmpMapper2.queryIdByNameLike","A");
        list1.forEach(System.out::println);*/

        //Date
        /*Date date = session.selectOne("com.yjxxt.mappers.EmpMapper2.queryDateById",7369);
        System.out.println(date);*/

        //Map
        //Map<String,Object> map = session.selectOne("com.yjxxt.mappers.EmpMapper2.queryMapById",7369);

        List<Map<String,Object>> list = session.selectList("com.yjxxt.mappers.EmpMapper2.queryMapBySal",Map.of("low",1000,"high",1500));

        list.forEach(System.out::println);

        //关闭回话
        session.close();
    }
}

10.接口绑定方案

映射文件:

  1. 接口名与SQL映射文件名字保持一致,同时放在同一个包下
  2. SQL映射文件命名空间要求定义为: 与之绑定的接口的包名.文件名
  3. sql标签的id属性值要求与所对应的抽象方法的方法名保持一致
  4. SQL的参数与返回值要求与对应的抽象方法的参数与返回值保持一致
    在核心配置文件中扫描接口
 <!--扫描接口绑定方案-->
    <mappers>
        <!--扫描一个指定的接口-->
        <!--<mapper class="com.yjxxt.mappers.DeptMapper"/>-->
        <!--扫描一个包下的所有接口-->
        <package name="com.yjxxt.mappers"/>
    </mappers>

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.DeptMapper">
    <select id="queryAll" resultType="dept">
        select * from dept
    </select>

    <!--如果参数只有一个,站位符的名字可以任意定义-->
    <select id="queryDeptByNo" parameterType="int" resultType="dept">
        select * from dept where deptno = #{id}
    </select>

    <!--多参数 : sql语句中占位符的名字默认为[arg1, arg0, param1, param2]-->
    <select id="queryDeptByNameDeptno" resultType="dept">
        <!--select * from dept where dname = #{param1} and loc = #{param2}-->
        select * from dept where dname = #{dname} and loc = #{loc}
    </select>

    <!--入参javabean,占位符的名字匹配对象的属性名-->
    <insert id="insertDept" parameterType="dept">
        insert into dept values(#{deptno},#{dname},#{loc})
    </insert>

    <!--update-->
    <update id="updateDept">
        update dept set dname=#{dname} where deptno = #{deptno}
    </update>
</mapper>

定义接口

/*
    测试接口绑定方案
        接口名与SQL映射文件名字保持一致
        同时放在同一个包下
 */
public interface DeptMapper {
    //查询所有的部门信息
    List<Dept> queryAll();

    //根据部门编号查询部门信息
    Dept queryDeptByNo(int deptno);
    //根据部门姓名与部门位置一起查询
    //@Param("参数别名") sql语句中占位符的名字可以对应通过@Param注解定义的别名
    Dept queryDeptByNameDeptno(@Param("dname") String dname,@Param("loc") String loc);

    //insert
    int insertDept(Dept dept);

    //修改update 根据部门编号修改部门名称
    int updateDept(@Param("deptno") int deptno,@Param("dname") String dname);
}

Java测试类

/*
    测试接口绑定方案
 */
public class Class001_Test {
    public static void main(String[] args) throws IOException {
        //获取回话
        SqlSession session = SessionUtils.getSession();
        //获取接口的实现类对象
        DeptMapper mapper = session.getMapper(DeptMapper.class);
        //通过实现类对象调用重写后的方法
        List<Dept> list = mapper.queryAll();
        //list.forEach(System.out::println);

        Dept dept = mapper.queryDeptByNo(20);


        dept = mapper.queryDeptByNameDeptno("SALES","shanghai");
        System.out.println(dept);

        //insert
        //mapper.insertDept(new Dept(91,"渠道部","学校"));

        //update
        mapper.updateDept(90,"网络部");



        //关闭回话
        session.close();
    }
}

多参数传递

1 方式一

a)接口中定义方法

User selByUP(String username, String password);

b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{arg+数字}或#{param+数字}的方式.

<select id="selByUP" resultType="user">
select * from t_user where username=#{param1} and password=#{param2}
</select>

2 方式二

a) 接口中定义方法, 参数中使用@Param 注解设定参数名用于在 SQL 语句中使用.

User selByUP(@Param("username") String username, @Param("password")
String password);

b) 映射文件中提供对应的标签. 此时, SQL 语句中获取方式有两种, 通过#{参数名称}或#{param+数字}的方式.

<select id="selByUP" resultType="user">
select * from t_user where username=#{username} and
password=#{password}
</select>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值