【MyBatis学习03】原始dao开发方法及其弊端
上一篇博文总结了一下mybatis的入门,接下来就要开发dao方法了,这篇博文主要总结一下mybatis中原始dao开发的方法,最后并总结一下原始dao开发方法的弊端。mybatis中dao开发应该使用mapper代理的方法,这将在下一篇博文中介绍。
原始dao开发思路比较简单,写个dao接口和dao实现类即可。需要向dao实现类中注入sqlSessionFactory,在方法体内通过sqlSessionFactory创建sqlSession。为什么在方法体内创建呢?因为mybatis中sqlSession是线程不安全的。如果在方法外面以成员变量的方式创建,可能会引发线程安全问题。下面总结一下原始dao开发的步骤(dao的方法跟上一节入门程序中的方法一致):
1. 写UserDao接口
public interface UserDao { //根据id查询用户信息
public User findUserById(int id) throws Exception;
//根据用户名模糊查询
public List<User> findUserByName(String name) throws Exception;
//添加用户信息
public void insertUser(User user) throws Exception;
//删除用户信息
public void deleteUser(int id) throws Exception;
//更新用户信息
public void updateUser(User user) throws Exception;
}
2. 写UserDaoImpl实现类
public class UserDaoImpl implements UserDao { private SqlSessionFactory sqlSessionFactory;
//需要向dao实现类中注入SqlSessionFactory,由于没和Spring整合,这里通过构造函数注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
} @Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
//释放资源
sqlSession.close();
return user;
} @Override
public List<User> findUserByName(String name) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByName", name);
//释放资源
sqlSession.close();
return list;
} @Override
public void insertUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();//执行插入要先commit
sqlSession.close();
} @Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser", id);
sqlSession.commit();//执行插入要先commit
sqlSession.close();
} @Override
public void updateUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("test.updateUser", user);
sqlSession.commit();//执行插入要先commit
sqlSession.close();
}
}
从UserDaoImpl实现类中可以看出,首先SqlSessionFactory需要注入进来,这里通过构造函数来注入,传个SqlSessionFactory进来即可完成注入。另外,sqlSession都是在具体方法内部创建的,没有将sqlSession放到外面,因为在方法内部,相对于每个线程是独立的,不会引起线程安全问题。至于每个方法内部的实现,和上一节的入门程序逻辑一样。
3. 写单元测试UserDaoImplTest
public class UserDaoImplTest { private SqlSessionFactory sqlSessionFactory; @Before
public void setUp() throws Exception {
//创建sqlSessionFactory
String resource = "SqlMapConfig.xml"; //mybatis配置文件 //得到配置文件的流
InputStream inputStream = Resources.getResourceAsStream(resource); //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test
public void testFindUserById() throws Exception {
//创建UserDao的对象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
System.out.println(userDao.findUserById(1));
}
}
从JUnit测试程序中可以看出,通过@Before注解,将SqlSessionFactory在测试方法执行之前初始化好,然后在测试方法中,直接通过构造函数传进去即可,这就和上面的UserDaoImpl实现类接上了。然后测试一下添加用户即可。
4. 原始dao开发存在的问题
从上面的代码中,可以很明显的看出原始dao开发方式有以下弊端:
dao接口实现类方法中存在大量重复代码,从设计上来看,应该抽取。
调用sqlSession方法时,将satement的id硬编码了,即类似于”test.findUserById”这种,都写死了。
sqlSession的方法中,要求传入的参数是Object类型的(泛型),也就是说如果我传错了参数,编译不会报错,执行的时候才会报错,不利于开发。
这些都是原始dao开发方式中存在的问题,在了解了原始dao开发方式的问题后,再来使用mapper代理开发dao,就可以形成鲜明的对比了。这篇博文就总结到这。
本篇可能发生的错误是:
Caused by: org.apache.ibatis.executor.ExecutorException: No constructor found in mybatis.po.User matching [java.lang.Integer, java.lang.String, java.sql.Date, java.lang.String, java.lang.String]
原因是缺少 无参的构造方法。
【MyBatis学习03】原始dao开发方法及其弊端的更多相关文章
- Mybatis学习笔记(三) —— DAO开发方法
一.SqlSession的使用范围 SqlSession中封装了对数据库的操作,如:查询.插入.更新.删除等. SqlSession通过SqlSessionFactory创建. SqlSessionF ...
- mybatis由浅入深day01_5mybatis开发dao的方法(5.1SqlSession使用范围_5.2原始dao开发方法)
5 mybatis开发dao的方法 5.1 SqlSession使用范围 5.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂 ...
- Mybatis的原始dao开发方法
在进入主题之前先提一下sqlSession.sqlSession是一个面向用户(程序员)的接口. sqlSession中提供了很多操作数据库的方法,如: selectOne(返回单个对象).selec ...
- Mybatis笔记 - 原始Dao开发方法
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.原始Dao的开发方式是基于入门程序的基础上,对 控制程序 进行分层开发,程序员需要 编写 Dao接口 和 ...
- Mybatis学习2传统dao开发
传统dao开发 在mybati基础上 dao和daoimpl 1.工厂工具类 获得SqlSessionFactory SqlSessionFactoryUtil.java package util; ...
- 【转】Mybatis学习---MyBatis知识、原始Dao开发和mapper代理开发
[原文]https://www.toutiao.com/i6594610137560777223/ 一.什么是MyBatis MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及 ...
- Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发
转载请注明出处:http://www.cnblogs.com/Joanna-Yan/p/6869133.html 前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——My ...
- Mybatis学习(2)原始dao开发和使用mapper接口代理开发
基础知识: 1).SqlSessionFactoryBuilder: 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory.将SqlSessionFact ...
- MyBatis开发Dao的原始Dao开发和Mapper动态代理开发
目录 咳咳...初学者看文字(Mapper接口开发四个规范)属实有点费劲,博主我就废了点劲做了如下图,方便理解: 原始Dao开发方式 1. 编写映射文件 3.编写Dao实现类 4.编写Dao测试 Ma ...
随机推荐
- (四)监控cpu
定义规则:创建模板--->群组--->应用集--->监控项--->图形--->触发器--->添加主机(加入到群组,关联模板) 1)cpu空闲率,用户态使用率,内核态 ...
- (二)mysql忘记root密码
(1)mysql 5.7.6以前版本 修改配置文件vim /etc/my.cnf [mysqld] skip-grant-tables 重启mysql systemctl restart mysqld ...
- PHP serialize 和 JSON 解析与区别
PHP serialize 和 JSON 解析与区别 对于JSON(JavaScript Object Notation)大家应该不陌生,它是一种轻量级的数据交换格式.易于人阅读和编写.同时也易于机器 ...
- 【ZOJ】3785 What day is that day? ——KMP 暴力打表找规律
转自:http://www.cnblogs.com/kevince/p/3887827.html 首先声明一下,这里的规律指的是循环,即找到最小循环周期. 这么一说大家心里肯定有数了吧,“不就是nex ...
- MongoDB走过的坑(4.0.3版本)
数据存储一般使用本地或者存储在数据库,MongoDB是一个非关系型数据库,今天小结下走过的一些坑. 1.网上的很多教程对自己无效 解决方法:这种情况一般都是和版本有关系,数据库在不断的更新发展,很多东 ...
- luogu P1056 排座椅
题目描述 上课的时候总会有一些同学和前后左右的人交头接耳,这是令小学班主任十分头疼的一件事情.不过,班主任小雪发现了一些有趣的现象,当同学们的座次确定下来之后,只有有限的D对同学上课时会交头接耳.同学 ...
- 「PKUWC 2018」随机算法 (第二版,正解做法)
上一版貌似是打了 O(3 ^ N) 暴力和 一条链的情况,得了60分.... 第一次做的时候光想练一练暴力...就没去想正解,谁知道正解比暴力好写不知道多少,mmp 设 f(S) 为 选集合S中的点可 ...
- 【推导】【贪心】Codeforces Round #402 (Div. 2) E. Bitwise Formula
按位考虑,每个变量最终的赋值要么是必为0,要么必为1,要么和所选定的数相同,记为2,要么和所选定的数相反,记为3,一共就这四种情况. 可以预处理出来一个真值表,然后从前往后推导出每个变量的赋值. 然后 ...
- 【pb_ds】【平衡树启发式合并】【并查集】bzoj2733 [HNOI2012]永无乡
用并查集维护联通性.对每个联通块维护一个平衡树.合并时启发式合并.比较懒,用了pb_ds. #include<cstdio> #include<ext/pb_ds/assoc_con ...
- MySQL json 类型操作快速入门
MySQL 5.7.8开始支持 json类型. create table t(id int,js json,PRIMARY KEY (`id`)) 插入数据insert into t values(1 ...