Mybatis实现数据库增删改查

MyBatis入门主要讲解了Mybatis的基本配置。在这些配置里面需要注意一下问题:

  • 持久层接口和持久层接口的映射配置文件必须在相同的包下。
    
  • 持久层接口配置文件中的mapper标签的namespace属性取值必须是持久层就看的全限定类名。
    
  • SQL语句的配置标签中的id属性值必须和持久层接口的方法名相同。例如上面的<select>标签中的id属性值findAll和UserDao接口中的方法名findAll相同。
    

接着MyBatis入门继续深入了解,在UserDao接口里面加入根据Id查询用户的方法

package com.liang.dao;

import com.liang.domain.User;

import java.util.List;

public interface UserDao{

    /**
     * 查询所有用户
     * @return
     */
    List<User> findAll();

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    User findById(int id);
    
}

同时需要在接口映射文件里面添加相应的SQL语句:根据Id查询用户

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.liang.dao.UserDao">
    <select id="findAll" resultType="com.liang.domain.User" >
        select *from user;
    </select>

    <!--根据id查询用户-->
    <select id="findById" resultType="com.liang.domain.User" parameterType="int">
        select *from user where id= #{userID};
    </select>
</mapper>

select标签中需要掌握的是其属性。

属性名属性值
resultType用于指定结果集的类型
parameterType用于指定传入参数的类型

**SQL语句中使用的#{}字符:**代表占位符,相当于使用jdbc的prepareStatement时候SQL语句传入的?,都是用于执行语句时候替换为实际的数据。
由于在MyBatis入门中通过main方法进行的测试的,这给后面的测试会带来很多不便,因此我做了在下面做了修改,使用了测试类进行测试,修改代码如下,并且加上了通过id查询用户的方法。


import com.liang.dao.UserDao;
import com.liang.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestMyBatis {

    private SqlSession sqlSession = null;
    private InputStream inputStream = null;
    private UserDao userDao = null;
    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }
    @After
    public void destroy() throws IOException {
        sqlSession.close();
        inputStream.close();
    }

    /**
     * 查询所有用户信息
     */
    @Test
    public void testFindAll(){
        List<User> users = userDao.findAll();
        for (User user : users)
        {
            System.out.println(user.toString());
        }
    }

    /**
     * 通过ID查询用户
     */
    @Test
    public void testFindById(){
        User user = userDao.findById(41);
        System.out.println(user.toString());
    }
}

实现保存用户信息
继续在持久层接口UserDao.java中添加保存方法。

  /**
     * 保存用户
     * @param user
     */
    void saveUser(User user);

相应的在其对应的接口映射文件中添加SQL语句。

   <!--注意此处传入的参数类型是我们自定义的参数类型
      相应的#{}占位符写入的内容,也应该是自定义类型的属性名。
      此处使用的都是apache提供的一种表达式语言 OGNL
      全称:Object Graphic Navigation Language(对象图导航语言)
    -->
    <insert id="saveUser" parameterType="com.liang.domain.User">
        insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex}, #{address});
    </insert>

在测试类中添加测试方法。

   @Test
    public void testSaveUser()
    {
        User user = new User();
        user.setUsername("娃哈啊");
        user.setSex("女");
        user.setBirthday(new Date());
        user.setAddress("陕西");
        userDao.saveUser(user);
        System.out.println("保存完毕");
    }

执行测试方法后,发现数据库里面并没有添加成功,这里和jdbc是相同的,在执行增删改的时候要控制事务的提交,在Mybatis中通过SqlSession对象的commit()方法来提交事务。可以将提交事务的方法加入到 userDao.saveUser(user);后面,也可以加入到 @After里面。

//在测试方法执行完成之后执行
 @After
    public void destroy() throws IOException {
        
        sqlSession.commit();
        
        sqlSession.close();
        inputStream.close();
    }

当添加提交方法后,在userDao.saveUser(user);后面打印用户信息发现此时id值为0,其实此处的id值是数据库自增长实现的,因此需要在新增用户后将自动增长的值进行获取。修改接口映射文件如下:

 <insert id="saveUser" parameterType="com.liang.domain.User">
        <!--配置保存时,获取插入的id
        keyColumn:  数据库表对应的字段
        keyProperty:  User对象的属性
        order: 执行顺序
        -->
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex}, #{address});
    </insert>

修改后在userDao.saveUser(user);后面打印用户信息发现id是我们需要的id.
添加更新用户和以上步骤没有任何区别。
在持久层添加更新方法:

   /**
     * 更新用户
     * @param user
     */
    void updateUser(User user);

在持久层对应的映射文件添加SQL语句:

 <!--更新用户-->
    <update id="updateUser" parameterType="com.liang.domain.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>

在测试类中添加测试方法:

  /**
     * 更新用户
     */
    @Test
    public void testUpdateUser()
    {
        User user = userDao.findById(70);
        user.setUsername("wahaha");
        userDao.updateUser(user);
        System.out.println(user);
    }

添加删除用户也是相同的三步。
在持久层添加删除方法:

    /**
     * 通过用户ID删除用户
     * @param userId
     */
    void deleteUser(int userId);

在相应的配置文件添加SQL语句:

  <!--通过用户id删除用户-->
    <delete id="deleteUser">
        delete from user where id= #{uid}
    </delete>

