【Java】手把手教你Mybatis毕业

MyBatis

什么是Mybatis

  • MyBatist是一款优秀的持久层框架

  • 他支持定制化SQL,存储过程以及高级映射

  • MyBatis避免几乎所有的JDBC代码和手动设置参数以及获取结果集

  • MyBatis原名叫iBatis

  • 2013年11月迁入github,所以现在要去giehub上找该开源项目的源码

  • iBatis提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)

什么是持久化

说白了就是将数据存放到数据库中,使数据持久化,要是数据在内存中根本不符合数据持久化的概念

  • 持久化就是将程序的数据在持久状态和瞬时状态转化的过
  • 使数据达到持久化状态的不仅仅是数据库(JDBC),还可以使用I/O

什么是持久层

在一个完整的企业级开发环境中,注重的是分工明确,逻辑分化,不同层实现不同的业务

之前学习了MVC三层架构,分别对应module层,view层,controler层

  • 应用数据数据持久化技术的层,数据持久化存在的代码块
  • 在项目中分层名称为:Data Access Objects(DAOs)

MyBatis的优点

相对于JDBC而言,的确还是有很多好处的,最重要的一点:技术没有高低

  • 简单易学

  • 灵活:实现SQL和程序代码分离,当然如果不使用MyBatis也可以实现,目前能想到的手段就是写在配置文件(propies)中,

    MyBatis是将SQL写在xml中,便于统一管理和优化。

  • 解除SQL与程序代码的耦合,将持久化的代码块以独立分层的方式写在DAO层,将业务逻辑数据访问逻辑分离,使系统设计更清晰,也提高了可维护性。

  • 提供映射标签,支持对象与数据库的ORM字段关系映射

  • 提供对象关系映射标签,支持对象关系组建维护

  • 提供XML标签,支持编写动态SQL

使用MyBatis

  • 编写MyBatis配置文件

    ​ 配置文件放在src/resources资源目录下**(给我记住一句话,这句话到哪里都适用,“约定大于配置”)**

    <configuration>
        <enviroments default="development">
            <environment id="development">
                <transationManager type="JDBC" />
                <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>
        </enviroments>
        
        <mappers>
            <!--每一个Mapper.xml都需要在Mybatis的配置文件中注册,个JavaWeb中的每一个Servlet都需要在web.xml中注册是一个道理-->
            <!--仔细看是外层大标签是mappers,所以可以注册多个-->
            <!--不同包级之间一定要使用  "/"  分割,否则出错了别来找我哦!-->
            <mapper resource="..." />
            <mapper resourc="..." />
            
        </mappers>
    </configuration>
    
  • 获取SQLSessionFactory对象(可以封装为工具类,固定代码使用)

    String resource = "mybatis-config.xml";
    InputStream inputStream = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    
  • 创建一个能执行SQL的对象

    //该对象与connetion对象无异,其旗下的方法是直接可以执行SQL语句的
    SqlSession sqlssion = sqlSessionFactory.openSession();
    

编写代码阶段

  • DAO层

    //编写DAO层接口
    public interface UserDao{
    	//User对象为数据库的实体类
    	List<User> geUserList();
    }
    
  • 接口实现类有原来的UserDaoImp转变成一个Mapper配置文件

    在使用JDBC的时候UserDaoImpl做为操作数据库的对象,完成对数据库中User的查询更新删除查找操作。

    现在,Mybatis中出现了Mapper名称,XML格式的配置文件来代替原来使用JDBC完成操作代码。

    //等待编写
    

    测试阶段

    重点且致命性错误(一)
    org.apache.ibatis.binding.BindingException: Type interface com.kuang.dao.UserDao is not known to the MapperRegistry.
    
    英文释义:registry——>登记处
    
    //报该错误是因为,每一个Mapper.XML都需要在Mybatis核心配置文件中注册
    
    重点且致命性错误(二)
    //错误示意:初始化异常失败
    java.lang.ExceptionInInitializerError
        
    //报该错误是因为Maven的原因,还是上面提到的一句话——————>“约定大于配置”
    
    //调用响应方法获取SQL执行对象————>SqlSession
    SqlSession sqlsession = MyBatisUtil.getSqlSession();
    
    //UserDao是数据库操作的接口,面向接口编程,直接获取该接口[详询DAO层配置]
    UserDao userdao = sqlsession.getMapper(UserDao.class);
    
    //调用该接口的方法
    List<User> list = userdao.getUserList();
    

CRUD

likely that neither a Result Type nor a Result Map was specified.
    可能既没有指定结果类型也没有指定结果映射。

Mybatis使用思路梳理

​ 到这里,其实大家已经了解mybatis各个部件的功能了,接下来就是将上述这些操作进行有规则的组合起来,大家就能轻松愉悦的使用我们的持久化框架Mybatis了,接下来大家跟着我的思路走,理完一边操作思路再结合我的实例,就能达到无脑上手操作的水平啦。

1、创建一个Maven项目,且Pom.xml中导入以下依赖

  <!--    配置SQL链接对象-->
