初步学习使用Mybatis框架

news2024/11/18 10:35:28

mybatis框架是一款半自动的ORM持久层框架,具有较高的SQL灵活性

所谓半自动的ORM持久层框架,是因为用mybatis进行开发,需要手动编写。而全自动的ORM框架,如hibernate,则不需要编写SQL语句。

对于mybatis,就是对于JDBC的封装,避免代码冗余。

1.要想使用mybatis,首先需要加载相应的mybatis类库,编写全局配置文件。

同样也是在pom.xml文件里面进行配置,将下列代码插入配置文件的相应位置。

        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.9</version>
        </dependency>

放置的具体位置,如下,注意不要放错位置!不要放错位置!不要放错位置!一定要放在

<dependencies></dependencies>里面,否则将无法安装相应的配置文件,具体放置位置我放在下面的图片里面了。

 然后可以点击右边的maven文件,然后右键单击maven项目,然后点击Reload project即可,或者直接ctrl + shift +o进行安装配置。

 

mybatis是对JDBC的封装,所以mysql相关类应该留着。至于为什么要留着,我们可以这样理解,我们对一栋大楼进行装修,大楼总得留着吧,不能因为装修,原始大楼拆了吧,拆了大楼我们还装修什么,同样的,mybatis是对JDBC进行封装,JDBC都没有了,我们还怎么进行封装啊,是同样的道理。

 mybatis框架主要是围绕着SqlSessionFactory进行的,SqlSessionFactory是MyBatis的关键对象,它是个单个数据库映射关系经过编译后的内存镜像。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象类获得,而SqlSessionFactoryBuilder则可以从XML配置文件或一个预先定制的Configuration的实例构建出SqlSessionFactory的实例。
SqlSession以及SqlSessionFactory的详细介绍可以看看下面这篇文章。

(265条消息) Mybatis组件之 SqlSessionFactory和SqlSession 对象详解_mybatis中sqlsessionfactory的作用_Tronhon的博客-CSDN博客

因此我们需要加载全局配置文件,生成SqlSessionFactory。

首先我们需要从 XML 中构建 SqlSessionFactory每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。 但也可以使用任意的输入流(InputStream)实例,比如用文件路径字符串或 file:// URL 构造的输入流。MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,使得从类路径或其它位置加载资源文件更加容易。

将以下代码复制到,自己在Test Sources Boots中创建一个的java class文件中。

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

我是新建了一个JAVA CLASS文件MyBatisTest文件,然后将复制的代码,放到main函数里面。

如果报红色错误,那是因为,没有导入包,可以将鼠标放置到红色单词处,然后Alt +Enter即可自动导入包。

导包完毕之后,就不会报红色错误了。

 然后我们可以注意到resource指向了一个配置文件的路径,说明我们需要一个配置文件,放置在对应的路径下。

 我们就在resource文件夹下面创建一个mybatis-config.xml配置文件,并且将

String resource对应的路径修改一下,直接“mybatis-config.xml”

 然后有一个异常需要跑出去,我们可以try catch一下,抛一下异常,然后就不报错了,finally可以先空着。

 然后将以下配置文件代码放到刚刚创建的mybatis-config.xml文件之下。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <environments default="development">
    <environment id="development">
      <transactionManager 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>
  </environments>
  <mappers>
    <mapper resource="org/mybatis/example/BlogMapper.xml"/>
  </mappers>
</configuration>

放置位置如下所示:

 然后mybatis-config.xml配置文件中有一些内容需要修改和JDBC代码对应一下。具体修改的地方如下,将你编写的JDBC java class文件对应替换mybatis-config.xml文件对应的url,password,driver,username。如下图所示:

 修改完了之后,翻到mybatis-config.xml配置文件末尾,可以看到末尾处有一个

<mapper resource="org/mybatis/example/BlogMapper.xml"/>

 和前面处理方式类似,我们先将main的resource文件下面,创建一个BlogMapper.xml文件,为了与前面的有所区分,我们在resource文件夹下面,创建一个文件夹mapper,然后BlogMapper.xml文件放到改文件夹中然后,再将<mapper resource="org/mybatis/example/BlogMapper.xml"/>

修改为<mapper resource="BlogMapper.xml"/>

