20200103——继续复习mybatis

mybatis与hibernate区别
hibernate是一个标准的orm框架(对象关系映射)不需要写sql语言。
但是如果需要对sql语句进行优化,比较困难
应用场景:适用于需求变化不多的小中型项目,比如后台管理系统

mybatis:专注于sql本身,需要程序员自己编写sql语句,优化比较方便
应用场景:需求变化较多的,互联网项目

mybatis开发dao方法

sqlsession使用范围
通过fatory创建sqlsession
工厂通过builder进行创建

使用单例模式管理sqlsessionFactory(工行内模式
将来使用spring与mybatis整合之后,使用单例模式管理sqlsessionFactory

sqlsession是一个面向用户的接口你
用于操作数据库的方法 selectOne selecttList
sqlsession是不安全的
还有数据域属性

原始开发dao方法
程序员需要写dao接口和实现类
需要向dao实现类中注入sqlsessionfatory,在方法体内通过sqlsessionfatory创建sqlsession

dao接口

public interface UserDao {
    //根据id查询用户信息
    public User findUserById(int id) throws Exception;

    //添加用户信息
    public void insertUser (User user) throws Exception;

    //删除用户信息
    public void deleteUser(int id )throws Exception;
    
}

实现接口类

package cn.mmz.mybatis.dao;

import cn.mmz.mybatis.pojo.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;

/**
 * @Classname UserDaoImpl
 * @Description dao接口实现类
 * @Date 2020/1/3 20:43
 * @Created by mmz
 */
public class UserDaoImpl implements UserDao {
    private SqlSessionFactory sqlSessionFactory;
    public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
        this.sqlSessionFactory = sqlSessionFactory;
    }

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = sqlSession.selectOne("test.findUserById",id);
        sqlSession.close();
        return user;
    }

    @Override
    public void insertUser(User user) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("test.insertUser",user);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void deleteUser(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("test.deleteUser",id);
        sqlSession.commit();
        sqlSession.close();
    }
}

如何创建一个测试类,
cmd+shift+T 在想要测试的类按下,就可以生成一个测试类了

package cn.mmz.mybatis.dao;

import cn.mmz.mybatis.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;

/**
 * @Classname UserDaoImplTest
 * @Description TODO
 * @Date 2020/1/3 21:04
 * @Created by mmz
 */
public class UserDaoImplTest {
    private SqlSessionFactory sqlSessionFactory;
    @Before
    public void setUp() throws  Exception{
        //创建sqlsessionFactory
        String resource = "SqlMapConfig.xml";
        //得到配置文件流
        InputStream inputStream =  Resources.getResourceAsStream(resource);
        //创建会话工厂,传入配置文件信息
        sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);
    }
    @Test
    public void findUserById() throws Exception{
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        User user = userDao.findUserById(1);
        System.out.println(userDao);
    }

    @Test
    public void insertUser() {
    }

    @Test
    public void deleteUser() {
    }
}

以上是生成的测试类,@Before写的是在进行单元之前都需要做些什么
就是需要生成sqlSessionFactory
然后在@Test方法中测试用例
就可以了

public void findUserById() throws Exception{
        UserDao userDao = new UserDaoImpl(sqlSessionFactory);
        User user = userDao.findUserById(1);
        System.out.println(userDao);
    }

总计原始dao开发问题
dao接口实现类方法存在大量的模板代码, 设想能否把代码提取出来

调用sqlsession方法时,将statement硬编码了

调用sqlsession方法传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错。不利于程序员开发

mapper代理方法

程序员只需要写接口,
还需要编写mapper映射文件
需要遵循开发规范

开发规范
namespace 等于mapper接口地址
在这里插入图片描述

mapper.java接口中的方法名和mapper.xml中的statement的id一致

mapper接口中的方法输入参数类型和statement的parameter指定的类型一致

mapper.java返回值与映射文件statement中的resultType的类型一致

总结
以上开发规范主要是对下边的代码进行统一生成

mybatis可以自动生成mapper接口实现类的代理对象

测试
在这里插入图片描述
我们一开始基于原始dao开发的时候,先创建了一个Userdao的接口interface,然后实例化这个接口为UserDaoImpl,这里面的方法写了如何进行操作

    @Override
    public User findUserById(int id) throws Exception {
        SqlSession sqlSession = sqlSessionFactory.openSession();

        User user = sqlSession.selectOne("test.findUserById",id);
        sqlSession.close();
        return user;
    }

所以当我们用mapper接口开发的时候,我们没有这个UserDaoImpl实例类,所以我们一开始要创建这个会话

 SqlSession sqlSession = sqlSessionFactory.openSession();

然后在创建该UserMapper的对象

        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);

这句话mybatis自动生成mapper代理对象

测试的时候报错了,原因是你配置好了UserMapper文件,你还需要把这个文件配置总体的SqlMapperConfig文件中

在这里插入图片描述
在这里插入图片描述
结果成功,由于User没加toString方法,所以返回的应该是地址

那么加上toString方法之后
在这里插入图片描述
代理对象内部调用selectOne 或者是selectList
如果mapper方法返回非集合对象,单个pojo对象,代理对象内部通过selectOne进行查询对象
那么如果是一个集合对象,那么会返回一个List

    public void findUserByName() throws Exception{
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper  userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> user = userMapper.findUserByName("小明");
        System.out.println(user);
    }

问题所在
mapper接口的方法参数只有一个,是否影响系统开发?
系统框架中,dao层代码是公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo来满足不同的业务方法的需求

注意:持久层中方法可以用包装类型,service方法中不建议使用包装类型(不利于业务层的可拓展维护)

发布了657 篇原创文章 · 获赞 39 · 访问量 6万+

猜你喜欢

转载自blog.csdn.net/qq_36344771/article/details/103826459