MyBatis基础

Posted 57容杰龙

tags:

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

1.简介:

  MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现,是一个基于Java的持久层ORM关系映射框架。需要使用的Jar包:mybatis-3.0.2.jar(mybatis核心包)。mybatis-spring-1.0.0.jar(与Spring结合包)。

  MyBatis的前身是ibatis,但是在配置sql的语法上有明显的区别,并且spring目前的版本封装mybatis,至于mybatis-spring.jar文件也是mybatis团队复杂开发的jar包,用于和spring整合。之前ibatis的源码托管方是apache,而mybatis是google。

  每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得。SqlSessionFactoryBuilder可以从一个xml配置文件或者一个预定义的配置类的实例获得。

ORM关系映射对象模型表示的对象映射到基于S Q L 的关系模型数据库结构中去。这样,我们在具体的操作实体对象的时候,就不需要再去和复杂的 SQ L 语句打交道,只需简单的操作实体对象的属性和方法。

2.原理流程

1.MyBatis应用程序Configuration对象根据XML配置文件或注解创建SqlSessionFactory工厂,获取一个SqlSession,加载SQL配置信息,生成一个个MappedStatement对象(包括传入参数映射配置、执行的sql语句、结果映射配置),并存储在内存中

2.SQL解析,SqlSession包含了执行sql所需要的所有方法,可以通过SqlSession实例直接运行映射的sql语句

(调用方法时,会接收到SQL的ID和传入对象,MyBatis会根据SQL的ID找到对应的MappedStatement,然后根据传入的参数对象对MappedStatement进行解析,解析后可以得到最终需要执行的SQL语句和参数)

3.SQL执行,完成对数据的增删改查,得到数据库操作结果

4.结果映射将操作结果按照映射配置进行转换,转换成HashMap、JavaBean等

5.事务提交,用完之后关闭SqlSession,返回结果。

开发流程:

 

 

3.环境搭建

A.添加依赖

  mysql-connector-java-5.1.35、mybatis-3.4.1

B.设置主配置文件

  config.xml文件放在resources文件夹底下

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE configuration
 3   PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
 4   "http://mybatis.org/dtd/mybatis-3-config.dtd">
 5 <!-- 提供mybatis框架的常用设置,包括数据库数据源等 -->  
 6 <configuration>
 7 <!-- 设置别名 -->
 8     <typeAliases>
 9     <!-- 设置某个实体类的别名 -->
10         <!-- <typeAlias type="com.rong.entity.Dept" alias="Dept"/> -->
11         <!-- 设置某个包中的类都支持别名,该包下的类的别名都会设置成去掉包名,只是用类名作为别名 -->
12         <package name="com.rong.entity"/>
13     </typeAliases>
14 
15 
16     <!-- 设置数据库数据源环境  可以多个
17         default表示默认使用的是哪个环境
18      -->
19     <environments default="mysqlEnvironment">
20     <!-- 
21         id:设置当前环境的身份id
22         transactionManager:设置事务管理器    type:设置用哪个事务管理器           JDBC是使用默认JDBC的事务管理自动提交
23      -->
24         <environment id="mysqlEnvironment">
25             <transactionManager type="JDBC"></transactionManager>
26             <!-- 数据源配置    
27                 type:设置数据源的类型      POOLED表示使用连接池策略
28             -->
29             <dataSource type="POOLED">
30                 <property name="driver" value="com.mysql.jdbc.Driver"/>
31                 <property name="url" 
32                 value="jdbc:mysql://localhost:3306/utf8?useUnicode=true&amp;characterEncoding=utf-8"/>
33                 <property name="username" value="root"/>
34                 <property name="password" value="123123"/>
35             </dataSource>
36         </environment>
37     </environments>
38     <!-- 配置映射配置文件  没有配置,则会出现mapper失败的异常 
39         resource:加载的映射配置文件路径
40     -->
41     <mappers>
42         <mapper resource="com/rong/dao/deptMapper.xml"/>
43         <mapper resource="com/rong/dao/deptVoMapper.xml"></mapper>
44     </mappers>
45 </configuration>