如下图所示:

 然后我们将以下xml代码放到BlogMapper.xml中。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.mybatis.example.BlogMapper">
  <select id="selectBlog" resultType="Blog">
    select * from Blog where id = #{id}
  </select>
</mapper>

 可以将namespace写成“test”

如下图所示:

 我们想要查询用户的信息可以按照以下步凑操作,对代码进行修改:

先将BlogMapper.xml中的<select></select>修改成一下样式。

 配置文件完成到这里,就暂时没有他什么事儿了,后续还会对BlogMapper.xml进行相应修改,后续涉及到再说吧。

镜头给到MybatisTest java class文件修改这里。

创建一个SqlSession对象session,用来对数据库进行操作,创建语句如下:

SqlSession session = sqlSessionFactory.openSession();

SqlSession是mybatis持久层框架提供的接口,该接口中包含了大量的CRUD操作方法(既增删改查方法)。

然后调用session中的selectList()方法,selectList()方法是一种查询方法。

我们创建session对象之后,然后再调用一下session的selectLIst()方法,为查询做准备。

session.selectList("");//session中的selectList()是一种查询方法。

 然后回到mapper文件夹的配置文件BlogMapper.xml里面

为了通过MybatisTest java class文件调用BlogMapper.xml中预先写好的sql代码块,可以采用以下方式,进行。

 可以将mapper的namespace和select部分的id,以(namespace.select)的形式写到session.session("namespace.select")中,这样就相当于调用了代码块select * from user

 然后创建一个对象接收session.selectList()的返回结果。如果知道创建何种类型的对象,可以采用在session.selectList()后面加一个.var,就会自动创建接收对象。

 然后回车一下就创建完毕了,如下图所示:

 之前JDBCTest java文件中写的while循环一大段代码,就直接可以用这么一句代码代替,极大地减少了代码量。

 返回的结果可以映射成一个List对象

 我们可以在控制台中看一看List对象,不DEBUG,直接写一个for循环将LIst对象输出到控制台。

 最后我们的SqlSession等对象是需要关掉的,否则会占用资源。

 把这两句调整一下,拿到前面去,调整为下面这个样子,直接在外面就定义了,然后再try内部进行赋值,再finally部分用完关闭相应的对象,避免计算机资源浪费。

//sqlSessionFactory是重量级对象,一般不直接在线程里面进行销毁,

然后我们运行一下代码:

 结果报了一个错误,说找不到资源文件夹,说找不到资源文件夹BlogMapper.xml

 这是因为之前在mybatis-config.xml中配置BlogMapper.xml时候路径有问题,

由于BlogMapper.xml不是直接在resources文件夹里面,而是在resources文件下面的mapper文件夹里面,不能直接写BlogMapper.xml,而要改成mapper/BlogMapper.xml

 然后又报了一个错误:

突然发现workbench mysql没有启动,很有可能是这个原因

于是我去打开workbench,准备登陆数据库,但是发现端口被占用,这是因为,我之前装了一个sqlyog用的MySQL,于是每次开机,都得手动net stop MySQL数据库,然后再net start MySQL80数据库,然后workbench才能成功登录MySQL80数据库。

 然后就登录成功了。

 然后再重新执行代码:

 然后还是报错,于是呼叫了企业老师,帮我查看,老师一眼就看错了我的问题所在,由于一会儿写java代码,一会儿写xml代码,我把注释的格式写错了,java中注释用//,而xml注释应该用

下面就是错误的根源

 xml文件中正确的注释应该像这样,

<!--    查询用户信息,返回map集合体。-->

以后写注释可得记着点了,分清xml还是java,要是害怕出错,就用ctrl + /进行自己添加注释。、

以上错误修改完了之后,代码就能够顺利执行了。开心!!!!!

 单纯这样对比,好像代码量也没有简化,而且多了,还得配置pom.xml,BlogMapper.xml,mybatis-config.xml几个文件,但是待写方法较多的话,就会发现还是mybatis效果好。


我们将object类改写成map,然后手动实现打印出username。在这个过程中又学到了许多快捷键。

 map.get("key").sout-------然后回车会转换为System.out.println(map.get("username"))

打印出结果如下:

 然后如果想要利用快捷键快速编写出打印一下代码:

可以这样做,先打印出map,

然后map,get("username"),

然后map.get("username")后面加一个var。

然后回车就会出现代码:

