MyBatis

作者: YasA | 来源:发表于2018-08-03 15:10 被阅读0次

    ---------- Mybatis ------------

    - web项目:
        DBUtil(数据持久层)    // 支持这两层的框架 hibernate、Mybatis
        dao,entity,service(业务层) Model
        servlet(控制器) 
        view(视图层)
    
    (1).什么是Mybatis
        - Mybatis最早源于Apache基金会的一个开源项目ibatis,2010年这个项目由ApacheSoftware foundation迁移到goole code
          并且改名为mybatis。
        - mybatis是支持普通sql查询,储存过程和高级映射的优秀持久层框架。
        - mybatis封装了几乎所有的jdbc代码和参数的手工设置以及结果集检索。
        - Mybatis使用简单的xml或者注解和定义映射关系,将java的pojos(实体类对象)映射成数据库中的记录。
        
    (2).mybatis的体系结构
        - mybatis体系结构有以下几个关键部分:
            1.加载配置(有两种形式)
                * xml配置文件
                * java代码注解
                (mybatis将sql的配置信息加载成为一个个的MappedStatement对象(传入参数映射配置、执行sql语句,结果映射配置))
                并将其储存在内存中。
                
            2.sql解析
                * 当API接口层接收到调用请求的时候,会接收到传入sql的id和传入对象,mybatis会根据sql的id找到传入对象,
                mybatis会根据sql的id找到对应的mappedstatement,然后根据传入参数对象对mappededstatement进行解析,
                解析后可以得到最后要执行的sql语句和参数。
        
            3.sql执行
                * 将最终得到的sql和参数拿到数据库进行执行,得到操作数据库的结果。
                
            4.结果映射配置
                * 将操作数据库的结果按照映射配置进行转换,可以转换成HashMap、JavaBean或者基本数据类型等,并最终结果返回。
            
    (3).Mybatis配置文件
        - mybatis框架的xml配置文件包含下面两种类型:
            1.sqlMapConfig.xml
                * 主配置文件,用于指定数据库连接参数和框架参数的。
            2.sqlMap.xml
                * 映射定义文件,用于定义sql语句和映射信息。
    
    (4).Mybatis框架API简介
        - 在使用mybatis框架时,主要涉及以下几个API:
            1.SqlSessionFactoryBuilder
                * 该对象负责根据Mybatis配置文件SqlMapConfig.xml构建SqlSessionFactory实例。
            2.SqlSessionFactory
                * 每一个Mybatis的应用程序都以一个SqlSessionFactory对象为核心,该对象负责创建SqlSession对象实例。
            3.SqlSession
                * 该对象包含了所有执行sql操作的方法,用于执行已映射的sql。
                    
    (5).利用SqlSession实现crud操作            
        - 当获取SqlSession对象后,就可以利用它对数据库表执行增删改查的操作了。
            使用步骤如下:
                1.根据数据表编写实体类(java POJO)。
                2.编写SqlMap.xml映射文件,定义sql操作和映射信息。
                3.获取SqlSession对象,执行crud操作。
                4.提交事务(DML操作)
                5.释放SqlSession对象资源。
    
    (6).解决实体类和表字段的对应问题
        - Emp.xml
            * resultMap:主要解决 实体类对应表字段不同名的问题 实体类属性对应表中字段
            * property="属性" 
            * column="表中字段"
    
    (7).利用mybatis实现分页查询(假分页)
        缺点: mybatis 假分页(原理:实际是查询出所有记录,然后拿出部分,然后基于jdbc的absolute和next()方法获取部分记录)
              如果数据庞大,使用假分页会出现内存异常。
        - 在使用sqlSession的selectList()方法时,指定一个RowBounds分页器参数,即可指定返回的记录。
        - RowBounds(offset,limit)构造器
        - RowBounds bounds = new RowBounds(offset,limit); // offset:指定抓取记录的起始行,从0开始 limit
        
    (8).Mapper映射器
        - Mapper映射器是开发者创建绑定映射语句的接口,映射器接口实例可以从SqlSession中获取。
            * SqlSession session = sqlSessionFactory.openSession();
            * EmpMapper mapper = session.getMapper(EmpMapper.class);
        -
        
    
    1.创建web项目
        action
        dao
        entity
        util
        
    2.lib导入jar包
        mybatis-3.2.5.jar
        mysql-connector-java-5.1.13-bin.jar
        
    3.创建SqlMapConfig.xml 主配置文件(指定数据库连接参数和框架参数的)
    /*
    1.通过property标签关联数据库
    2.配置实体类映射文件 
    */
    
    <?xml version="1.0" encoding="UTF-8" ?>  
    <!DOCTYPE configuration PUBLIC "-//ibatis.apache.org//DTD Config 3.0//EN" 
        "http://ibatis.apache.org/dtd/ibatis-3-config.dtd">
    
    <configuration>
        <environments default="environment">
            <environment id="environment">
                <transactionManager type="JDBC" />
                <dataSource type="POOLED">
                    <!-- 主配置文件,用于指定数据库连接参数和框架参数的 -->
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql://localhost:3306/db_emp" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
        <!-- 配置实体类映射文件 -->
        <mappers>
            <mapper resource="com/entity/Emp.xml"/>
        </mappers>
    </configuration> 
    
    4.util包下创建DBUtil关联SqlMapConfig.xml
    
    package com.util;
    import java.io.IOException;
    import java.io.Reader;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    
    public class DBUtil {
        
        public static SqlSession getSession(){
            // 加载配置文件
            String conf = "SqlMapConfig.xml";
            SqlSession session = null;
            try {
                // Resources.getResourceAsReader()读取配置文件
                Reader reader = Resources.getResourceAsReader(conf);
                // 根据Mybatis配置文件SqlMapConfig.xml构建SqlSessionFactory实例
                SqlSessionFactoryBuilder sfb = new SqlSessionFactoryBuilder();
                // 创建SqlSessionFactory 每一个Mybatis的应用程序都以一个SqlSessionFactory对象为核心,该对象负责创建SqlSession对象实例。
                SqlSessionFactory sf = sfb.build(reader);
                // 创建SqlSession对象 该对象包含了所有执行sql操作的方法,用于执行已映射的sql。
                session = sf.openSession();
            } catch (Exception e) {
                e.printStackTrace();
            }
            return session;
            
        }
        
        //测试
        public static void main(String[] args) {
            SqlSession session = getSession();
            System.out.println(session);
        }
    
    }
    
    
    5.entity包下创建Emp实体类(关联表字段)
    6.创建Emp.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">
    
        <!-- 映射定义文件,用于定义sql语句和映射信息 -->
        
        <!-- 对应接口 -->
    <mapper namespace="com.dao.EmpMapper">
        <!--
            属性:id="实现功能" 
            parameterType="传入参数类型" //id(int) 
            parameterMap(了解..)
            resultType="返回类型" 
            resultMap="返回类型" 
            <insert></insert>: mybatis将sql的配置信息加载成为一个个的MappedStatement对象
        -->
    
        <!-- 实现EMP信息的添加功能 -->
        <insert id="addEmp" parameterType="com.entity.Emp">
            insert into
            t_emp(name,sex,birthday,address,dept_id,aihao)
            values(#{name},#{sex},#{birthday},#{address},#{dept_id},#{aihao})
        </insert>
    
        <!-- 实现EMP信息的修改功能 -->
        <update id="updateEmp" parameterType="com.entity.Emp">
            update t_emp set
            name=#{name},sex=#{sex},birthday=#{birthday},address=#{address},dept_id=#{dept_id},aihao=#{aihao}
            where id=#{id}
        </update>
    
        <!-- 实现EMP信息的删除功能 -->
        <delete id="deleteEmp" parameterType="int">
            delete from t_emp where
            id=#{随便写}
        </delete>
    
        <!-- 实现EMP信息的查询功能 -->
        <select id="findById" parameterType="int" resultMap="empMap">
            select *
            from t_emp where id=#{id}
        </select>
    
        <!-- 实现EMP信息的查询所有功能 -->
        <select id="findAll" resultMap="empMap">
            select * from t_emp
        </select>
        
        <!-- 查询员工信息列表 (真分页)-->
        <select id="findPages" parameterType="com.entity.EmpPage" resultMap="empMap">
            select * from t_emp limit #{page},#{pageSize};
        </select>
        
        <!--
            resultMap:主要解决 实体类对应表字段不同名的问题 实体类属性对应表中字段
            property="属性" 
            column="表中字段"
        -->
        <resultMap type="com.entity.Emp" id="empMap">
            <result property="name" column="name" />
            <result property="sex" column="sex" />
            <result property="address" column="address" />
            <result property="birthday" column="birthday" />
            <result property="dept_id" column="dept_id" />
            <result property="aihao" column="aihao" />
        </resultMap>
    
    </mapper>
    
    
    8.创建EmpPage实体类(对应Emp.xml 真分页)
    
    package com.entity;
    
    public class EmpPage {
        private int page;
        private int pageSize;
        
        // 对应xml #{page}
        public int getPage() {
            return (page-1)*pageSize;
        }
        public void setPage(int page) {
            this.page = page;
        }
        public int getPageSize() {
            return pageSize;
        }
        public void setPageSize(int pageSize) {
            this.pageSize = pageSize;
        }
        
    }
    
    7.dao包下创建EmpDao 实现功能(使用EmpMapper后,可以删除EmpDao)
    
    package com.dao;
    import java.util.List;
    import org.apache.ibatis.session.RowBounds;
    import org.apache.ibatis.session.SqlSession;
    import com.entity.Emp;
    import com.entity.EmpPage;
    import com.util.DBUtil;
    
    /**
     * 1.获取工具类(static)
     * 2.创建方法
     * 3.  添加 session.insert("Emp.xml的id属性值",parameterType)
     *     修改 session.update("Emp.xml的id属性值",parameterType);
     *     删除 session.delete("Emp.xml的id属性值",parameterType);
     *     查询单条数据session.selectOne("Emp.xml的id属性值",parameterType);
     *   查询所有session.selectList("Emp.xml的id属性值"); // 查询所有不需要传入参数
     */
    public class EmpDao {
        // 获取工具类 session
        static SqlSession session = DBUtil.getSession();
    
        // 添加
        public void saveEmp(Emp emp) {
            // 根据session调用insert方法 ("对应xml里面的id值",对应实体类对象)
            session.insert("addEmp", emp);
            // 提交事务
            session.commit();
            // 释放资源
            session.close();
        }
    
        // 修改
        public void updateEmp(Emp emp) {
            // 根据session调用update方法
            session.update("updateEmp", emp);
            // 提交事务
            session.commit();
            // 释放资源
            session.close();
        }
    
        // 根据id删除
        public void deleteEmp(int id) {
            // 根据session调用delete方法
            session.delete("deleteEmp", id);
            // 提交事务
            session.commit();
            // 释放资源
            session.close();
        }
    
        // 根据id查询
        public Emp findEmpById(int id) {
            // session.selectOne 查询并返回一条数据
            Emp emp = session.selectOne("findById", id);
            // 释放资源
            session.close();
            return emp;
        }
    
        // 查询员工列表
        public List<Emp> findAll() {
            List<Emp> emps = session.selectList("findAll");
            // 释放资源
            session.close();
            return emps;
    
        }
        
        // 员工信息的分页查询(假分页)
        public List<Emp> findPages(int page,int pageSize){
            // 指定一个RowBounds分页器参数,指定返回的记录
            RowBounds rb = new RowBounds((page-1)*pageSize, pageSize);
            // 
            List<Emp> emps = session.selectList("findAll", null, rb);
            // 释放资源
            session.close();
            return emps;
        }
        
        // 员工信息的分页查询(真分页)
        public List<Emp> findPages2(EmpPage epage){
            List<Emp> emps = session.selectList("findPages", epage);
            session.close();
            return emps;
        }
        
        // 测试
        public static void main(String[] args) {
            /*
            // 添加
            Emp emp = new Emp();
            emp.setId(1);// 修改 需要id 添加不需要 id
            emp.setName("Yazolo");
            emp.setSex("1");
            emp.setBirthday("1666-6-6");
            emp.setAddress("休斯顿");
            emp.setDept_id(2);
            emp.setAihao("1,2");
            EmpDao dao = new EmpDao();
            // dao.saveEmp(emp);// 添加
            dao.updateEmp(emp);// 修改
            */
            
            /*
            // 根据id删除
            EmpDao dao = new EmpDao();
            dao.deleteEmp(12);// 删除
             */
            
            /*
            // 根据id查询
            EmpDao dao = new EmpDao();
            Emp emp = dao.findEmpById(3);// 根据id查询
            // 注:[如果xml查询配置字段不一样会报0(具体有解决方法 对应字段暂时解决这个问题)]
            System.out.println(emp.getName() + "|" + emp.getSex() + "|"
                    + emp.getBirthday() + "|" + emp.getAddress() + "|"
                    + emp.getDept_id() + "|" + emp.getAihao());
            */      
    
            /*
            // 查询所有
            EmpDao dao = new EmpDao();
            List<Emp> emps = dao.findAll();
            System.out.println(emps.size() + "***********");
            */
            
            /*
            // mybatis 假分页(实际是查询出所有,然后拿出部分)
            // 问题:如果数据庞大,使用假分页会出现内存异常。
            EmpDao dao = new EmpDao();
            List<Emp> emps = dao.findPages(1, 3);
            for (Emp e : emps) {
                System.out.println(e.getId()+"||"+e.getName());
            }
            */
            
            /*
            // sql语句 分页
            EmpDao dao = new EmpDao();
            // 设置 page  pageSize
            EmpPage epage = new EmpPage();
            epage.setPage(1);
            epage.setPageSize(4);
            List<Emp> emps = dao.findPages2(epage);
            for (Emp e : emps) {
                System.out.println(e.getId()+"||"+e.getName());
            }
            */
        }
    
    }
    
    
    9.创建接口 EmpMapper
    /*
        实现CRUD 分页... 功能
    */
    
    package com.dao;
    import java.util.List;
    import com.entity.Emp;
    import com.entity.EmpPage;
    
    public interface EmpMapper {
        /*
         * 1.一个接口可以有多个方法
         * 2.接口没有构造方法
         * 3.接口里面所有方法必须是抽象(abstract)方法
         * 4.接口不能包含成员变量,除了static和final变量
         * 5.接口不是被类继承,而是要被类实现。
         * 6.抽象类的方法可以有方法体,但接口中的方法不能有方法体
         * 7.抽象类的成员变量可以是各种类型,而接口的成员变量只能是public static final类型
         * 8.接口中不能含有静态代码块以及静态方法,而抽象类可以有静态代码块和静态方法
         * 9.一个类只能继承一个抽象类,而一个类却可以实现多个接口。
         * */
        
        // 抽象方法是否传参取决于Emp.xml parameterType
        
        // 添加员工信息
        public void addEmp(Emp emp);
        // 修改员工信息
        public void updateEmp(Emp emp);
        // 删除员工信息
        public void deleteEmp(int id);
        // 根据id查询
        public void findById(int id);
        // 查找所有员工
        public List<Emp> findAll();
        // 分页查询
        public List<Emp> findPages(EmpPage epage);
        
    }
    
    
    10.创建测试类 EmpTest
    
    package com.test;
    import java.util.List;
    import org.apache.ibatis.session.SqlSession;
    import com.dao.EmpDao;
    import com.dao.EmpMapper;
    import com.entity.Emp;
    import com.entity.EmpPage;
    import com.util.DBUtil;
    
    public class EmpTest {
        public static void main(String[] args) {
            // 获取工具类session
            SqlSession session = DBUtil.getSession();
            // 调用方法 得到Mapper接口
            EmpMapper mapper = session.getMapper(EmpMapper.class);//(类类型)
            /*
            // 添加
            Emp emp = new Emp();
            emp.setName("IceIceIce...");
            emp.setSex("0");
            emp.setBirthday("1995-5-5");
            emp.setAddress("菲律宾");
            emp.setDept_id(2);
            emp.setAihao("1,2");
            mapper.addEmp(emp);
            session.commit();
            */
            
            /*
            // 删除
            mapper.deleteEmp(12);
            session.commit();
            */
            
            /*
            // 修改
            Emp emp = new Emp();
            emp.setId(7);
            emp.setName("Paparazi");
            emp.setSex("1");
            emp.setBirthday("1995-5-5");
            emp.setAddress("上海");
            emp.setDept_id(2);
            emp.setAihao("1,2");
            mapper.updateEmp(emp);
            session.commit();
            */
            
            /*
            // 根据id查询
            EmpDao dao = new EmpDao();
            Emp emp = dao.findEmpById(5);
            System.out.println(emp.getId()+"||"+emp.getName());
            */
            
            /*
            // 查询所有
            List<Emp> emps = mapper.findAll();
            for (Emp e : emps) {
                System.out.println(e.getId()+"||"+e.getName());
            }
            */
            
            /*
            // 分页查询
            EmpPage epage = new EmpPage();
            epage.setPage(1);
            epage.setPageSize(3);
            List<Emp> emps = mapper.findPages(epage);
            for (Emp e : emps) {
                System.out.println(e.getId()+"||"+e.getName());
            }
            */
        }
    }
    
    

    相关文章

      网友评论

          本文标题:MyBatis

          本文链接:https://www.haomeiwen.com/subject/zeoyvftx.html