MyBatis基础学习知识点2

MyBatis基础学习知识点2,第1张

MyBatis基础学习知识点2

本文衔接MyBatis基础学习知识点1,继续对以下两个问题进行探讨

        1.dao配置文件主要是用来干什么的?如何进行配置?

        2.使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

目录

dao配置文件主要是用来干什么的?如何进行配置?

mapper标签

select标签

insert标签

update标签

delete标签

使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

基础步骤

SqlSessionFactory接口

SqlSession接口

MybatisUtils工具类

实现dao接口

使用代理模式

mybatis的dao代理

理解参数

parameterType

传递一个简单类型参数

传递多个简单类型参数

使用实体类属性传递参数

按照位置传递参数

使用map传参

#占位符与$占位符的区别

封装MyBatis输出结果

resultType

当查询结果为自定义类型时

当查询的结果为简单类型时

当查询结果为Map类型时

resultMap自定义查找结果

有关like查询


dao配置文件主要是用来干什么的?如何进行配置?

        我们拿出一个最简单的dao层配置文件进行分析




    
    
        select * from user
    
insert标签

        主要用于书写insert相关sql语句

id属性

        设置sql语句名称,为了方便分清结构层次,以及后续工具的使用,建议使用对应的方法名称


    insert into user values(#{id},#{username},#{password})
update标签

        主要用于书写update相关sql语句

id属性

        设置sql语句名称,为了方便分清结构层次,以及后续工具的使用,建议使用对应的方法名称

    
        update user set password = #{password} WHERe id = #{id};
    
delete标签

        主要用于书写delete相关sql语句

id属性

        设置sql语句名称,为了方便分清结构层次,以及后续工具的使用,建议使用对应的方法名称

    
        delete from user where id = #{id}
    
使用测试方法测试程序运行是如何实现的?每条语句起什么作用?

        首先我们使用以下基础执行代码作为例子进行说明

@Test
    public void test1() throws IOException {
        //定义mybatis核心配置文件在classes下的路径
        String mybatisPath = "mybatisConfig.xml";
        //根据路径获取字节输入流对象
        InputStream is = Resources.getResourceAsStream(mybatisPath);
        //创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //通过SqlSessionFactoryBuilder对象的build方法创建SqlSessionFactory对象
        SqlSessionFactory factory = sqlSessionFactoryBuilder.build(is);
        //通过工厂类的openSession方法获取sql执行对象
        SqlSession sqlSession = factory.openSession();
        //sql执行对象的selectOne方法
        //获取第一个参数,即执行id:由namespace + . + SQL语句标签id
        String id = "com.ling.mybatis.dao.UserDao" + "." + "findUserById";
        User user = sqlSession.selectOne(id);
        System.out.println(user);
        //关闭sqlSession
        sqlSession.close();
    }
基础步骤

第一步:设置中心配置文件的路径

第二步:使用Resources静态方法,将中心配置文件加载进字节输入流

第三步:获取SqlSessionFactoryBuilder对象,该对象的主要任务是创建factory对象

第四步:使用SqlSessionFactoryBuilder对象的build方法,传入字节输入流,解析中心配置文件,初始化数据库连接池,并且获取各个dao配置文件。

第五步:通过SqlSessionFactory对象的openSession方法获取sqlSession执行对象,该对象主要用于sql语句的执行 *** 作。

第六步:定义字符串,锁定需要执行的语句

第七步:执行sql语句

SqlSessionFactory接口 接口作用

        SqlSessionFactory接口是sqlSession的工厂接口,主要作用是创建SqlSession对象

        SqlSessionFactory功能众多,创建过程较之其他比较缓慢,需要更多的时间和空间,在项目中有一个即可。

接口方法

openSession();获取一个默认的SqlSession对象,默认是需要手动提交事务的

openSession(boolean):boolean参数表示是否自动提交事务

        true:创建一个自动提交事务的SqlSession

        false:等同于没有参数的openSession

SqlSession接口 接口作用

        提供了大量的执行sql语句的方法,线程不安全

        针对线程不安全,需要注意使用步骤

使用步骤

1.在方法内部执行sql语句之前,先获取sqlSession对象

2.调用sqlSession方法对象,执行sql语句

3.关闭sqlSession,执行sqlSession的close方法

        如此一来,该sqlSession就只在方法内存在,在该方法所在执行的线程空间内存在,这样其他线程就无法获取这条线程内的数据对象。

接口方法

selectOne(String,Object):执行返回值只有一行的执行结果,多余一行会执行错误

selectMap(String,Object):执行返回一个map类型的接口

selectList(String,Object):执行返回一个list集合数据

insert(String,Object):执行添加 *** 作

update(String,Object):执行修改 *** 作

delete(String,Object):执行删除 *** 作

commit:执行事务提交 *** 作

rollback:执行事务回滚 *** 作

MybatisUtils工具类

        由上文实现步骤我们可以看出,每一次进行数据库 *** 作我们都需要进行以上七步的 *** 作,但是七步 *** 作中有大量的代码冗余,一到五步代码基本大致相同,因此我们可以写构造一个MybatisUtils工具类,专门用于mybatis初始化 *** 作。

public class MybatisUtils {

    private static SqlSessionFactory sqlSessionFactory = null;

    //通过静态代码块,当类进行加载时赋值
    static {
        String sqlPath = "mybatisConfig.xml";
        try {
            //根据核心配置文件路径获取字节输入流
            InputStream resource = Resources.getResourceAsStream(sqlPath);
            //使用Builder对象的build方法获取factory对象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获取SqlSession对象(不自动提交事务)
    public static SqlSession getSqlSession(){
        //openSession方法中没有参数,则取消自动提交。传入true则打开自动提交
        return sqlSessionFactory.openSession();
    }
}

        此时我们简化了前五步步骤,但是第六步简单的字符串拼接和第七步方法的执行还是没有简化,而且我们在使用的过程中发现,接口好像根本没啥作用,接口的方法没有被调用,接口也没有实现类,接口好像白写了?

实现dao接口

        按照Javaweb学习阶段三层架构的代码书写习观我们创建impl文件夹,并且于文件夹内部创建dao接口实现类。

public class UserDaoImpl implements UserDao {
    @Override
    public List findAllUser() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        String sqlPath = "com.ling.mybatis.dao.UserDao.findAllUser";
        List list = sqlSession.selectList(sqlPath);
        sqlSession.close();
        return list;
    }
}

        我们将第六步第七步的 *** 作步骤放到了接口实现类中,这样就完成了整合,当我们需要调用方法进行sql语句 *** 作时,创建dao接口实现类对象,执行其对应的方法即可。

        但是对于以上整合方案并不能帮助我们简化程序书写的步骤,只是简单的对数据 *** 作进行了整合 *** 作,我们需要一种可以直接完成数据 *** 作的方法

使用代理模式 mybatis的dao代理

代码书写

getMapper(dao接口的class类)

@Test
    public void test2() {
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        userDao.findUserById(1);
        sqlSession.close();
    }

        通过sqlSession的getMapper方法获取代理对象,我们在学习Spring框架的Aop增强时学习过了proxy代理模式,主要工作原理是通过反射机制创建目标增强对象的子类,并且在不改变原方法内容的情况下强化方法的参数,内容,返回值。

        这里的getMapper方法就是使用代理模式,创建userDao的实现类对象,并且通过类加载器和反射机制获取UserDao的路径名,以及方法名,自动的完成拼接,并且选择合适的sqlSession方法执行增删改查的 *** 作。这里就回收了为什么我们在设置dao层配置文件namespace属性尽量要设置为dao接口src下全路径,为什么sql语句标签id要设置为方法名。

理解参数

通过Java程序把数据传入到mapper文件中的sql语句,这里的参数主要是指dao接口方法中的形参

parameterType

        表示参数类型,指定dao方法的形参数据类型。这个形参的数据类型是给mybatis使用。mybatis在给sql语句的参数赋值时使用,我们在jdbc中学习过的防止sql语句注入,使用preparedStatement对象。我们对?内容进行属性值注入时,需要使用对应的setXXX(索引,值)方法进行输入,这里的parameterType就是在选择注入的属性类型。


     select * from user where id = #{id}
传递多个简单类型参数

        使用@Param注解,用于命名参数,在方法的形参前面使用,定义参数名。这个名称要用于mapper文件中,也就是#{}内的值就是参数命名后的名称

    List findUserByIdOrUsername(@Param("Sid") Integer id, @Param("Susername") String username);
    
        select * from user where id = #{arg0} or username = #{arg1}
    
使用map传参

        map中的key值就对应了#{}中的名称,value值即为注入的值。

List findUserByIdOrUsername(Map map);
标签的属性出现的

resultType:表示结果类型,mysql执行sql语句,得到java对象出现的类型,他的值有两种

        1.java类型的全限定名称(我们之前一直使用的)

        2.在中心配置文件中设置的别名

        别名我在第一篇文章中讲解中心配置文件的时候详细说过,他是在中心配置文件的typeAliases标签内部设置的,如果使用package标签取别名,那么就是整包一起取,如果使用typeAlias标签的话就是一个一个取,具体的优缺点可以看我的第一篇文章。

中心配置文件:


    
    
    
    
    

dao层配置文件:


        select * from user where id = #{id}
    
当查询的结果为简单类型时

        设置resultType直接设置为java中的路径

    
        select * from user where id = #{id}
    
Map getMapper(Integer id);
resultMap自定义查找结果

使用resultMap可以自定义结果集中属性与对象属性的对应关系,常用于对象属性与查询结果列名不相同的情况。

如何使用:

1.主键名使用id标签,column指定结果集中的列名,property指定类中的属性名。

2.其他列名使用result标签,column指定结果集中的列名,property指定类中的属性名。

3.id属性用于设置该结果集的名称

4.type属性用于指定需要匹配的类

5.select标签中resultMap属性设置为resultMap标签中的id值

List findAllUserdocument();
    
        
        
        
        
        
        
    

    
        select * from user where username like "%" #{username} "%"
    
@Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao userDao = sqlSession.getMapper(UserDao.class);
        List list = userDao.findUserLike1("z");
        for (User user : list) {
            System.out.println(user);
        }
        sqlSession.close();
    }

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5721617.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-18
下一篇 2022-12-18

发表评论

登录后才能评论

评论列表(0条)

保存