Object username = map.get("username");

然后username后面加一个.soutv,然后回车就会出现以下代码:

System.out.println("username = " + username);

如果username后面添加一个.sout然后回车就会出现以下代码:

System.out.println(username);

 然后打印就会出现,以下结果的打印结果:

 但是map类有一个弊端,那就是不容易发现错误

例如下面username中间加一个1  user1name,界面不会反馈错误:

 那么有没有好的写法便于大家发现错误呢?答案是:当然是有的。

那就是写实体类entity,编写User实体类。

下面将介绍在main文件夹蓝色的java源文件夹环境中建立com.neuedu.entity用于装实体类的包。

具体文件摆放格式如下:

我们先编写出,实体类所含有的基本数据元素:

 然后右键单击generate,

 然后点击Getter and Setter,自动生成对于基本元素的get,set方法。

 然后回到,MybatisTest java class文件中,就可以用List<User>类型替换List<map>类型了,

比如说我们在我们写一句这样的:

List<User> usesr=null;

下面又要介绍一种写for循环的快捷键方式:

user加一个.for然后回车自动生成遍历users的for循环。

即user.for然后回车就会自动生成如下代码:

for (User user : users) {
    
}

想要获得user的名字就只能,写成user.getUsername();

写其他的就不对就会报错,这样便于我们即使发现编写错误,

不会出现前面的map.get("user1name")这种不提醒我们代码编写错误的情况,可能在编译时候才能够发现拼写错误。

比如我们写成user.getUsername1,编译时候就会遇到问题。

如下图所示:

 因此由此可知,我们最好不映射成map类型,而是映射成User类型,这样便于大家发现错误。

然后写了user之后,BlogMapper.xml对应位置的resultType类型也应该编写能够映射user对象的实体类型。

可以直接重新编写一个<select></select>

 <select id="selectUser2" resultType="com.neuedu.entity.User">
        select * from user
    </select>

然后想要调用该对象,调用mybatis的实体类,的对应session.selectList("")中的字符串也应该修改成,test.selectUser2

具体修改位置,如下图所示:

 想要再在MybatisTest java class文件中写一段代码实现不同的功能,但是一个类只能有一个main函数,这该怎么办呢?

那么下面介绍一个方法-------单元测试。

先学着用用看,原理就先不展开讨论。

同样地,点击到pom.xml文件界面。配置单元测试需要的junit,大致步凑和之前配置mysql,和配置Mybatis大致相同。

 <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.13.2</version>
            <scope>test</scope>
 </dependency>

添加以上依赖之后就可以进行单元测试了,<scope>test</scope>加了之后,同样crtl +shift+o,安装依赖完成之后就可以写注解了,就是@test,在写注解之前,每个java class文件中只有main函数部分可以执行,而写了注解之后,每个函数部分就都可以执行了。

 添加完junit依赖之后,然后MybatisTest java class文件中,非主函数前面添加@Test注解之后,也能点击执行单端代码,main函数只能写一个,但是public void test()方法可以写很多个,如下所示,都可以独立执行。

 那public void test1()和public void test2()中的session.selectList()中的参数就分别写test.selectUser1和test.selectUser2,分别测试一下之前BlogMapper.xml中写的两个resultType类型,分别是map和com.neuedu.entity.User。

 

 以下代码是打印对象

System.out.println(user);打印对象实际上就是调用的tostring()函数,我们可以在实体类利用generate自动生成一个tostring()函数。

 

 如果没有重写tostring()函数,那么打印的就是类名加哈希值

如下图所示:

 如果编写了tostring函数,那么打印的就是generate生成的tostring中的内容。

 编写了数据库中的updateBy数据信息,但是用toString方法打印出来时还是null,

原因是编写的实体类中的属性名和数据库中的列名不对应,导致查找时候找不到,所以是null

 把实体类user中的updateby改成update_by就可以查询到了:

 如果实体类中的updateBy和数据库中的update_By映射不上,有没有什么解决方法呢?

除了修改实体类之外还有没有什么其他方法呢?

答案是肯定有的。

要将实体类中的updateBy和mysql数据库中的update_By强行对应上,需要用一个结果集的映射,

首先需要进入BlogMapper.xml,在创建一个用于强行对应的selectUser3。

相对于之前selectUser1和selectUser2中的内容

