SSM——3.Mybatis的增删改查

  • Post author:
  • Post category:其他



目录


1查询所有数据


2根据id进行查询


3.插入一条数据


4.获取插入数据的id


5.根据id进行删除


6.修改数据


7.小结


前面实践篇我们讲了如何从零创建一个Mybatis项目,然后原理篇我们浅讲了一下Mybatis的实现原理及流程,今天,我们来详细讲一下Mybatis的语法规则。

我们就安照原理篇写的书写顺序,然后根据实例,来讲解一下Mybatis的语法规则。

1查询所有数据

现在,我们要查询User表中的所有数据

我们在UserDao.xml文件中写下如下的sql语句:

<select id="findAll" resultType="com.qcby.entity.User">
        select * from user
   </select>

即如下图所示:

说明:

第5行 namespace :写的是我们Userdao的地址,与相应的接口类进行连接

第7行 select:是查询关键字,表示语句是用来查询的,其他的比如删除,用delete;修改,用update;添加,用insert

第7行 id:是唯一标识符,可以理解为方法名,要与对应的接口类中的方法名相同(可以与相应的测试方法名不同)

第7行 resultType:指返回值类型,这里我们查询出来的是一条条user数据,所以用user对象来接收

现在,我们在接口类中写下如下内容:

public List<User> findAll();

即如下图所示:

说明:因为查询返回的是一条条user内容,所以我们用List<User>来接收返回值

现在,我们来写测试类:

public class UserTest {

    private InputStream in = null;
    private SqlSession session = null;
    private UserDao mapper = null;

    @Before  //前置通知, 在方法执行之前执行
    public void init() throws IOException {
        //加载主配置文件,目的是为了构建SqlSessionFactory对象
        in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //创建SqlSessionFactory对象
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
        //通过SqlSessionFactory工厂对象创建SqlSesssion对象
        session = factory.openSession();
        //通过Session创建UserDao接口代理对象
        mapper = session.getMapper(UserDao.class);
    }

    @After  //@After: 后置通知, 在方法执行之后执行 。
    public void destory() throws IOException {
        //释放资源
        session.close();
        in.close();
    }

    /**
     * 测试查询所有的方法
     */
    @Test
    public void findAll() throws IOException {
        List<User> users = mapper.findAll();
        for (User user:users) {
            System.out.println(user.toString());
        }
    }
}

即如下图所示:

说明:

第19行:我们创建一个io对象in,并对in赋值null

第20行:创建一个sqlSession对象session,赋值null

第21行:创建接口代理对象,还是赋值null

第26行:利用io对象in,来加载sqlMapConfig.xml文件,使计算机可以读取mapper下的UserDao.xml文件

第28行:创建sqlSessionFactory对象,就是一个工厂,让工厂通过in来读取sqlMapConfig.xml文件

第30行:我们可以理解为打开工厂,并将其命名为session,也可以理解为第28行的factory是一个工厂模板,第30行是创建了一个实体化工厂对象,然后我们的一些操作是在这里进行的

第32行:通过session对象来创建UserDao接口代理对象。这里才是最关键的一步,因为这里出现了我们的代理对象(回想代理的基本思想)

第47行:创建User类型的列表users,通过代理对象来调用接口里面的findAll()方法

第48行:for循环,打印输出

第45行:@Test 表示这个一个测试方法,点击可以运行此方法

第23行:@Before 注解,表示下面的代码在Test之前运行

第35行:@After 注解,表示下面的代码在Test之后运行

第38行:关闭sqlSession工厂,释放资源

第39行:关闭io对象,释放资源

下面,我去配置一下sqlMapConfig.xml文件,如下图所示:

说明:

第20行:是对mapper下的xml文件的引用。

好了,现在让我们回到测试方法来点击测试一下:

当然,有点同学会出现这样的情况:

上面是几行红色的警告,不用担心,我的其他文章会教大家解决。

现在,我们的第一条sql语句就执行成功了。

2根据id进行查询

下面我们来书写根据id进行查询的sql语句

首先,在我们的UserDao.xml中写下如下语句:

<select id="findById" parameterType="java.lang.Integer" resultType="com.qcby.entity.User">
        select * from user where id = #{id}
    </select>

即如下图所示:

说明:

第11行 parameterType:指的是输入值的类型,可以理解为入参类型

第12行 id=#{id}:这里用的是#{},是用占位赋值的方式来拼接sql的,这是Mybatis参数注入的一种方式,后面会详细讲,暂时先记着这样用就行

下面,我们来写接口,如下图所示:

然后,我们来写测试方法:

 @Test
    public void findById(){
        User user=mapper.findById(3);
        System.out.println(user.toString());
    }

即如下图所示:

然后,点击测试运行:

3.插入一条数据

老规矩,先写UserDao.xml文件中的方法,代码如下:

<insert id="insertUser" parameterType="com.qcby.entity.User">
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

截图如下:

说明:

我们在写sql语句时,考虑的出参入参,是针对sql语句的,而不是针对接口中方法的。什么意思?以插入为例:插入数据,我们需要对数据赋值,这就是入参,但是插入的sql语句会返回什么?是一张表吗?不是;是一条数据吗?不是;是一个数子吗?不是;也就是说,当我们插入一条数据时,它是没有返回值的。所以,这里我们没有写出参,也就是resultType。但是换个角度想,我们执行这条插入语句时,会返回什么?Navicat会返回你插入的条数,也就是1。所以我们接口的返回参数类型就要定义为int型。

这里我们要区别:“我们查询 / 插入 / 删除 / 修改 一条语句时,需要什么?会返回什么?”根据这个,确定我们写sql语句时要定义的出参与入参。还有“当我们执行 查询 / 插入 / 删除 / 修改 语句时,会返回什么?”根据这个,可以在一些时候来确定我们写接口时定义返回参数的类型。这是比较绕的。我也是执行插入操作时才思考的。

下面,我们来看一下接口的书写(不给你们代码了,直接上图):

注意那个int,结合上面写的,思考一下。

下面看测试方法的书写:

@Test
    public void insert(){
        User user = new User();
        user.setUsername("哈哈1");
        int code = mapper.insertUser(user);
        session.commit();
        System.out.println(code);

    }

截图如下:

说明:

第65行:这里的session.commit()是做session提交的。我们在执行修改操作时(增,删,改,三种)需要进行数据的提交。记住就行,原理我也不太清楚。

最后,看一下结果:

为了弄清那个出参与入参的东西,让我们直接在Navicat上运行一下插入操作,看下结果:

关于这个出入参,和接口方法返回值的定义,我们需要好好思考一下

4.获取插入数据的id

一样,先写UserDao.xml文件里面的方法,代码如下:

<insert id="insertGetId" parameterType="com.qcby.entity.User">
        <selectKey keyProperty="id" resultType="int" order="AFTER">
            select LAST_INSERT_ID()
        </selectKey>
        insert into user (username,birthday,sex,address) values (#{username},#{birthday},#{sex},#{address})
    </insert>

写完后的截图如下:

说明:

第19行:和前面插入方法一样,不多讲

第20行:注意这里的关键字是“selectKey”,什么意思?查询关键字,表示这条语句就是查询关键字的;  “keyProperty”表示你的关键字是什么,我们当初在设计表的时候,是将id设为关键字的,所以后面写“id”;  “resultType”指的是返回值类型,前面讲过,不多说;  “order”指的是顺序,即这条语句执行的顺序是什么,我们这里是在插入数据之后获取它的id的,所以这条语句的顺序是在插入语句之后执行。

第21行:算是一种固定写法吧,记住就行

第23行,插入语句,没啥好说的

然后,我们来写接口(不给代码,直接给图):

然后,我们来看一下测试方法(代码如下):

 @Test
    public void insertGetId(){
        User user = new User();
        user.setUsername("哈哈3");
        int code = mapper.insertGetId(user);
        //数据的修改,需要做session数据的提交
        session.commit();
        System.out.println(code); //code = 1
        //获取id
        System.out.println(user.getId());
    }

截图如下:

然后,我们来看一下运行结果:

这里我们可以看到2个值,一个是code的值,为1,也是方法的返回值;第二个是插入数据的id,为32,是通过get方法得到的。

5.根据id进行删除

一样,我们先写UserDao.xml文件,代码如下:

<delete id="deleteById" parameterType="java.lang.Integer">
        delete from user where id = #{id}
    </delete>

截图如下:

其实出入参和上面的插入操作基本一致

下面来写接口,如图:

最后写测试文档,代码如下:

 @Test
    public void deleteById(){
        int code = mapper.deleteById(32);
        session.commit();
        System.out.println(code);
    }

截图如下:

然后,我们执行一下,看下运行结果:

这就没什么好说的了

6.修改数据

首先,我们来写UserDao.xml文件,代码如下:

<update id="update" parameterType="com.qcby.entity.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
        where id= #{id}
    </update>

截图如下:


然后,我们来写接口,截图如下:

然后,我们来写测试方法:

最后,我们来看一下结果:

一些理解:

我们能够发现,我们的插入与修改操作都是new了一个新对象,然后用新对象覆盖旧对象。插入就不多说什么了,这里说一下修改操作。我们在Navicat上执行修改操作时,感觉只是赋值就行,没什么特别的,而到这里,却要new新对象,我个人觉得这应该与实体类的包装有关。

7.小结

这里小结一下我们在增删改查中所用到的关键字

namespace:连接我们的对应的接口

id:唯一标识符,可以理解为方法名,要与接口中的方法名相同

resultType:返回值类型,确定时要根据sql语句考虑,而不是接口中的方法考虑

parameterType:可以理解为入参类型,即传给sql在值,也是根据sql来进行确定

selectKey:查询关键字,结合上面的例子进行分析

keyProperty:后面接关键字,与表有关

order:执行顺序,即在后面语句之前执行还是之后执行

#{}:这是用占位赋值的方式来拼接sql的,是Mybatis参数注入的一种方式。另外一种我们后面会讲并且会比较二者的不同。

到这里,我们的增删改查操作全部完成,当然,肯定不全,但是大体不差多少,后面的具体问题就具体分析了。

文中所写的一些个人理解如果有失偏颇,还请各位大佬指出!



版权声明:本文为m0_52096593原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。