美文网首页
Mybatis入门(一)之简单介绍

Mybatis入门(一)之简单介绍

作者: 穿梭在围城 | 来源:发表于2018-12-04 11:29 被阅读0次

    Mybatis入门

    一、简介

    ​ MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

    ​ Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

    二、为什么要使用Mybatis

    jdbc问题总结如下:

    1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

    2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。

    3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。

    4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

    三、Mybatis的架构

    执行流程

    1、 mybatis配置SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

    mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

    2、 通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

    3、 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

    4、 mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

    5、 Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

    6、 Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

    7、 Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

    四、Mybatis与Hibernate的对比

    1、Hibernate是完全的ORM框架。只需要对对象进行操作无需写sql语句。
    ​ Hibernate学习成本高。
    ​ 开发速度很快
    ​ 应用场景:传统项目的开发。管理系统的开发。

    2、Mybatis并不是一个完全的orm框架。只能把返回值映射到一个对象中。只是对sql语句的一个封装。
    ​ 学习成本很低,要求熟练掌握sql语句。
    ​ 开发速度不是很快。
    ​ 互联网项目:都是使用mysql的数据库集群。

    五、Mybatis的搭建

    下载地址:https://github.com/mybatis/mybatis-3/releases

    jar包内容

    这里我使用maven来引入Mybatis的jar包

    创建主配置文件(放在资源目录)

    <?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>
        <!-- 和spring整合后 environments配置将废除 -->
        <environments default="development">
            <environment id="development">
                <!-- 使用jdbc事务管理 -->
                <transactionManager type="JDBC" />
                <!-- 数据库连接池 -->
                <dataSource type="POOLED">
                    <property name="driver" value="com.mysql.jdbc.Driver" />
                    <property name="url" value="jdbc:mysql:///test?characterEncoding=utf-8" />
                    <property name="username" value="root" />
                    <property name="password" value="root" />
                </dataSource>
            </environment>
        </environments>
        
    </configuration>
    

    改文件与Spring整合后将舍去

    properties(属性)
    ​ settings(全局配置参数)
    ​ typeAliases(类型别名)
    ​ typeHandlers(类型处理器)
    ​ objectFactory(对象工厂)
    ​ plugins(插件)
    ​ environments(环境集合属性对象)
    ​ environment(环境子属性对象)
    ​ transactionManager(事务管理)
    ​ dataSource(数据源)
    ​ mappers(映射器)

    创建pojo对象

    package cn.zw.pojo;
    
    import java.util.Date;
    
    public class User {
        private int id;
        private String username;// 用户姓名
        private String sex;// 性别
        private Date birthday;// 生日
        private String address;// 地址
        public User() {
            super();
            // TODO Auto-generated constructor stub
        }
        public User(int id, String username, String sex, Date birthday, String address) {
            super();
            this.id = id;
            this.username = username;
            this.sex = sex;
            this.birthday = birthday;
            this.address = address;
        }
        
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getUsername() {
            return username;
        }
        public void setUsername(String username) {
            this.username = username;
        }
        public String getSex() {
            return sex;
        }
        public void setSex(String sex) {
            this.sex = sex;
        }
        public Date getBirthday() {
            return birthday;
        }
        public void setBirthday(Date birthday) {
            this.birthday = birthday;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
                    + address + "]";
        }
        
        
    }
    
    

    创建mapper映射文件(放在资源目录下和pojo的同级目录)

    <?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语句的隔离
         id:同个命名空间下不可重复
         #{}:站位符号,相当于jdbc中的?,如何使简单类型的参数名称任意,如果是pojo类型的{pojo的属性名称}
         parameterType:参数类型
         resultType:结果集封装到pojo类中
     -->
    <mapper namespace="user">
        <select id="getUserById" parameterType="int" resultType="cn.zw.pojo.User">
            select * from user where id = #{id}
        </select>
     </mapper>
    

    在主配置文件中引入mapper映射文件

    引入mapper映射文件

    测试查询单行

    package cn.zw.hello;
    
    import java.io.IOException;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Test;
    
    import cn.zw.pojo.User;
    
    public class DemoTest {
        
        @Test
        public void fun01() throws IOException{
            //通过SqlSessionFactoryBuilder获取SqlSessionFactory对象
            SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder();
            SqlSessionFactory sqlSessionFactory = sessionFactoryBuilder.build(Resources.getResourceAsStream("SqlMapConfig.xml"));
            //获取连接
            SqlSession sqlSession = sqlSessionFactory.openSession();
            //执行语句
            User user = sqlSession.selectOne("user.getUserById", 1);
            System.out.println(user);
            sqlSession.close();
        }
    }
    

    测试查询多行

    <select id="selectByName" parameterType="String" resultType="cn.zw.pojo.User">
        select * from user where username like #{username}
    </select>
    
    
    @Test
    public void fun02() throws IOException{
        //获取连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        List<User> users = sqlSession.selectList("user.selectByName", "%xiao%");
        System.out.println(users);
        sqlSession.close();
    }
    

    插入一条数据

    <insert id="save" parameterType="cn.zw.pojo.User" >
        INSERT INTO `user` (
        `user`.username,
        `user`.sex,
        `user`.birthday,
        `user`.address
        )
        VALUES
        (#{userName},#{sex},#{birthday},#{address}) 
    </insert>
    
    @Test
    public void fun03() throws IOException{
        User user = new User();
        user.setUsername("铁甲小宝");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("大阪");
        //获取连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        int insert = sqlSession.insert("user.save", user);
        sqlSession.commit();
    }
    

    插入一条数据并返回主键

    <insert id="save2" parameterType="cn.zw.pojo.User" >
        <selectKey order="AFTER" keyProperty="id" resultType="int">
            SELECT LAST_INSERT_ID();
        </selectKey>
    
        INSERT INTO `user` (
        `user`.username,
        `user`.sex,
        `user`.birthday,
        `user`.address
        )
        VALUES
        (#{username},#{sex},#{birthday},#{address}) 
    </insert>
    
    
    

    删除一条记录

    <delete id="delete" parameterType="int">
        DELETE  FROM `user` WHERE id = #{id};
    </delete>
    
    @Test
    public void fun05() throws IOException{
        //获取连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("user.delete", 2);
        sqlSession.commit();
    }
    
    

    更新一条数据

    <update id="update" parameterType="cn.zw.pojo.User">
    update user set username = #{username} WHERE id = #{id}
    </update>
    
    @Test
    public void fun06() throws IOException {
        User user = new User();
        user.setId(3);
        user.setUsername("蟑螂恶霸");
        user.setSex("男");
        user.setBirthday(new Date());
        user.setAddress("大阪");
        // 获取连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("user.update",user);
        sqlSession.commit();
    }
    

    六、开发中使用dao模式

    传统方式:接口+实现类+mapper映射文件(xml)
    传统

    然后实现类再去映射文件中调用sql语句

    mapper代理方式(官方推荐):接口+映射文件
    代理

    相比传统的方式来说,省去了一步实现接口的步骤,所以会方便开发者,下面我们就来看看用这种方式需要满足什么条件?

    开发规范:
    ​ 1)mapepr映射文件的namespace应该是接口的全路径。
    ​ 2)接口的方法名称应该和sql语句的id一致。
    ​ 3)接口的参数类型应该和parameterType一致。
    ​ 4)接口返回值类型应该和ResultType保持一致。

    package cn.zw.mapper;
    
    import cn.zw.pojo.User;
    
    public interface UserMapper {
        void save(User user);
        void delete(int id);
        void update(User user);
        User findOne(int id);
    }
    
    
    <?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="cn.zw.mapper.UserMapper">
    
        <insert id="save" parameterType="cn.zw.pojo.User">
            INSERT INTO
            `user` (
            `user`.username,
            `user`.sex,
            `user`.birthday,
            `user`.address
            )
            VALUES
            (#{username},#{sex},#{birthday},#{address})
        </insert>
    
        <delete id="delete" parameterType="int">
            DELETE FROM `user` WHERE id =
            #{id};
        </delete>
    
        <update id="update" parameterType="cn.zw.pojo.User">
            update user set username =
            #{username} WHERE id = #{id}
        </update>
        <select id="findOne" parameterType="int" resultType="cn.zw.pojo.User">
            select *
            from user where id = #{id}
        </select>
    
    </mapper>
    
    规范
    
    public class DemoTest2 {
        SqlSessionFactory sqlSessionFactory = null;
    
        @Before
        public void init() throws IOException {
            // 通过SqlSessionFactoryBuilder获取SqlSessionFactory对象
            SqlSessionFactoryBuilder sessionFactoryBuilder = new                     SqlSessionFactoryBuilder();
            sqlSessionFactory = sessionFactoryBuilder.build(Resources.getResourceAsStream("SqlMapConfig.xml"));
    
        }
    
        @Test
        public void fun01() throws IOException {
            SqlSession session = sqlSessionFactory.openSession();
            UserMapper mapper = session.getMapper(UserMapper.class);
            User user = mapper.findOne(3);
            System.out.println(user);
        }
    
    }
    

    相关文章

      网友评论

          本文标题:Mybatis入门(一)之简单介绍

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