<select id="selectUser2" resultType="com.neuedu.entity.User">

selectUser3中的内容有所不同,应为无法和com.neuedu.entity,User映射,映射不了,直接对应不上。

于是下面介绍一种中间方案

用resultMap=“BaseResultMap”替换resultType="com.neuedu.entity.User"

 再<select>最前面,书写以下代码:

<resultMap id="BaseResultMap" type="com.neuedu.entity.User">
    <result property="id" column="id"/>
    <result property="username" column="username"/>
    <result property="createtime" column="createtime"/>
    <result property="updateBy" column="update_by"/>
</resultMap>

 另外主键具有去重功能,最好采用<id property="id" column="id"/>写法,具有去重功能。

 我感觉这个结果映射,就是利用一个中转站resultMap=“BaseResultMap”,然后将实体类的property(属性)和数据库中的对应的列一一对应,一一映射,这样手动一一映射,即使实体类中的名字和数据库中相应列的名字对应不上,也能一一映射。

那我们同样的代码再来一个呗,看看这种方法能不能将实体类中的updateBy和数据库中的update_By映射成功。

于是我们再来一个test3

 我们执行一下test3

 从截图中我们可以看到updateBy列有了数值,说明映射成功。

前面我们已经在BlogMapper.xml文件中写了查询<select><select/>语块

接下来我们再在BlogMapper.xml文件写一下插入语块,同理可得,插入语句应该就用

<insert><>模块具体写法如下

<insert id="insert" parameterType="com.neuedu.entity.User">
</insert>

发然后将sql语句中的insert命令复制到两个insert之间。

具体复制mysql语句中的insert语句的方法:

 点击之后该数据表对应的插入语句就复制到了,剪切板,就可以复制粘贴到<select><select/>之间了。

如下图所示:

 将id删去,因为id是自增的

将sql语句改成下面这个格式:

 然后再MybatisTest java class文件,编写 注解

public void testInsert(){

        SqlSessionFactory sqlSessionFactory = null;
        SqlSession session = null;
        try{
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);


            session = sqlSessionFactory.openSession();

            User user = new User();
            user.setUsername("super");
            user.setPassword("123456");
            user.setCreatetime(new Date());
            user.setUpdateBy("abc");
            int count = session.update("test.insert", user);

            System.out.println("count = " + count);
            session.commit();
        }catch (Exception e){
            session.rollback();
            e.printStackTrace();
        }
        finally {
            session.close();
        }

    }

解 类型的test代码块。和前面的test一样。

插入操作所需要的对象时user,因此需要创建一个user对象,

 自增列,不需要设置数值:

即user.setId();是不需要的。

然后用以下代码调用提前准备好的sql语句完成插入:

int count = session.update("test.insert", user);
//count是受影响的代码的行数

以上代码都是写的死的,理论上来说,我们应该搞一个页面录入信息,而不应该

user.setUsername("super");
user.setPassword("123456");
user.setCreatetime(new Date());
user.setUpdateBy("abc");

不应该把数值写成死的。

还有就是调用session.date方法之后,需要提交事务,即session.commit();才能完成数据更新

 正常来说,我们事务执行完毕之后,就应该session.commit()提交事务。即使不写session.commit(),在session.close()中也会提交事务。如果出现异常,我们可以调用session.rollback()

如果出现异常,回滚操作能够,代码能够保持session.commit()操作执行之前(提交事务之前)的数据不变。

然后我们给testinsert()添加一个注解,然后进行执行操作。

 结果给我们报了以下错误:

  There is no getter for property named 'update_by' in 'class com.neuedu.entity.User'

原来又是user中的属性和<insert>封装块中的插入语句的没对应上的问题。

下面这个应该改成java的属性名字,因为我们要从java的user类中去取数据:

 将update_by修改成updateBy

如下

 然后再执行testinsert()代码语块就执行成功了!!!!

 然后我们打开workbench查看数据库,是不是成功插入:

 我们看到数据多了一行即我们插入哪一行,插入操作只影响了一行,因此返回的count=1。

因此我执行是没有问题的,老师执行之后,没有报错,但是数据库没有更新,是因为老师之前写代码块位置写错了,写到了test3()里面,而应该写在我们将要执行的testinsert模块里面,如下图所示:

 老师添加上这一句之后,数据库就自动更新了。

