九点钟☆方向

记录成长点滴

欢迎来到我的个人博客~


Mybatis笔记(三) Mybatis基于代理DAO的CRUD

目录

引入依赖、实体类、建表、Mybatis主配置文件都和上篇示例一致,所需变化的只有DAO接口和映射配置文件。

保存用户

  1. 持久层接口中增加
/**
* 保存用户
* @param user
* @return 影响数据库记录的行数
*/
int saveUser(User user);
  1. 映射配置文件中增加
<!-- 保存用户-->
<insert id="saveUser" parameterType="com.mg.entity.User">
    insert into user(username,birthday,sex,address)
    values(#{username},#{birthday},#{sex},#{address})
</insert>

细节:

  • parameterType 属性: 代表参数的类型,因为我们要传入的是一个类的对象,所以类型就写类的全名称。

  • sql 语句中使用#{}字符: 它代表占位符, 相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。具体的数据是由#{}里面的内容决定的。

  • #{}中内容的写法: 由于我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。它用的是 ognl 表达式。

  • ognl 表达式: 它是 apache 提供的一种表达式语言, 全称是:Object Graphic Navigation Language 对象图导航语言。它是通过对象的取值方法来获取数据,在写法上把get省略。如:类中写法:user.getUserName() OGNL的写法为:user.userName

    #{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user. 而直接写 username。

保存用户时获取插入数据的ID

<insert id="saveUser" parameterType="com.mg.entity.User">
    <!-- 配置保存时获取插入的 id -->
    <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>

细节:

  • keyColumn:表的列名
  • keyProperty:实体类的属性名
  • order:什么时候执行。AFTER:插入语句执行之后执行 BEFORE:插入语句执行之前执行

更新用户

  1. 持久层接口中增加
/**
* 更新用户
* @param user
* @return 影响数据库记录的行数
*/
int updateUser(User user);
  1. 映射配置文件
<!-- 更新用户 -->
<update id="updateUser" parameterType="com.mg.entity.User">
    update user set username=#{username},birthday=#{birthday},sex=#{sex},
    address=#{address} where id=#{id}
</update>

删除用户

  1. 持久层接口中增加
/**
* 根据 id 删除用户
* @param userId
* @return
*/
int deleteUser(Integer userId);
  1. 映射配置文件
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
	delete from user where id = #{uid}
</delete>

细节:

  • parameterType取值也可以写 int Integer等,因为Mybatis作了别名
  • 当参数是基本类型及其包装类或者String并且只有一个参数时,SQL语句中#{}中的形参名称可以随便写。这里可以是userId,uid或者其他任何符合命名规范的写法

根据ID查询一个元素

  1. 持久层接口中增加

    /**
    * 根据 id 查询
    * @param userId
    * @return
    */
    User findById(Integer userId);
    
  2. 映射配置文件

    <!-- 根据 id 查询 -->
    <select id="findById" resultType="com.mg.entity.User" parameterType="int">
    	select * from user where id = #{uid}
    </select>
    

细节:

  • resultType 属性:用于指定结果集的类型。

模糊查询

  1. 持久层接口

    /**
    * 根据名称模糊查询
    * @param username
    * @return
    */
    List<User> findByName(String username);
    
  2. 映射配置文件

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

细节:

  • 对于返回类型是List等集合类型时,resultType的取值为List集合中元素的类型

  • 我们在配置文件中没有加入%来作为模糊查询的条件,所以在测试传入字符串实参时,就需要给定模糊查询的标识% 如: List users = userDao.findByName("%王%");

  • 此时控制台打印出来的SQL语句为:

    select * from user where username like ?

    配置文件中的#{username}也只是一个占位符,所以 SQL 语句显示为“?”

模糊查询的另一种配置方式 ${}

<!-- 根据名称模糊查询 -->
<select id="findByName" parameterType="string" resultType="com.mg.entity.User">
	select * from user where username like '%${value}%'
</select>

细节:

  • ${value}的写法就是固定的,不能写成其它名字 。因为源码中写死了

  • 程序代码中就不需要加入模糊查询的匹配符%了

    List users = userDao.findByName("王");

  • 控制台语句为:

    select * from user where username like ’%王%‘

#{}与${}的区别

    • #{}表示一个占位符号

    • 通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型转换
    • #{}可以有效防止 sql 注入。
    • #{}可以接收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值, #{}括号中可以是 value 或其它名称。
    • #{}会自动加上单引号
    • ${}表示拼接 sql 串
    • 通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,
    • ${}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值, ${}括号中只能是 value。
    • ${}不会自动加上单引号

使用聚合函数查询

  1. 持久层接口

    /**
    * 查询总记录条数
    * @return
    */
    int findTotal();
    
  2. 映射配置文件

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

注意:

以上的CRUD方法,增、删、改方法在测试时需要注意提交事务 sqlSession.commit() 查询方法则不需要

Mybatis 与 JDBC 编程的比较

  1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。 解决:在 SqlMapConfig.xml 中配置数据链接池,使用连接池管理数据库链接。
  2. Sql 语句写在代码中造成代码不易维护,实际应用 sql 变化的可能较大, sql 变动需要改变 java 代码。 解决:将 Sql 语句配置在 XXXXmapper.xml 文件中与 java 代码分离。
  3. 向 sql 语句传参数麻烦,因为 sql 语句的 where 条件不一定,可能多也可能少,占位符需要和参数对应。 解决:Mybatis 自动将 java 对象映射至 sql 语句,通过 statement 中的 parameterType 定义输入参数的类型。
  4. 对结果集解析麻烦, sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成 pojo 对 象解析比较方便。 解决:Mybatis 自动将 sql 执行结果映射至 java 对象,通过 statement 中的 resultType 定义输出结果的 类型

打赏一个呗

取消

感谢您的支持,我会继续努力的!

扫码支持
扫码支持
扫码打赏,你说多少就多少

打开支付宝扫一扫,即可进行扫码打赏哦