【Mybatis】基于Mybatis完成基本的增删改查操作

本文详细介绍了如何使用Mybatis完成基本的数据库操作:增删改查。通过实例展示了如何传递参数,包括基本数据类型和引用数据类型,并解释了如何处理主键自增和回显,以及在多参数情况下如何绑定参数。同时,文章涵盖了insert、update、delete操作的实现细节。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 大家好呀,我是书架。

【Mybatis】快速搭建01介绍了MyBatis框架如何在Dao层接口、映射文件(写SQL语句的Mapper.xml文件)、配置文件SqlMapConfig.xml组合下完成了对数据库的查询操作。

本次内容依然是在快速搭建01开发基础上更加全面的通过示例介绍基本的增删改查操作。

查询操作-select

我们在查询数据库时,通常会传入参数以筛寻符合条件的数据。那么SQL语句是如何接收传入的参数呢?

示例1-传入基本数据类型作为参数

Dao层接口UserMapper增加findById方法

public User findById(int id);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容


 <!--1.根据传入的参数类型为基本数据类型-->
 <select id="findById" parameterType="int" resultType="com.zssj.domain.User">
     select * from user where id = #{id}
 </select>

示例2-传入引用数据类型作为参数

Dao层接口UserMapper增加findByIdTest方法

public User findByIdTest(User user);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

 <!--2.传入的参数类型为引用数据类型-->
<select id="findByIdTest" parameterType="com.zssj.domain.User" resultType="com.zssj.domain.User">
    select * from user where id = #{id}
</select>

通过示例1和示例2发现Dao层接口中方法的参数类型和UserMapper.xml中select标签parameterType参数的类型一致,它们是一一对应的。

两个示例语句中的select标签传入参数类型不一样,一个是基本数据类型int,一个是引用数据类型User。

因此select * from user where id = #{id}中的id值,示例一来自于Dao层直接传入的参数,示例二来自user对象中的id值。

而两个示例的查询结果都以resultType="com.zssj.domain.User"形式进行封装。

插入操作-insert

示例3-User对象进行插入

Dao层接口UserMapper增加insert方法

int insert(User user);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