然后我还发现个细节,也印证了老师之前说的话,自增列,不用给他设置值,他会自动增加:

如下图所示:

 然后我们再在MybatisTest()java class文件中添加一个更新数据操作。

要更新数据,首先我们需要找到要更新的数据,那我们就先写一个查询单条结果:

我们先回到BlogMapper.xml文件里面添加相应的sql更新语块:

 以上是通过主键进行查找,

 

 还有记得将session的方法也换成session.selectOne

 查询不会修改数据库中的数据,就不用session.commit()了

然后我们执行一下,就查到了第一条数据:

 以上说明查询成功,那我们现在完成数据更新操作:

复制查询的java class注解块之后,

我们为了执行添加操作,加上了如下代码:

 count仍然是更新操作影响的行数:

下边我们看BlogMapper.xml中添加的更新sql语句块儿应该怎么写:

首先和之前写insert语句一样,我们进入workbench对应的待更新表格的位置,右键单击,然后将鼠标放在Copy to Clipboard 然后点击Update Statement,就将更新的sql语句复制到了粘贴板。 

 然后我们就可以将更新sql语句块复制到BlogMapper.xml中的对应位置了,

从workbench中复制的更新模块代码,如下,需要修改一下:

 修改之后是下面这个样子:

 因为id是自增列,就不用设置了直接删除了,然后还有就是update_by应该修改为updateBy,之前遇到过了,这里就不解释了。

然后我们就可以执行testUpdate(){}中的语句了

 以上代码是将第一行元素中的密码部分改变为999999,我们执行一下,会返回一个收到影响的行。

 从控制台我们可以看到应该是执行成功了,我们再检查看看数据库的第一行的数据的密码是不是变成了999999.

 我们可以看到数据库中的数据修改成功了。说明我们写的代码是没有问题的。注意由于更新数据,我们需要session.commit(),提交事件,对数据库进行更新。

然后我们,自己写一下删除语句,基本操作和之前一样,首先在workbench复制delete对应的sql语句到粘贴板上面,然后在BlogMapper.xml中封装对应的sql语句,然后再在之前updateUpdate()的基础上改改,写出testDelete()函数块,以下是按照主键值id进行删除。

 如果删除成功,第二行元素wangwu将不复存在

 下面我们执行一下代码:

返回一个count=1,看样子上是执行成功了,我们再检查一下数据库是不是成功

删除了第二行wangwu那一行的元素: 

刷新之后,wangwu那一行的元素不复存在了,说明mybatis删除编写是没有问题的。

开心!!!!

注意这里应该改成int类型,此处的类型对应的是待修改的id号码:

前面的更新操作写com.neuedu.entity.User是因为修改之后的User类对象user需要重新写回数据库,所以需要传入的参数类型是一个User实体类,所以BlogMapper.xml中对应的代码的parameterType应该写成com.neuedu.entity.User。

com.neuedu.entity.User,因为只需要传入id号就能确定对应行,由于通过确定行之后就直接删除。

由此我发现我写的代码的一部分是完全不需要的。delete查询都需要,直接输入id号就可以,直接进行删除。

因此方框里面的代码是多余的。之前更新数据需要select查询是因为,需要将数据库中对应行的对饮的User对象,读出来,然后进行修改,

然后再全部读回去,所以需要一下代码:

 单纯删除操作的话,只需要保留以下代码:parameterType 因为输入的id的类型int

 通过写MybatisTest方法我们发现很多代码都是重复的,例如以下方框中的代码:

 在实际的开发过程中实际上通常采用三层架构(后端代码的组织结构)的形式。

业务层:业务代码放置的位置,往往需要访问数据库

DAO(DATE ACCESS OBJECT)层:和JDBC(Java DataBase Connectivity)有关的代码全放在这儿,在该层会封装一些单表的增删改查操作。

控制层(Controller顶层):不负责具体业务,只负责调度,调度业务层

以下我们以封装用户这张表的DAO层进行举例,在src的main里面的蓝色java文件夹写封装方法

首先我们建一个新的包dao(date access object)。

 然后在dao下创建一个user实体对应的dao类UserDao

 以下就是UserDao java class文件中封装的主要部分:

 然后我们将MybatisTest中查集合,查单体,删除,修改等部分的代码复制到UserDao各个代码块中就可以了但是需要复制过去后需要做微小的调整。具体调整过程如下。

 其他模块的代码调方法,同理。

 但是写了这么多好像没有运用到封装思想啥的。