<!--    注意mysql 5.1.47版本有问题,报错 Communications link failure-->
<!--    报错误为通信链接失败-->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.28</version>
    </dependency>

    <!--    配置Mybatis对象-->
    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.9</version>
    </dependency>

2、编写Mybatis配置文件,格式跟上面一样,为了显示更清楚的格式,我就在贴一遍

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>

<!--    mybatis注册-->
    <mappers>
        <mapper resource="Mapper.xml"/>
    </mapper
</configuration>

3、跟数据库连接,并根据数据库表中的字段编写响应的实体类

  • 数据表名称ibatis,分别有 id , name , age三个字段

在这里插入图片描述

  • 在Java中编写对应的实体类,一定要跟数据库中的字段名称和类型相对应

    /**
     * 该类为对应数据的实体类
     */
    public class Users {
        private String id;
        private String name;
        private int age;
    
        public Users() {
        }
    
        public Users(String id, String name, int age) {
            this.id = id;
            this.name = name;
            this.age = age;
        }
    
        public String getId() {
            return id;
        }
    
        public void setId(String id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int getAge() {
            return age;
        }
    
        public void setAge(int age) {
            this.age = age;
        }
    
        @Override
        public String toString() {
            return "Users{" +
                    "id='" + id + '\'' +
                    ", name='" + name + '\'' +
                    ", age='" + age + '\'' +
                    '}';
        }
    }
    

4、编写接口对象,并编写对数据库操作的方法

public interface UserDao {
    //获取数据库表中的所有记录
    List<Users> getUserList();

    //根据ID查询表中记录
    public List<Users> SearchUser(String ids);

    //增加记录
    public int addUser(Users user);

    //删除记录
    public int DelUser(String id);

    //更新记录
    public int UpdateUser(Users user);
    
}

5、编写书写SQL的xml文件,该文件集中书写SQL,实现了代码和SQL的分离(我的文件名叫:Mapper.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">
    
    
<mapper namespace="com.darling.Dao.UserDao">
<!--    查询表中的全部记录-->
    <select id="getUserList" resultType="com.darling.Pojo.Users">
        select * from ibatis
    </select>

<!--    向数据库表中插入数据,#{id} 是从传过来的对象中取数据-->
    <insert id="addUser" parameterType="com.darling.Pojo.Users">
        insert into ibatis (`id`,`name`,`age`)
        values (#{id},#{name},#{age})
    </insert>

</mapper>

6、编写测试类,键入下列代码(运行结果我就不贴了)

 public static void ListAllUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);

        //如果执行成功那么就返回ibatis表中的所有记录
        List<Users> List = userDao.getUserList();

        for (Users users : List) {
            System.out.println(users);
        }
    }

    //查询数据库表中的记录,以ID为条件
    public static void SearchUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);

        List<Users> users = mapper.SearchUser("3");

        for (Users user : users) {
            System.out.println(user);
        }

        sqlSession.close();
    }

完成上述操作之后,基本上Mybatis就毕业了,但是还是有必要更深一步详细的详细解释一下,我们使用数据库做的最多的是什么?那必然是CRUD增删改查,有了上面的基本理解之后,接下来我就带着大家一步一步的解释这些参数上面的关键字都代表的是什么意思!

CRUD

向数据库中添加数据
  • 在 UserDAO接口内编写约束方法

    public interface UserDao {
        //增加记录
        public int addUser(Users user);
    
    }
    

    注意一点在形参中的参数为Users实体类的类型,下面会提到。

  • 在我们编写的Mapper.xml中重点看以下代码

    <mapper namespace="com.darling.Dao.UserDao">
    <!--    向数据库表中插入数据,#{id} 是从传过来的对象中取数据-->
        <insert id="addUser" parameterType="com.darling.Pojo.Users">
            insert into ibatis (`id`,`name`,`age`)
            values (#{id},#{name},#{age})
        </insert>
    </mapper>
    

    到这里有很多关键字就需要解释一下了,首先是

    • namespace=“com.darling.Dao.UserDao”——>这个是将我们当前的Mapper跟我们编写的UserDao接口进行绑定

    • id=“addUser”——>这个ID里面填写的是我们接口中定义的方法

    • parameterType=“com.darling.Pojo.Users”——>注意这里面是我们接口中定义方法的形式参数的类型,如果是自己编写的类型必须是要从包级别一直引用到自己编写的返回值类型

    • #{id},#{name},#{age}——>首先这个是引用数据中参数,大家可以看到大括号中的名称跟我们编写的实体类Users中的属性是一致的,这里强调一下必须是一致的

      #{ }——>Mybatis中引用数据的常用方式,一定记住,后面还会用到,我就不提了。

  • 编写测试方法,执行看结果即可

    //实现添加用户的操作
    public static void addUser(){
        //获取sql操作对象,基本操作,日后封装成工具类
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
    
        int flag = mapper.addUser(new Users("5", "八重神子", 80));
        System.out.println(flag);
    
        //向数据库提交数据,否者不会更改数据库表内容
        sqlSession.commit();
    
        //释放操作对象
        sqlSession.close();
    }
    
删除数据表中的记录
  • UserDAO接口内编写约束方法

    public interface UserDao {
        //删除记录
        public int DelUser(String id);
    
    }
    

    注意在形参中参数类型和形参名称,下面会提到。

  • 在我们编写的Mapper.xml中重点看以下代码

    <!--    删除表中记录-->
        <delete id="DelUser" parameterType="String" >
            delete from ibatis where id=#{id}
        </delete>
    

    记住不用忘了标签一定要写在标签内。

    注意这里的parameterType内写的是String类型。

    注意#{id}引用数据的数据名称跟接口中定义的方法的形参名称相同,必须相同!!!

  • 编写测试方法,执行看结果即可

    //删除数据表中的记录
    public static void DelUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
    
        //删除ID为2的记录
        int i = mapper.DelUser("2");
    
        if (i>0) {
            System.out.println("删除成功");
        }
    
        //提交上述执行的事务,是数据库中的记录发生改变
        sqlSession.commit();
        sqlSession.close();
    }
    