在测试类中添加测试方法:

   /**
     * 通过用户ID删除用户
     */
    @Test
    public void testDeleteUser()
    {
        userDao.deleteUser(70);
        System.out.println("删除成功");
    }

两种模糊查询的方式
两种方式和上面的一样,都需要三步完成。
方式一
在持久层接口中添加模糊查询的方法

  /**
     * 根据名称模糊查询
     * @param name
     * @return
     */
    List<User>findByName(String name);

在映射文件中添加SQL语句

 <!--根据名称模糊查询-->
    <select id="findByName" parameterType="String" resultType="com.liang.domain.User">
        select *from user where username like #{username}
    </select>

添加测试方法

  /**
     * 根据名称模糊查询用户
     */
    @Test
    public void testFindByName()
    {
        List<User> users = userDao.findByName("%小%");
        for (User user : users)
        {
            System.out.println(user);
        }
    }

方式二
在持久层接口中添加模糊查询的方法,这一步不做任何改变。
在映射文件中添加SQL语句

  <!--根据名称模糊查询 
    需要注意问题:
            1.将#{}占位符改为${value}
            2.${value是固定写法,不能该写成其他}-->
    <select id="findByName" parameterType="String" resultType="com.liang.domain.User">
        select *from user where username like '%${value}%'
    </select>

添加测试方法

   /**
     * 根据名称模糊查询用户
     */
    @Test
    public void testFindByName()
    {
        List<User> users = userDao.findByName("小");
        for (User user : users)
        {
            System.out.println(user);
        }
    }

以上两种方式虽然执行结果相同,但是是有区别的,区别主要体现在执行SQL语句时。
#{}表示一个占位符,相当于PreparedStatement,可以有效的防止SQL注入问题。而且#{}可以接收简单类型的值和 POJO 属性值。
表 示 拼 接 S Q L , 内 容 拼 接 不 能 有 效 防 止 S Q L 注 入 , {}表示拼接SQL,内容拼接不能有效防止SQL注入, SQLSQL{}也可以接收简单类型值和 POJO 属性值。如果parameterType传递耽搁简单型参数${}括号中只能是value。
聚合函数的使用
在持久层接口中添加查询总记录条数的方法

    /**
     * 查询总记录条数
     * @return
     */
    int findTotal();

在映射文件中添加SQL语句

 <!--查询总记录条数-->
    <select id="findTotal" resultType="int">
        select count(*) from user
    </select>

添加测试方法

   /**
     * 查询总记录条数
     */
    @Test
    public void testFindTotal()
    {
        int res = userDao.findTotal();
        System.out.println(res);
    }
MyBatis 是一种持久层框架,它可以简化 Java 开发人员与数据库之间的交互。MyBatis 提供了一种将 SQL 语句与 Java 代码分离的方法,使得代码更加易于维护和升级。下面,我将详细介绍 MyBatis 如何实现数据库增删改查操作。 首先,需要在项目中引入 MyBatis 的依赖。可以在 Maven 中添加以下依赖: ```xml <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> ``` 接下来,需要配置 MyBatis 的配置文件,这个配置文件包括了数据源、事务管理器、mapper 映射文件等信息。MyBatis 的配置文件通常命名为 `mybatis-config.xml`,示例配置如下: ```xml <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/test" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml" /> </mappers> </configuration> ``` 上述配置中,定义了数据源的信息,包括数据库驱动、URL、用户名和密码。同时,还定义了一个 `UserMapper.xml` 文件,该文件用于映射 SQL 语句。 然后,就可以创建一个 mapper 接口,使用注解或 XML 文件映射 SQL 语句,示例代码如下: ```java public interface UserMapper { @Select("SELECT * FROM user WHERE id = #{id}") User getUserById(int id); @Insert("INSERT INTO user(name, age) VALUES(#{name}, #{age})") @Options(useGeneratedKeys = true, keyProperty = "id") int addUser(User user); @Update("UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}") int updateUser(User user); @Delete("DELETE FROM user WHERE id = #{id}") int deleteUser(int id); } ``` 上述代码定义了一个 `UserMapper` 接口,其中使用了 `@Select`、`@Insert`、`@Update` 和 `@Delete` 四个注解,分别对应查询、插入、更新和删除操作。注解中的 SQL 语句可以直接写在注解中,也可以使用 XML 文件来映射 SQL 语句。 最后,在代码中使用 `SqlSessionFactory` 和 `SqlSession` 对象来执行 SQL 语句,示例代码如下: ```java SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); UserMapper userMapper = session.getMapper(UserMapper.class); User user = new User(); user.setName("张三"); user.setAge(25); userMapper.addUser(user); session.commit(); User user2 = userMapper.getUserById(user.getId()); System.out.println(user2); user.setName("李四"); user.setAge(30); userMapper.updateUser(user); session.commit(); userMapper.deleteUser(user.getId()); session.commit(); session.close(); ``` 上述代码中,首先创建了一个 `SqlSessionFactory` 对象,然后调用 `openSession()` 方法创建一个 `SqlSession` 对象。接着,通过 `session.getMapper(UserMapper.class)` 方法获取到一个 `UserMapper` 对象,然后就可以使用 `UserMapper` 接口中定义的方法执行 SQL 语句。 最后,需要调用 `session.commit()` 方法提交事务,并通过 `session.close()` 方法关闭 `SqlSession` 对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值