Mybatis中的CRUD

Mybatis中CRUD

补充

在这里插入图片描述

1. 更新操作

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

上面我们可以看到id为4的那一行的age、bir都变为了空,有时候我们想让不存在值的保留原来的值,那怎么做呢,我们往下看

在这里插入图片描述

使用标签去掉多余的逗号

在这里插入图片描述

UserDAO.xml中需要添加的内容:

<!--更新方法-->
    <update id="update" parameterType="com.baizhi.eneity.User">
        update t_user
            <set>  <!--set标签动态去掉赋值语句前后多余的逗号-->
                <!--test里面书写的name为对象的属性名-->
                <!--name不为空并且name不等于空串-->
                <if test="name!=null and name!=''">
                    name=#{name},
                </if>
                <if test="age!=null">
                    age=#{age},
                </if>
                <if test="bir!=null">
                    bir=#{bir}
                </if>
            </set>
        where id=#{id}
        <!--
            update t_user set name='小李', where id=1
            逗号多余了
        -->
    </update>

在UserDAO接口中需要添加更新方法:

public interface UserDAO {
    // 保存用户
    int save(User user);
    // 更新方法
    int update(User user);
}

执行的更新操作的代码:

// 更新操作
    @Test
    public void update() throws IOException {
        // 读取配置文件
        InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
        // 创建sqlSessionFactory对象
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        // 获取sqlSession执行sql语句
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
            // 更新数据:
            // 更新:有值更新,不存在值保留原始的值   1.先查(拿)再改   2.动态sql
            User user = new User();
            user.setId(1);
            user.setName("小李");
            int count = userDAO.update(user);
            System.out.println("修改的条数:" + count);
            sqlSession.commit();    // 事务提交
        } catch (Exception e) {
            e.printStackTrace();
            sqlSession.rollback();  // 事务回滚
        } finally {
            sqlSession.close();
        }

    }

2. 删除操作

在UserDAO接口中需要添加删除方法:

public interface UserDAO {
    // 保存用户
    int save(User user);
    // 更新方法
    int update(User user);
    // 删除方法
    int delete(Integer id);
}

UserDAO.xml中需要添加的内容:

<!--删除方法-->
<!--全限定名应该是:java.lang.Integer,但是在java中lang包默认引入,所以直接写Integer就行-->
<delete id="delete" parameterType="Integer">
    delete from t_user where id=#{id}
</delete>

执行的删除操作的代码:

// 删除操作
@Test
public void delete() throws IOException {
    // 读取配置文件
    InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
    // 创建sqlSessionFactory对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
    // 获取sqlSession执行sql语句
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
        int delete = userDAO.delete(1);
        System.out.println("删除的条数:" + delete);
        sqlSession.commit();
    } catch (Exception e) {
        e.printStackTrace();
        sqlSession.rollback();
    } finally {
        sqlSession.close();
    }
}

在执行代码时前面有几行数据还有后面的释放资源每次都是一样的,存在冗余,我们可以这些行为封装为工具类

在这里插入图片描述

工具类中的代码:

public class MybatisUtil {

    private static SqlSessionFactory sqlSessionFactory;
    // SqlSessionFactory的实例很大,我们可以使用静态代码块简化
    // 静态代码块特点:类加载时候执行,只执行一次
    static {
        // 读取配置文件
        InputStream is = null;
        try {
            is = Resources.getResourceAsStream("mybatis-config.xml");
            // 创建sqlSessionFactory对象
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                is.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    // 提供sqlSession
    public static SqlSession getSqlSession() throws IOException {
        // 获取sqlSession执行sql语句
        return sqlSessionFactory.openSession();
    }
    // 关闭sqlSession
    public static void close(SqlSession sqlSession){
        sqlSession.close();
    }
}

3. 查询操作

查询所有

在UserDAO接口中需要添加查询所有方法:

public interface UserDAO {
    // 保存用户
    int save(User user);

    // 更新方法
    int update(User user);

    // 删除方法
    int delete(Integer id);

    // 查询所有方法
    List<User> queryAll();
}

UserDAO.xml中需要添加的内容:

!--
    查询所有
    resultType:返回结果,虽然queryAll()方法返回类型为List集合,
    但是resultType要写为List集合中封装的泛型类型的全限定名:com.baizhi.eneity.User
    resultType: List集合的泛型类型  com.baizhi.eneity.User
-->
<select id="queryAll" resultType="com.baizhi.eneity.User">
    select id, name, age, bir from t_user;
</select>

执行的查询所有操作的代码:

// 查询所有
@Test
public void testQueryAll() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    // queryAll()方法返回类型为List集合,mybatis会将数据库中的记录自动封装为User并存储到List集合中
    List<User> users = userDAO.queryAll();
    // 使用lambda表达式进行List集合的遍历
    users.forEach(user -> System.out.println(user));
    MybatisUtil.close(sqlSession);
}

查询结果:

在这里插入图片描述

关于标签的使用