更新数据表中记录
  • UserDAO接口内编写约束方法

    public interface UserDao {
        //更新记录
        public int UpdateUser(Users user);
    
    }
    

    注意在形参中参数类型和形参名称,下面会提到。

  • 在我们编写的Mapper.xml中重点看以下代码

    <!--    更新记录-->
    <update id="UpdateUser" parameterType="com.darling.Pojo.Users">
        update ibatis set name=#{name} where id=#{id}
    </update>
    

    记住不用忘了标签一定要写在标签内。

  • 编写测试方法,执行看结果即可

     //更新数据库中的数据
    public static void UpdateUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
    
        int flag = mapper.UpdateUser(new Users("5", "八重神子", 80));
    
        if (flag>0) {
            System.out.println("数据更新成功");
        }
    
        sqlSession.commit();
        sqlSession.close();
    }
    
查询数据表中的数据

​ 这里我们使用ID匹配的方式来进行查询。

  • UserDAO接口内编写约束方法

    public interface UserDao {
    	//根据ID查询表中记录
        public List<Users> SearchUser(String ids);
    }
    
  • 在我们编写的Mapper.xml中重点看以下代码

    <!--    不管是参数的数据还是对象的数据都需要使用  #{}来引用-->
    <select id="SearchUser" parameterType="String" resultType="com.darling.Pojo.Users">
        select * from ibatis where id=#{ids}
    </select>
    

    记住不用忘了标签一定要写在标签内。

  • 编写测试方法,执行看结果即可

    //查询数据库表中的记录,以ID为条件
    public static void SearchUser(){
        SqlSession sqlSession = MybatisUtil.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
    
        List<Users> users = mapper.SearchUser("3");
    
        for (Users user : users) {
            System.out.println(user);
        }
    
        sqlSession.close();
    }
    

总结

​ 看到这里的话,你的Mybatis正常使用已经没有任何问题了,无非就是CRUD的操作嘛,多看两遍,自己练练手,这个持久化框架就已经被你拿下了,学习的时候体会一下Mybatis带来的便捷性,跟JDBC自己编写DAO层使用Java代码跟SQL代码结合来实现CRUD的操作相比对,Mybatis绝对是更加便捷啦,还是亘古不变的话——>懒惰变相的使人进步。

错误预判

​ 博主在自己学习的时候发现了一个很有意思的bug,这里就跟大家分享一下,代码我贴在这里,相关的注释也有,有兴趣的自己尝试一下吧!!!(被注释掉的代码就是出现问题的代码,有兴趣的米娜桑自取…)

//更新数据库中的数据

    /**
     * 发现问题:
     *      如果我们使用伪链式编程的思路来进行操作并需要更新数据库表中的数据的时候
     *      我们就无法重写获取当初我们使用链式编程的操作sqlSession的对象了,这样就算从别处获得SqlSession对象来进行提交
     *      那么也不会对数据库进行任何改变和数据更新
     */
    public static void UpdateUser(){
//        if (MybatisUtil.getSqlSession().getMapper(UserDao.class).UpdateUser(new Users("5","李超群",80))>0) {
//            System.out.println("数据更新成功!");
//        }
//       MybatisUtil.getSqlSession().commit();
//       MybatisUtil.getSqlSession().close();
    }
}

时候发现了一个很有意思的bug,这里就跟大家分享一下,代码我贴在这里,相关的注释也有,有兴趣的自己尝试一下吧!!!(被注释掉的代码就是出现问题的代码,有兴趣的米娜桑自取…)

//更新数据库中的数据

    /**
     * 发现问题:
     *      如果我们使用伪链式编程的思路来进行操作并需要更新数据库表中的数据的时候
     *      我们就无法重写获取当初我们使用链式编程的操作sqlSession的对象了,这样就算从别处获得SqlSession对象来进行提交
     *      那么也不会对数据库进行任何改变和数据更新
     */
    public static void UpdateUser(){
//        if (MybatisUtil.getSqlSession().getMapper(UserDao.class).UpdateUser(new Users("5","李超群",80))>0) {
//            System.out.println("数据更新成功!");
//        }
//       MybatisUtil.getSqlSession().commit();
//       MybatisUtil.getSqlSession().close();
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

卡特霖娜

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值