4.SqlSession实现CRUD

 

SqlSession sqlSession;
    
    @Before
    public void before() throws IOException{
        //通过mybatis的api读取主配置文件
        Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
        //创建造SqlSessoin工厂的对象  
        SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
        //造工厂
        SqlSessionFactory sqlSessionFactory = factoryBuilder.build(reader);
        //生产sqlSession   SqlSession类与JDBC的Connection类似    
        sqlSession = sqlSessionFactory.openSession();//开启事务
        System.out.println(sqlSession.getConnection());
    }
    
    @After
    public void after(){
        sqlSession.commit();
        sqlSession.close();//关闭连接资源
    }



    @Test
    public void testSelect(){
        //selectOne  查询结果为唯一对象的时候使用   statement参数为当前调用的sql映射文件中的sql语句对象id,
        //parameter  是参数
        Dept dept = sqlSession.selectOne("findDept", 10);
        System.out.println(dept);
    }
    //int insert = sqlSession.insert("saveDept",dept );
    //int update = sqlSession.update("updateDept", dept);
    //int delete = sqlSession.delete("deleteDept",110);
 */
    @Test
    public void testFindAll(){
        List<Dept> list = sqlSession.selectList("findAll");
        for (Dept dept : list) {
            System.out.println(dept);
        }
    }

@Test
    public void testFindMap(){
        List<Object> list = sqlSession.selectList("findMap");
        System.out.println(list);
        for (Object object : list) {
            Map<String,Object> map = (Map<String, Object>) object;
            Set<String> set = map.keySet();
            for (String key : set) {
                System.out.print(key+":"+map.get(key)+" ");
            }
            System.out.println();
        }
    }

 

 1 /**
 2  * dept模块的数据访问层接口
 3  * Mapper映射器实现:
 4  * 1.方法名必须与对应的mapper映射xml文件中的sql的id一致
 5  * 2.映射xml文件的namespace必须与当前接口(Mapper映射器)的全限定名一致
 6  * 3.通过sqlSession对象的getMapper(Mapper映射器)  获取映射器对象  mybatis会自动根据当前的接口  通过动态代理
 7  * 生产子类对象,并且自动实现调用方法
 8  * @author Administrator
 9  *
10  */
11 public interface DeptMapper {
12     
13      Dept findDept(Integer id);//根据id查询部门
14     
15      void saveDept(Dept dept);
16     
17      void updateDept(Dept dept);
18     
19      void deleteDept(Integer id);
20     
21     List<Dept> findAll();
22     
23     List<Map<String,Object>> findMap();
24 }
<!-- 
    提供了sql映射配置信息,mybatis通过该配置来实现数据库表和实体类之间的映射关系
mapper是整个sql映射配置文件的根元素 
namespace:设置命名空间   应该与当前项目的模块中的dao接口全限定名对应
-->  
<mapper namespace="com.rong.dao.DeptMapper">
    <!-- 根据id查询部门信息 
        sql文件是直接写在当前映射文件中的
        select设置查询的SQL   id:该sql的标记,是一个唯一标识
        resultType:设置返回值类型    
        需要填写全限定名  com.rong.entity.Dept
        或者是别名       Dept   使用别名需要先设置
        parameterType:设置参数类型  参数个数唯一    可以是全限定名或者是mybatis提供的简写类型
        
        #{deptno}是mybatis的表达式    #{}是占位符   deptno是传入的参数  单一个参数,mybatis会自动传递过来赋值
        
        使用java提供的类型的全限定名 可使用简写   如 java.lang.Integer  ->integer   首字母改小写
    -->
    <select id="findDept" resultType="Dept" parameterType="integer">
        select deptno,dname,loc from dept where deptno=#{deptno}
    </select>
    
    <!-- 
        insert用于插入sql操作
        当执行该sql,mybatis会根据#{deptno}从当前传入的对象上调用get方法获取该属性值  ,所以需要属性与括号中的值对应
     -->
    <insert id="saveDept" parameterType="Dept">
        insert into dept values(#{deptno},#{dname},#{loc}) 
    </insert>
    
    <update id="updateDept" parameterType="Dept">
        update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}
    </update>
    
    <delete id="deleteDept" parameterType="integer">
        delete from dept where deptno=#{deptno}
    </delete>
    
    <!-- 查询所有记录
    resultType为当前一条记录对应的java的类型
     -->
    <select id="findAll" resultType="Dept">
        select deptno,dname,loc from dept
    </select>
    
    <!-- 查询一张表中的部分字段信息   或    多张表关联查询的结果   可以通过   返回map来实现 -->
    <select id="findMap" resultType="hashMap">
        select dname,loc from dept
    </select>
    