我们把各个类模块中的公共部分封装到一个静态类当中,可以设置一些静态变量,然后各个类就可以省略这些公共部分的代码了。公共部分的代码封装情况如下所示:

 然后,每个类中的这些部分就可以删除了:

 这样就简化了很多重复的代码:

 实际上,这是一个返回的类函数,是不需要输出的,即下面这部分还可以省略,

 省略之后就变成下面这个样子了,确实非常非常简短:

 然后我们需要测试一下,写成静态类类之后的代码是否正确,我们进行测试一下

以下我们进行单元测试:

首先把光标放置到UserDao.java的代码界面。

 右键单击,然后点击generate,然后点击test。即可生成在Test Source Boot文件夹下的绿色java文件夹下的测试代码:

 

然后勾选junit4,之前在pom.xml配置文件中配置过。

 即可在Test Sources Boot文件夹下面生成相应的测试文件夹UserDaoTest。

 然后我们就可编写相应的测试代码,然后测试看看之前封装的代码是否正确。

先编写带啊测试第一段代码是否正确吧。

 编写完后,直接执行,看看能不能返回相应的返回文件。

执行之后,我们可以看到成功打印出了相应的返回值,说明封装公共类代码操作正确。

 其实我们还可以发现,封装静态类之后的代码还有一大部分是重复的,比如返回集合,和返回个体的代码,两个类中就只有两个地方不同。

 那么问题来了,既然区别这么少,我们这个UserDao.java能不能不写了呢?

 我们可不可以用mybatis中的某个API(application process interface)直接帮我们生成一下呢?

答案是当然是都可以的。

那我就跟大家介绍一下,老师讲的方法,我的理解就是java的抽象思想,先不具体实现,写一个抽象类,然后具体需要的时候,再通过接口调用,进行具体实现。

一下是具体步凑,首先在src的main文件夹的蓝色java源文件的之前创建的dao文件夹下面创建一个UserMapper的java class文件。

 然后改写成接口类(不需要具体实现)然后接口类里面写上方法名:

 然后每一个接口里面又很多方法,我希望的是调用UserMapper这个接口会自动给我们生成一个代理对象,我们通过方法名去找到方法,那么找哪一个xml文件呢?这时候就需要创建一个对应的xml文件了

我们在src的main的resources的mapper文件里面创建一个UserMapper.xml文件。 

 然后我们将BlogMapper.xml里面的代码copy到UserMapper.xml,然后修改,添加部分代码:

第一个需要修改的就是namespace需要修改,我们希望的是UserMapper接口自动寻找UserMapper.xml文件,那么UserMapper.xml文件中的namespace就需要是UserMapper接口的权限类名(权限类名就是包名加上类名)。

我们复制UserMapper接口的权限类名(权限类名就是包名加上类名)放到

 

 点击之后就复制到粘贴板上面了,然后替换UserMapper.xml文件的<mapper namespace=>

位置的字符串。如下图所示:

 我们希望的是只写一个接口,其他的什么都不需要自己写了。

那么就需要UserMapper接口中的方法名,就是xml文件中的id对应的名字。也可以这么说,实际上xml文件中的id就是接口的文件中的方法名。

如下图所示:

 捋一捋吧,看看UserMapper接口文件和UserMapper.xml文件都有哪些文件是对应上的。

然后还有比较重要的一步要将新创建的UserMapper.xml文件的地址放在mybatis-config.xml配置文件中。

 

 如下图所示:

 为了区分一下,我们直接将之前的写的BlogMapper.xml文件注释了。

 然后下面就介绍一下应该怎么使用接口。我们试一试这样到底行不行。

一下和之前一样,在接口java文件中再生成一个测试代码:

 

 

 

 然后编写代码打印一下,代码编写是否正确,

 

 然后我们执行一下能否正常输出:

 可以看到通过接口调用代理对象,成功实现了集合查询操作

同样地我们可以编写个体查询操作。

本来我们正在写的测试是UserMapper,哈哈哈老师可能脑壳也混了,写成了测试UserDao,我就说老师怎么前后不连贯(把我整的一愣一愣的),一下双横虚线的部分可以跳过,直接继续测试UserMapper接口类。