	<!--
        查询所有
        resultType: List集合的泛型类型  com.baizhi.User
    -->
    <!--sql标签:用来实现sql语句复用 id:相当于给sql标签中内容定义一个唯一标识-->
    <sql id="userQuery">
        select id, name, age,bir from t_user
    </sql>
    <select id="queryAll" resultType="com.baizhi.eneity.User">
        <!--使用sql语句的复用的查询所有可以这样写-->
        <!--include:包含哪个片段 refid:包含片段的id-->
        <include refid="userQuery"/>
    </select>	

查询一个基于id查询

在UserDAO接口中需要添加查询一个(基于id)方法:

// 根据id查询一个用户
User queryById(Integer id);

UserDAO.xml中需要添加的内容:

<!--sql片段复用-->
<sql id="userQuery">
      select id, name, age,bir from t_user
</sql>
<!--查询一个基于id-->
<select id="queryById" parameterType="Integer" resultType="com.baizhi.eneity.User">
    <include refid="userQuery"/> where id=#{id}
</select>

执行的查询一个(基于id)的代码:

// 查询一个基于id查询
@Test
public void testQueryById() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    User user = userDAO.queryById(7);
    System.out.println(user);
    MybatisUtil.close(sqlSession);
}

查询结果:

在这里插入图片描述

模糊查询 where name like ‘%张%’

在UserDAO接口中需要添加一个模糊查询的方法:

// 模糊查询
List<User> queryLikeByName(String name);

UserDAO.xml中需要添加的内容:

<sql id="userQuery">
        select id, name, age,bir from t_user
</sql>
<!--根据名字模糊查询-->
<select id="queryLikeByName" parameterType="String" resultType="com.baizhi.eneity.User">
    <!--
        这样写是错误的
        <include refid="userQuery"/> where name like '%#{name}%'
        在mybatis中应该使用concat拼接。
        oracle: '%' || #{name} || '%'
        mysql:  concat('%', #{name}, '%')
    -->
        <include refid="userQuery"/> where name like concat('%', #{name}, '%')
</select>

执行的模糊查询的代码:

// 模糊查询
@Test
public void testQueryLike() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    List<User> users = userDAO.queryLikeByName("三");
    users.forEach(user -> System.out.println(user));
    MybatisUtil.close(sqlSession);
}

查询结果:

在这里插入图片描述

分页查询 select … from … limit 起始条数,每页显示的记录数

在UserDAO接口中需要添加一个分页查询的方法:

// 分页查询     // 参数1:起始位置     参数2:每页显示的记录数
// 为了在mybatis的层面上区分这两个参数,使用@Param注解给这两个参数起了别名
List<User> queryByPage(@Param("start") Integer start, @Param("rows") Integer rows);

UserDAO.xml中需要添加的内容:

<!--分页查询 多个参数不写parameterType-->
<select id="queryByPage" resultType="com.baizhi.eneity.User">
    <include refid="userQuery"/>
    limit #{start},#{rows}
</select>

执行的分页查询的代码:

// 分页查询
@Test
public void testQueryPage() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    // mysql默认起始条数是从0开始计数的
    //            起始位置:(当前页-1)*每页显示的记录数  该页显示的记录数
    List<User> users = userDAO.queryByPage(0, 2);
    users.forEach(user -> System.out.println(user));
    MybatisUtil.close(sqlSession);
}

结果:

在这里插入图片描述

查询总条数

在UserDAO接口中需要添加查询总条数的方法:

// 查询总条数
Long queryTotalCounts();

UserDAO.xml中需要添加的内容:

<!--查询总条数-->
<select id="queryTotalCounts" resultType="Long">
    select count(id) from t_user
</select>

执行的查询总条数的代码:

// 查询总条数
@Test
public void testQueryTotalCounts() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    Long counts = userDAO.queryTotalCounts();
    System.out.println("总记录数" + counts);
    MybatisUtil.close(sqlSession);
}

结果:

在这里插入图片描述

4. resultType 和 resultMap

总结:resultType、resultMap 都是用来对数据库中返回的结果进行封装的

  • resultType 只能封装简单类型的对象 简单类型对象:对象中没有对象类型的属性 —> 简单对象(八大、Date、String)
  • resultMap 可以封装复杂类型的对象(也可以封装简单的) 处理库表关联关系 --> 一对一、一对多、多对多关系时封装对象

自动封装 对象属性必须和数据库字段一致才会自动封装正确

// 查询所有方法
List<User> queryAll();
<!--
        查询所有
        resultType: List集合的泛型类型  com.baizhi.User
    -->
    <!--sql标签:用来实现sql语句复用 id:相当于给sql标签中内容定义一个唯一标识-->
    <sql id="userQuery">
        select id, name, age,bir from t_user
    </sql>

    <!--结果映射 id:resultMap标签起一个唯一标识 type:指定封装对象的类型-->
    <!--对象属性必须和数据库字段一致才会自动封装,否则就要自己写映射了-->
    <resultMap id="userResultMap" type="com.baizhi.eneity.User">

    </resultMap>
    <select id="queryAll" resultMap="userResultMap">
        <!--include:包含哪个片段 refid:包含片段的id-->
        <include refid="userQuery"/>
    </select>
// 查询所有
@Test
public void testQueryAll() throws IOException {
    SqlSession sqlSession = MybatisUtil.getSqlSession();
    UserDAO userDAO = sqlSession.getMapper(UserDAO.class);
    List<User> users = userDAO.queryAll();
    // 遍历
    users.forEach(user -> System.out.println(user));
    MybatisUtil.close(sqlSession);
}

结果:

在这里插入图片描述

对象属性和数据库字段不一致会封装错误

<!--
    查询所有
    resultType: List集合的泛型类型  com.baizhi.User
-->
<!--sql标签:用来实现sql语句复用 id:相当于给sql标签中内容定义一个唯一标识-->
<sql id="userQuery">
    select id, name as uname, age,bir from t_user
</sql>

<!--结果映射 id:resultMap标签起一个唯一标识 type:指定封装对象的类型-->
<!--对象属性必须和数据库字段一致才会自动封装,否则就要自己写映射了-->
<resultMap id="userResultMap" type="com.baizhi.eneity.User">

</resultMap>
<select id="queryAll" resultMap="userResultMap">
    <!--include:包含哪个片段 refid:包含片段的id-->
    <include refid="userQuery"/>
</select>

在这里插入图片描述

结果:

在这里插入图片描述

解决方法

使用id标签封装主键(如果是联合主键:从联合主键字段中选一列为主键,其余联合主键中的列当做普通列用result标签处理)

使用result标签封装普通列

UserDAO接口中的方法:

// 查询所有方法
List<User> queryAll();

UserDAO.xml中对应的内容:

<!--
    查询所有
    resultType: List集合的泛型类型  com.baizhi.User
-->
<!--sql标签:用来实现sql语句复用 id:相当于给sql标签中内容定义一个唯一标识-->
<sql id="userQuery">
    select id, name as uname, age,bir from t_user
</sql>

<!--结果映射 id:resultMap标签起一个唯一标识 type:指定封装对象的类型-->
<!--对象属性必须和数据库字段一致才会自动封装,否则就要自己写映射了-->
<resultMap id="userResultMap" type="com.baizhi.eneity.User">
    <!--主键封装:id标签-->
    <!--column:数据库中的列名 property:对象中对应的属性名字-->
    <id column="id" property="id"/>
    <!--普通列 result标签-->
    <result column="uname" property="name"/>
    <result column="age" property="age"/>
    <result column="bir" property="bir"/>
</resultMap>
<select id="queryAll" resultMap="userResultMap">
    <!--include:包含哪个片段 refid:包含片段的id-->
    <include refid="userQuery"/>
</select>

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值