</mapper>

 5.结果对象属性与数据库表字段不一致情况

<mapper namespace="com.rong.dao.DeptVoMapper">
    
    
    <select id="findDeptVo" parameterType="integer" resultMap="deptMap">
        select deptno,dname,loc from dept where deptno=#{deptno}
    </select>
    <insert id="saveDeptVo" parameterType="DeptVo">
        insert into dept values(#{id},#{deptName},#{location})
    </insert>
    <!-- 
        resultType:当数据库表字段与实体类的属性名一致的情况下,mybatis会自动的生成一个resultMap来实现对应的关系映射
        resultMap自定义关系映射 :
        当结果对象的属性与数据库表字段不一致的情况下,需要自己指定关系映射
        type:设置哪个实体类进行关系映射    id:唯一标记
        result:设置当前的某个数据库字段与实体类某个属性的对应关系
               property:设置属性             column:设置字段
               javaType:该属性的类型       可以全限定名或简写(类名首字母小写)       基本数据类型情况下可以忽略
               jdbcType:该字段的数据库类型    必须使用指定的数据库类型名(全大写)    基本数据类型情况下可以忽略
     -->
    <resultMap type="DeptVo" id="deptMap">
        <result property="id" column="deptno" javaType="integer" jdbcType="INTEGER"/>
        <result property="deptName" column="dname" javaType="string" jdbcType="VARCHAR"/>
        <result property="location" column="loc" />
    </resultMap>
    
</mapper>

MyBatis实现分页查询

    /**
     * 分页功能,通过mybatis的api实现
     * selectList("findAll",null,new RowBounds(0, 2)):带三个参数的方法  第一个参数是sql的id 第二个参数是条件
     * 第三个参数是rowBounds对象
     * 查询所有部门信息,每页显示两条,显示出第一页
     */
    @Test
    public void testFindByPage(){
        List<Dept> list = sqlSession.selectList("findAll",null,new RowBounds(0, 2));
        for (Dept dept : list) {
            System.out.println(dept);
        }
    }

6.Mapper映射器

接口中的方法和映射文件中定义的语句一一对应。接口方法的名称必须和语句id完全相同,接口方法的返回值和参数和相应的语句相对应

将映射文件的命名空间改为对应的映射文件的类名

SqlSession上调用getMapper方法,并传入要获取的Mapper类

 

SqlSession sqlSession;
    DeptVoMapper mapper;
    @Before
    public void before(){
        sqlSession = MybatisUtil.openSession();
        mapper = sqlSession.getMapper(DeptVoMapper.class);
    }
    
    @After
    public void after(){
        sqlSession.commit();
        sqlSession.close();
    }
    
    @Test
    public void testFindVo(){
        DeptVo deptVo = mapper.findDeptVo(10);
        System.out.println(deptVo);
    }

 

以上是关于MyBatis基础的主要内容,如果未能解决你的问题,请参考以下文章

mybatis学习(39):动态sql片段

SSM-MyBatis-05:Mybatis中别名,sql片段和模糊查询加getMapper

mybatis动态sql片段与分页,排序,传参的使用

MyBatis动态SQL标签用法

MYBATIS05_ifwherechoosewhentrimsetforEach标签sql片段

[vscode]--HTML代码片段(基础版,reactvuejquery)