=======================================================================

然后我们编写一下UserDaoTest.java函数中的测试selectById()测试方法

 执行一下:

 执行之前不要忘记把之前mybatis-config.xml文件中的

对<mapper resource="mapper/BlogMapper.xml"/>的注释解除掉,

不然无法执行,老师的就报错了

 

 

 因为实际上UserDao调用的的是

<mapper resource="mapper/BlogMapper.xml"/>

 ========================================================================

测试UserMapper接口的selectById方法。

 

执行一下:成功输出id号为1的那一行,看来代码书写没有错误。

 该句实际上是生成一个UseMapper代理接口的代理对象。

 为了进一步简化代码模块,即将引入Springboot框架结构。

将在下一篇文章中进行介绍,敬请期待!!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/695826.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

五、云尚办公-菜单管理

云尚办公系统&#xff1a;菜单管理 B站直达【为尚硅谷点赞】: https://www.bilibili.com/video/BV1Ya411S7aT 本博文以课程相关为主发布&#xff0c;并且融入了自己的一些看法以及对学习过程中遇见的问题给出相关的解决方法。一起学习一起进步&#xff01;&#xff01;&#x…

PLC选择指南:西门子还是三菱?

选择适合自己的PLC涉及多个因素&#xff0c;包括项目要求、技术要求、可用性、支持和个人偏好。西门子和三菱是两个知名的PLC制造商&#xff0c;它们都有自己的优势和特点。以下是一些考虑因素&#xff1a; 我这里刚好有plc、嵌入式、单片机的资料需要的可以私我或在评论区扣6…

tp使用layui友好显示修改状态功能

之前找了很多次,然后经过自己的总结,这里记录一下 html部分 <a href"{:url(admin/merchant/make_merchant_erweima,[id>$vo[id]])}" class"layui-btn layui-btn-normal layui-btn-sm ajax-change">二维码</a> 重点是添加上ajax-change的…

别再用查询count,判断数据是否存在了

目录 一、目前多数人的写法 二、优化方案 三、总结 大家在实际的开发过程中&#xff0c;会根据某些条件&#xff0c;从数据库表中查询出是否存在符合该条件的数据。无论是刚入行的程序员小白&#xff0c;还是久经沙场多年的程序员老白&#xff0c;都是一如既往的SELECT count(*…

Faster Segment Anything: Towards Lightweight SAM for Mobile Applications

Faster Segment Anything: Towards Lightweight SAM for Mobile Applications SAM代码&#xff1a;https://github.com/ChaoningZhang/MobileSAM SAM论文&#xff1a;https://arxiv.org/pdf/2306.14289.pdf 1 概述 Faster SAM的目标是通过用轻量级图像编码器取代笨重的图像编…

HTML点击显示、点击隐藏details 标签

<!DOCTYPE html> <html> <head> <meta charset"utf-8"> <title>菜鸟教程(runoob.com)</title> </head> <body><details> <summary>Copyright 1999-2011.</summary> <p> - by Refsnes Da…

通过阿里云函数计算FC实现音视频转码

1.进入阿里云函数计算FC页面 2.创建音视频转码应用 可以看到代码&#xff0c;看到相关的传参 3.进行测试 编辑测试参数&#xff0c;使用账号的OSS中的资源 点击测试函数进行测试 可以在OSS中看到生成的mp4格式的视频了 测试后发现函数计算可以使用 4. 接下来就是在项目中通过代…

力姆泰克小型电动推杆LAM

小型电动推杆 高强度工程塑料的蜗轮或者粉末冶金齿轮 向下翻动查看更多 力姆泰克小型电动推杆LAM 系列大量采用铝合金壳体&#xff0c;伸缩管等零部件&#xff0c;和部分高强度工程塑料的蜗轮或者粉末冶金齿轮&#xff0c;设计开发出专门应用在医疗&#xff0c; 办公家具&am…

Linux操作系统通过实战理解CPU上下文切换

前言&#xff1a;Linux是一个多任务的操作系统&#xff0c;可以支持远大于CPU数量的任务同时运行&#xff0c;但是我们都知道这其实是一个错觉&#xff0c;真正是系统在很短的时间内将CPU轮流分配给各个进程&#xff0c;给用户造成多任务同时运行的错觉。所以这就是有一个问题&…

