使用要求:
1、持久层接口和持久层接口的映射配置必须在相同的包下
2、持久层映射配置中 mapper 标签的 namespace 属性取值必须是持久层接口的全限定类名
3、SQL 语句的配置标签<select>,<insert>,<delete>,<update>的 id 属性必须和持久层接口的
方法名相同。

一、根据 ID 查询

在mybatis01工程中继续操作

1.在持久层接口中添加 findById 方法

/**
* 根据 id 查询
* @param userId
* @return
*/
User findById(Integer userId);

2.在用户的映射配置文件中配置

<!-- 根据 id 查询 --><select id="findById" resultType="cn.oesoft.mybatis01.domain.User" parameterType="int">select *from userwhere id = #{uid}</select>
细节:
resultType 属性:
用于指定结果集的类型。
parameterType 属性
用于指定传入参数的类型。
sql 语句中使用#{}字符:
它代表占位符,相当于原来 jdbc 部分所学的?,都是用于执行语句时替换实际的数据。
具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:
由于数据类型是基本类型,所以此处可以随意写。

3.在测试类添加测试

public class MybastisCRUDTest {private InputStream in;private SqlSessionFactory factory;private SqlSession session;private IUserDao userDao;@Testpublic void testFindOne() {
//6.执行操作User user = userDao.findById(41);System.out.println(user);}@Before//在测试方法执行之前执行public void init() throws Exception {
//1.读取配置文件in = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建构建者对象SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//3.创建 SqlSession 工厂对象factory = builder.build(in);
//4.创建 SqlSession 对象session = factory.openSession();
//5.创建 Dao 的代理对象userDao = session.getMapper(IUserDao.class);}
}

二、保存操作

1.在持久层接口中添加新增方法

/**
* 保存用户
* @param user
* @return 影响数据库记录的行数
*/
int saveUser(User user);

2.在用户的映射配置文件中配置

<!-- 保存用户--><insert id="saveUser" parameterType="cn.oesoft.mybatis01.domain.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 对象图导航语言
它是按照一定的语法格式来获取数据的。
语法格式就是使用 #{对象.对象}的方式
#{user.username}它会先去找 user 对象,然后在 user 对象中找到 username 属性,并调用
getUsername()方法把值取出来。但是我们在 parameterType 属性上指定了实体类名称,所以可以省略 user.
而直接写 username。

3.添加测试类中的测试方法

@Testpublic void testSave(){User user = new User();user.setUsername("modify User property");user.setAddress("北京市顺义区");user.setSex("男");user.setBirthday(new Date(System.currentTimeMillis()));System.out.println("保存操作之前:"+user);
//5.执行保存方法userDao.saveUser(user);System.out.println("保存操作之后:"+user);}
打开 Mysql 数据库发现并没有添加任何记录,原因是什么?
这一点和 jdbc 是一样的,我们在实现增删改时一定要去控制事务的提交,那么在 mybatis 中如何控制事务
提交呢?
可以使用:session.commit();来实现事务提交。加入事务提交后的代码如下:
@After//在测试方法执行完成之后执行
public void destroy() throws Exception{
session.commit();
//7.释放资源
session.close();
in.close();
}

4.问题扩展:新增用户 id 的返回值

新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相
当于我们要在新增后将自动增长 auto_increment 的值返回。
<!-- 保存用户--><insert id="saveUser" parameterType="cn.oesoft.mybatis01.domain.User"><!-- 配置保存时获取插入的 id --><selectKey keyColumn="id" keyProperty="id" resultType="int">select last_insert_id();</selectKey>insert into user(username, birthday, sex, address)values (#{username}, #{birthday}, #{sex}, #{address})</insert>

三、用户更新

1.在持久层接口中添加更新方法

/**
* 更新用户
* @param user
* @return 影响数据库记录的行数
*/
int updateUser(User user);

2.在用户的映射配置文件中配置

<!-- 更新用户 --><update id="updateUser" parameterType="cn.oesoft.mybatis01.domain.User">update userset username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}where id = #{id}</update>

3.加入更新的测试方法

@Testpublic void testUpdateUser()throws Exception{
//1.根据 id 查询User user = userDao.findById(50);
//2.更新操作user.setAddress("北京市顺义区");int res = userDao.updateUser(user);System.out.println(res);}

四、用户删除

/*** 根据 id 删除用户* @param userId* @return*/int deleteUser(Integer userId);
<!-- 删除用户 --><delete id="deleteUser" parameterType="java.lang.Integer">deletefrom userwhere id = #{uid}</delete>
 @Testpublic void testDeleteUser() throws Exception {
//6.执行操作int res = userDao.deleteUser(50);System.out.println(res);}

五、用户模糊查询

1.第一种

/**
* 根据名称模糊查询
* @param username
* @return
*/
List<User> findByName(String username);
<!-- 根据名称模糊查询 --><select id="findByName" resultType="cn.oesoft.mybatis01.domain.User" parameterType="String">select *from userwhere username like #{username}</select>
@Testpublic void testFindByName(){//5.执行查询一个方法List<User> users = userDao.findByName("%王%");for(User user : users){System.out.println(user);}}
在控制台输出的执行 SQL 语句如下:
我们在配置文件中没有加入%来作为模糊查询的条件,所以在传入字符串实参时,就需要给定模糊查询的标
识%。配置文件中的#{username}也只是一个占位符,所以 SQL 语句显示为“?”。

2.模糊查询的另一种配置方式

<!-- 根据名称模糊查询 --><select id="findByName" resultType="cn.oesoft.mybatis01.domain.User" parameterType="String">select *from userwhere username like '%${value}%'</select>
我们在上面将原来的#{}占位符,改成了${value}。如果 parameterType 传输单个简单类型值,${}括号中只能是 value。
修改测试方法,把参数中的%去掉
@Testpublic void testFindByName(){//5.执行查询一个方法List<User> users = userDao.findByName("王");for(User user : users){System.out.println(user);}}

在控制台输出的执行 SQL 语句如下:

上面的是这样

可以发现,我们在程序代码中就不需要加入模糊查询的匹配符%了,这两种方式的实现效果是一样的,但执行
的语句是不一样的。

3.#{}${}的区别

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

4.模糊查询的${value}源码分析

我们一起来看 TextSqlNode 类的源码:

黑马的解释有问题:这就说明了源码中指定了读取的 key的名字就是”value”,所以我们在绑定参数时就只能叫 value 的名字
了。

六、查询使用聚合函数

/**
* 查询总记录条数
* @return
*/
int findTotal();
<!-- 查询总记录条数 --><select id="findTotal" resultType="int">select count(*)from user;</select>
@Test
public void testFindTotal() throws Exception {
//6.执行操作
int res = userDao.findTotal();
System.out.println(res);
}

七、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 定义输出结果的
类型。

3- 基于代理 Dao 实现 CRUD 操作相关推荐

  1. Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录

    Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录 Android Studio开发(四)SQLite数据库的DAO标准CRUD操作模拟微信通讯录 一.任务 ...

  2. Mybatis框架实现CRUD操作

    Mybatis框架实现CRUD操作 自定义mybatis流程 mybatis基于代理dao的CRUD操作(重点) E:\JAVAworkspace\mybatis_CRUD CRUD中可能遇到的问题: ...

  3. 基于OCILIB的oracle数据库操作总结及自动生成Model和Dao的工具

    基于OCILIB的oracle数据库操作总结 1.       类图 2.       基类BaseOCIDao的设计与实现 BaseOCIDao.h头文件 #pragma once/* ------ ...

  4. 设计一个事务增强的动态代理类, 对持久层的用户的CRUD操作进行事务增强 即:

    动态代理类: package com.bj169.invoke;import com.bj169.dao.UserDao; import com.bj169.util.HibernateUtil; i ...

  5. java中利用框架传入相同的url实现crud操作_Java SSM框架基础面试题

    1.Spring 在ssm中起什么作用? Spring:轻量级框架 作用:Bean工厂,用来管理Bean的生命周期和框架集成. 两大核心: 1.IOC/DI(控制反转/依赖注入) :把dao依赖注入到 ...

  6. MyBatis 3(2)实体映射 CRUD 操作(XML/注解方式)

    MyBatis 实体映射 Mybatis 配置数据映射主要有 2 种方式,通过 XML 配置文件进行,通过注解进行: Mybatis 对于实体映射是通过接口调用的方式,在底层上使用 Java 的动态代 ...

  7. mybatis 一对多_Springboot整合Mybatis实现级联一对多CRUD操作

    在关系型数据库中,随处可见表之间的连接,对级联的表进行增删改查也是程序员必备的基础技能.关于Spring Boot整合Mybatis在之前已经详细写过,不熟悉的可以回顾Spring Boot整合Myb ...

  8. mybatis mysql crud_Mybatis实现CRUD操作

    Mybatis实现CRUD操作 导入相关依赖 创建实体类User 创建Mybatis主配置文件:SqlMapConfig.xml 创建IUserDao接口. 创建于接口对应的映射配置文件:IUserD ...

  9. Mybatis中使用Dao实现类实现增删改查【实际开发中使用代理dao】

    在Mybatis开发中,使用到的是代理Dao的方式实现增删改查,这样就不需要在写Dao的实现类 但是Mybatis也支持写Dao实现类!即DaoImpl 直接上DaoImpl,之前的代码可以参考前面几 ...

最新文章

  1. 有关Spring 3.0的发布
  2. 假期不能错过的音视频领域技术进展
  3. android和ios系统的内存,WP和Saipan系统的流畅程度相当于ios,占用的内存很少,但是为什么要用Android取代它...
  4. Python3基础12(collections、struct、itertools、chardet等的使用)
  5. 汇编环境的搭建(windows 10 + debug)
  6. 批量删除.svn文件的方法
  7. HDU1846 Brave Game
  8. js控制页面只刷新一次
  9. python为什么是蛇的天敌_青蛙和蛇一直是天敌,只知道蛇会吃青蛙,你知不知道青蛙也吃蛇...
  10. MFC界面编程基础(01):Windows 编程模型
  11. 量子力学(4) 全同粒子
  12. 手机共享电脑网络上网
  13. 全球及中国数字温度传感器行业商业模式分析及投资风险预测2022年版
  14. 【NFS服务】Linux/Ubuntu 搭建NFS服务器
  15. 非抢占模式下故障后优先级降低却不切换问题--使用Keepalived实现非抢占模式主备切换
  16. [软件发布]WAP网站在线浏览器 WapReader
  17. 2016word排版小技巧
  18. 物联卡到底能不能长期使用,跟着搜卡之家一块来看下吧
  19. 《高级无线网络—4G技术》——第2章  物理层和多址接入2.1 高级时分多址——ATDMA...
  20. 文本分类中的文本特征表示

热门文章

  1. c++ 标准异常类层次结构_Java入门教程十一(异常处理)
  2. 【Elasticsearch】Elasticsearch中数据是如何存储的
  3. 【Java】JSR 内存屏障
  4. 【elasticsearch】es直接put一个数据到es Can‘t merge because of conflicts Cannot update enabled setting _source
  5. 【Java】Java StreamCorruptedException: invalid stream header: EFBFBDEF
  6. Kudu : kudu 主键相关
  7. 计算机二级vb资料百度云,全国计算机等级考试二级VB复习资料.pdf
  8. 【设计模式:单例模式】单例模式02:懒汉模式
  9. Redis如何高效实现点赞、取消点赞功能
  10. Java中Comparable和Comparator接口的区别