<insert id="insert" >
    insert into user(id, username,password)  values(#{id}, #{username}, #{password})
 </insert>

测试类中的测试代码

    @Test
    public void test2() throws IOException {
        //1. 读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = factory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象
        User user = new User();
        user.setId(7);
        user.setUsername("guanyu");
        user.setPassword("hello123");
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.insert(user);
        //新增数据需要提交事务
        session.commit();
        //6. 释放资源
        session.close();
        in.close();
    }

在测试方法中,我们手动生成了一个User对象,并且调用Dao接口中的insert方法,完成数据的插入。

目光聚集到Dao接口中的insert方法,发现它的返回值类型是int类型,这代表插入数据库的总条数,我们此次只插入了一条数据,因此返回值是1。

UserMapper.xml中的insert标签里将数据库的所有字段都列出来,并且用#{属性值}的方式进行一一对应,属性值来自Dao层接口传入的User对象的属性值。

上述示例代码展示了运用Mybatis插入简单的数据,可以发现在测试方法中主键id是我们手动赋值,但是在实际生产中,主键id值会被设置为自动增长,不需要自己赋值。

那么在我们插入数据后,如果还想得到数据库中为这条记录生成的id值该怎么办呢?

Mybatis框架也为我们提供了方法。

示例4-MySQL数据库完成id值回显

Dao层接口UserMapper增加insert2方法

 int insert2(User user);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

<insert id="insert2" useGeneratedKeys="true" keyProperty="id">
    insert into user(id, username,password)  values(#{id}, #{username}, #{password})
 </insert>

测试类中的方法

    @Test
    public void test5() throws IOException {
        //1. 读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = factory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象
        User user = new User();
        user.setUsername("liubei");
        user.setPassword("hello123");
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.insert2(user);
        System.out.println(user.getId());
        //新增数据需要提交事务
        session.commit();
        //6. 释放资源
        session.close();
        in.close();
    }

在测试方法中创建实体对象user时,我们并没有主动给id赋值,在实行插入语句insert2后,测试user.getId()方法,获取到了这条记录的id值。

而实现这一功能,主要是在UserMapper.xml中中相应的select标签中,加入了两个参数,第一个是useGeneratedKeys="true" ,第二个是keyProperty="id"。

这两个参数的意思是Mybatis会将数据库获得的id自增值赋值给实体对象的id。

但是这个方法只适用如MySql、SqlServer这样支持主键自增的数据库。而像Oracle数据库不提供主键自增功能,而是使用序列得到一个值,然后将这个值赋值给id,再将数据插入数据库。

对于这种情况,可以通过<selectKey>标签来获取主键的值代码示例如下。

示例5-Oracle数据库完成id回显

Dao层接口UserMapper增加insert3方法

int insert3(User user);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

 <insert id="insert3" >
      <selectKey keyColumn="id" resultType="int" keyProperty="id" order="BEFORE">
          select seq_id.nextval from dual
      </selectKey>
      insert into user(id, username,password)  values(#{id}, #{username}, #{password})
 </insert>

我们发现Dao层接口的方法不变,变的是在UserMapper.xml中insert标签中加入了子标签<selectKey>。

Oracle会将从序列seq_id中得到的值通过keyColumn赋值给数据库的id字段,并且通过keyProperty回显给实体对象的id。

更新操作-update

Dao层接口UserMapper增加updateById方法

int updateById(User user);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

 <!--修改操作-->
<update id="updateById" parameterType="com.zssj.domain.User">
    update user set username = #{username}, password = #{password} where id = #{id}
</update>

测试类中的方法

    @Test
    public void test3() throws IOException {
        //1. 读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = factory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象
        User user = new User();
        user.setId(6);
        user.setUsername("zhugeliang");
        user.setPassword("hello123");
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.updateById(user);
        //新增数据需要提交事务
        session.commit();
        //6. 释放资源
        session.close();
        in.close();
    }

在测试方法中我们生成了user对象其id为6,因此传入到UserMapper.xml中的updateById方法就会根据此id修改该记录。

删除操作-delete

Dao层接口UserMapper增加deleteById方法

int deleteById(int id);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

<!--删除操作-->
<delete id="deleteById" parameterType="int">
     delete from user where id = #{id}
</delete>

测试类中的方法

    @Test
    public void test5() throws IOException {
        //1. 读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = factory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象
        UserMapper userMapper = session.getMapper(UserMapper.class);
        userMapper.deleteById(1);
        //需要提交事务
        session.commit();
        //6. 释放资源
        session.close();
        in.close();
    }

多参数参与SQL语句

不知道大家有没有发现在上述的示例中,Dao层接口的参数要么是基本数据类型要么是实体对象,但是参数只有一个,那如果我要传入多个参数怎么办呢?

通过一个例子来说明一下,要求查出id为1,username为zhangsan的密码信息。

Dao层接口UserMapper增加findByParam方法

public User findByParam( int id,  String username);

映射文件UserMapper.xml中增加与Dao层接口匹配的如下内容

<select id="findByParam" resultType="com.zssj.domain.User">
    select * from user where id = #{id} and username = #{username}
</select>

测试类中的方法

    @Test
    public void test6() throws IOException {
        //1. 读取核心配置文件SqlMapConfig.xml
        InputStream in = Resources.getResourceAsStream("SqlMapConfig.xml");
        //2. 创建SqlSessionFactory工厂
        SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
        SqlSessionFactory factory = builder.build(in);
        //3. 使用工厂生产一个SqlSession对象
        SqlSession session = factory.openSession();
        //4. 使用SqlSession创建Dao接口的代理对象

        UserMapper userMapper = session.getMapper(UserMapper.class);
        User user = userMapper.findByParam(1, "zhangsan");
        System.out.println(user);
        //新增数据需要提交事务
        session.commit();
        //6. 释放资源
        session.close();
        in.close();
    }

在Dao层接口方法findByParam中,其参数为两个。运行上述测试代码会发现报错

org.apache.ibatis.exceptions.PersistenceException: 
### Error querying database. 
    Cause: org.apache.ibatis.binding.BindingException: Parameter 'id' not found. 
    Available parameters are [arg1, arg0, param1, param2]

报错显示id值没找到,说明Dao层把值传给UserMapper.xml的对应的select标签时出现问题,这时候需要借用注解@param来绑定参数。

因此将Dao层中的方法改为

public User findByParam( @Param("id") int id,  @Param("username") String username);

注解@Param("id") 的意思是把此id值绑定给占位符#{id},@Param("username")是把username绑定给占位符#{username}。

这样在多参数传入时就能实现一一对应,再次调用测试方法测试通过。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值