Redis实战案例3-缓存概念和添加Redis缓存

1. 缓存 缓存是数据交换的缓冲区&#xff0c;是贮存数据的临时地方&#xff0c;一般读写性能较高&#xff1b; 其中数据库缓存&#xff0c;例如&#xff1a;索引数据&#xff0c;MySQL会给id创建索引&#xff0c;从而查询时可以在内存中快速检索&#xff0c;提升速度&#xff1…

MDK指定.sct(分散加载描述文件)文件位置

文章目录 MDK指定.sct(分散加载描述文件)文件位置概述END MDK指定.sct(分散加载描述文件)文件位置 概述 用STM32CubeMX生成的工程, 默认的.sct位置在临时输出目录, 里面都是.o. 都是工程编译时生成的临时文件(中间文件) 当工程归档时, 这个临时目录肯定是要删除的(编译过程…

用ThinkJs框架快速搭建博客网站

ThinkJS是一个企业级的NodeJS应用框架&#xff0c;整合了各种常用SDK以及企业级常用的技术方案&#xff0c;为减少了开发人员的学习成本&#xff0c;提高团队的开发效率而生。框架底层基于Koa2实现&#xff0c;并且结合ThinkPHP的思想&#xff0c;使代码更加简洁实用。 ThinkVu…

Dependency ‘io.spring.platform:platform-bom:Cario-SR7‘ not found

刚看到这个错的时候&#xff0c;以为是maven中需要配置aliyun镜像的缘故&#xff0c;所以&#xff0c;在/conf/settings.xml中加入了aliyun镜像&#xff1a; <mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http://maven.al…

智能优化算法六种常见图—参数空间图、搜索历史图、第一维度轨迹图、多样性曲线、平均适应度曲线、收敛曲线图(以黏菌算法为例)

一、基本介绍&#xff1a; 智能优化算法六种常见图绘制—参数空间图、搜索历史图、第一维度轨迹图、多样性曲线、平均适应度曲线、收敛曲线图。一篇文章有几张高颜值的图片&#xff0c;能给审稿人留下良好的第一印象。以上这些图像均可用于仿真实验中。各图像功能如下&#xf…

五个维度,解析 Spring 中 @Autowired 和 @Resource 的区别

Autowired注解是由Spring提供的&#xff0c;它可以用来对构造方法、成员变量及方法参数进行标注&#xff0c;它能够根据对象类型完成自动注入&#xff0c;代码如下&#xff1a; public class Service {// 构造方法注入Autowiredpublic Service(Service service) {this.service…

实现一个转盘随机选择器

实现效果 完整代码 <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, initial-scale1.0" /><title>Document</title><…

Java的Stream流详细讲解

一.Stream 是什么 Stream是Java 8新增的重要特性, 它提供函数式编程支持并允许以管道方式操作集合. 流操作会遍历数据源, 使用管道式操作处理数据后生成结果集合, 这个过程通常不会对数据源造成影响。 ​ 同时stream不是一种数据结构&#xff0c;它只是某种数据源的一个视图&…

Neo4j desktop在界面上使用dump备份还原

Neo4j数据库的版本在4.4版本中有dump &#xff08;Neo4j 3.5的版本没有dump文件&#xff09;&#xff0c;选中某个数据库可以使用dump导出一个.dump文件。 导出后的文件 导入dump文件&#xff0c;创建新的数据库

基于InteloneAPI的油锅爆燃预警系统

基于InteloneAPI的油锅爆燃预警系统 前言一、方案介绍1.系统概述2.设计思路 二、方案实现1.ResNet-18模型2.Intel OneAPI AI Kit 使用1.Intel Neural Compressor&#xff1a;2.Intel Optimization for PyTorch* 三、方案价值总结 前言 家居场景下&#xff0c;最容易起火的原因…

selenium自动化登录(实战解析)

目录 1.纯英文验证码 1.首先需要了解运行所需要的模块 2.获取我们的目标地址链接 3.进入古诗词首页面&#xff0c;找到验证码的标签&#xff0c;获取并且保存 4.调用超级鹰打码平台 5.调用超级鹰内的方法 6.输入账号密码 7.模拟登陆需要用cookie保持登陆状态 相信有很多…