• 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);
        }
  • 相关阅读:
    html5中新增的form表单属性
    FORM
    .Net Core 发布失败
    Sql Server查询最近执行sql
    HttpWebRequest.GetResponse()操作超时
    使用SqlBulkCopy批量插入/更新数据
    ADO .NET 往数据库批量插入数据发生错误:超时时间已到,但是尚未从池中获取链接
    Ueditor代码内容前台只显示一行
    Lambda表达式
    委托的简单使用
  • 原文地址:https://www.cnblogs.com/57rongjielong/p/7887737.html
Copyright © 2020-2023  润新知