博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MyBatis(3)开发dao方法
阅读量:6038 次
发布时间:2019-06-20

本文共 9526 字,大约阅读时间需要 31 分钟。

本次全部学习内容

 
 
 
SqlSession
        SqlSession是一个面向用户(程序员)的接口。
        SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。
        SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)
还有数据域属性
       
 SqlSession最佳应用场合在方法体内,定义成局部变量使用。
        SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。
        通过SqlSessionFactory创建SqlSession,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。
 
        每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。
        因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
        打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。
 
 
 
SqlSessionFactoryBuilder
        通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
        将SqlSessionFactoryBuilder
当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。
        在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
 
        SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,
        因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方
        法范围即方法体内局部变量。
 
 
SqlSessionFactory
        通过SqlSessionFactory创建SqlSession,使用
单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。
        将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。
         SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围
        是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。
 
 
SqlSession:
SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类。
 
 
1.原始dao开发方法(程序员需要些dao接口和dao实现类)
程序员需要写dao接口和dao实现类
需要xiangdao实现类中注入SqlSessionFactory在方法体内通过SqlSessionFactory创建SQlSession
 
开始实践:
新建包和类
 

在UserDao.java接口中:

public interface UserDao {     //根据id查询用户信息     public User findUserById(int id) throws Exception;     //添加用户信息     public void insertUser(User user) throws Exception;     //删除用户信息     public void deleteUser(int id) throws Exception;}

 

 UserDao.java的实现类,UserDaoImp.java中:
 
//UserDao的实现类public class UserDaoImp implements UserDao {     //需要向dao实现类里面注入SqlSessionFactory     //通过构造器注入     private SqlSessionFactory SqlSessionFactory;     public UserDaoImp(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 void insertUser(User user) throws Exception {           SqlSession sqlSession = SqlSessionFactory.openSession();           sqlSession.insert("test.addUser", user);           //提交事务           sqlSession.commit();           //结束会话           sqlSession.close();     }     @Override     public void deleteUser(int id) throws Exception {           SqlSession sqlSession = SqlSessionFactory.openSession();           sqlSession.delete("test.deleteUser", id);           //提交事务           sqlSession.commit();           //结束会话           sqlSession.close();     }}

 在testUserDaoImp.java中:

 
public class testUserDaoImp {          private SqlSessionFactory SqlSessionFactory;     public SqlSessionFactory getSqlSessionFactory() throws IOException{           //配置文件的        String resource = "SqlMapConfig.xml";        //得到配置文件流        InputStream inputStream = Resources.getResourceAsStream(resource);        //创建会话工程       SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        return SqlSessionFactory;     }          //根据id查询用户信息     @Test     public void findUserById() throws Exception{           SqlSessionFactory SqlSessionFactory = getSqlSessionFactory();           UserDao userdao = new UserDaoImp(SqlSessionFactory);            User user = userdao.findUserById(1);           System.out.println(user);     }     //添加用户信息}

 控制台:

DEBUG [main] - Opening JDBC ConnectionDEBUG [main] - Created connection 2054574951.DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7a765367]DEBUG [main] - ==>  Preparing: select * from user where id=?DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - <==      Total: 1

 

 测试添加用户信息:
 
//添加用户信息     @Test     public void testAddUser() throws Exception{           SqlSessionFactory SqlSessionFactory = getSqlSessionFactory();           UserDao userdao = new UserDaoImp(SqlSessionFactory);           User user = new User();           user.setUsername("Ma");           user.setSex(1);           user.setAddress("安徽");           userdao.insertUser(user);          }

 控制台:

DEBUG [main] - Opening JDBC ConnectionDEBUG [main] - Created connection 22429093.DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]DEBUG [main] - ==>  Preparing: insert into user(id,username,birthday,sex,address) value(?,?,?,?,?)DEBUG [main] - ==> Parameters: 0(Integer), Ma(String), null, 1(Integer), 安徽(String)DEBUG [main] - <==    Updates: 1DEBUG [main] - ==>  Preparing: SELECT LAST_INSERT_ID()DEBUG [main] - ==> Parameters:DEBUG [main] - <==      Total: 1

 

 
 
 测试删除操作:
//删除用户信息           @Test           public void testDelete() throws Exception{                SqlSessionFactory SqlSessionFactory = getSqlSessionFactory();                UserDao userdao = new UserDaoImp(SqlSessionFactory);                userdao.deleteUser(29);           }
DEBUG [main] - Opening JDBC ConnectionDEBUG [main] - Created connection 22429093.DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]DEBUG [main] - ==>  Preparing: delete from user where id=?DEBUG [main] - ==> Parameters: 29(Integer)DEBUG [main] - <==    Updates: 1DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1563da5]

 

 
 
总结原始dao开发的问题:
 
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2、调用sqlsession方法时将statement的id硬编码了
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
 
 
 
 
 
2.mapper代理方法(程序员只需要mapper接口)
程序员还需要编写mapper.xml映射文件
程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
 
Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义
创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。
 
Mapper接口开发需要遵循以下规范:
  1. Mapper.xml文件中的namespace与mapper接口的类路径相同。
  2.  Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
  4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
 
接口定义有如下特点:
  1. Mapper接口方法名和Mapper.xml中定义的statement的id相同
  2. Mapper接口方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
  3. Mapper接口方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
 
以上开发规范主要是对下边的代码进行统一生成:
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.insert("test.insertUser", user);
update/insert/.........
........
 
 
 
 
代码的实现开始了:
 

 

 
创建包,类,已经映射文件
此时添加了新的映射文件一定要在全局配置文件中添加:

 在UserMapper.java接口中:

//根据id查询用户信息     public User findUserById(int id) throws Exception;
在UserMapper.xml文件中;
namespace:
是接口类的全类名
id:是接口类中的方法

 在测试类testUserMapper.java类中

private SqlSessionFactory SqlSessionFactory;     public SqlSessionFactory getSqlSessionFactory() throws IOException{           //配置文件的        String resource = "SqlMapConfig.xml";        //得到配置文件流        InputStream inputStream = Resources.getResourceAsStream(resource);        //创建会话工程       SqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);        return SqlSessionFactory;     }     @Test     public void testfindUserById() throws Exception{            //得到sqlsession           SqlSession sqlSession = getSqlSessionFactory().openSession();           //创建UserMapper的代理对象           UserMapper mapper = sqlSession.getMapper(UserMapper.class);           //调用userMapper的方法           User user = mapper.findUserById(27);           System.out.println(user);            sqlSession.close();     }

 实现成功:

DEBUG [main] - Opening JDBC ConnectionDEBUG [main] - Created connection 352359770.DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1500955a]DEBUG [main] - ==>  Preparing: select * from user where id=?DEBUG [main] - ==> Parameters: 27(Integer)DEBUG [main] - <==      Total: 1User [id=27, username=MrChegns, birthday=Fri Oct 05 00:00:00 CST 2018, sex=2, address=北京]

 

 
模糊查询:
在UserMapper.java接口中:
这里我们是不是会有疑问为什么不这样写?public User findByName(String name)  throws Exception;
//根据用户名查询(模糊查询)     public List
findByName(String name) throws Exception;
UserMapper.xml文件

 测试类:

@Test     public void testfindByName() throws Exception{           SqlSession sqlSession = getSqlSessionFactory().openSession();                      //创建UserMapper的代理对象           UserMapper mapper = sqlSession.getMapper(UserMapper.class);           //调用userMapper的方法           List
users = mapper.findByName("小明"); for(User user:users){ System.out.println(user); } sqlSession.close(); }

 查询成功:

DEBUG [main] - ==>  Preparing: select * from user where username Like '%小明%'DEBUG [main] - ==> Parameters:DEBUG [main] - <==      Total: 3User [id=16, username=张小明, birthday=null, sex=1, address=河南郑州]User [id=22, username=陈小明, birthday=null, sex=1, address=河南郑州]User [id=25, username=陈小明, birthday=null, sex=1, address=河南郑州]

 

模糊查询,此时可能会查出多个数据
public User findByName(String name)  throws Exception;
使用这个进行查询,系统在查询的时候会报错
 
 
 
代理对象内部调用selectOne或selectList:
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。
 
 
 
 
mapper接口方法参数只能有一个参数会不会影响开发:
mapper接口方法防暑只能有一个参数,系统开发是不利于扩展和维护的
系统框架中,dao层是被业务代码公用的
即使mapper接口层只有一个参数,可以使用包装类型的pojo满足不同的方法需求
注意:持久层方法的参数包装类型:map,service....不建议使用(不利于扩展)
 
 
 
 
 
 
 

转载于:https://www.cnblogs.com/Mrchengs/p/9750076.html

你可能感兴趣的文章
ios之UISlider
查看>>
短信验证流程
查看>>
php 使用htmlspecialchars() 和strip_tags函数过滤HTML标签的区别
查看>>
OpenCV Error: Assertion failed (data0.dims <= 2 && type == 5 && K > 0) in cv::kmeans
查看>>
python string 之 format
查看>>
树形DP 复习
查看>>
Vuex随笔
查看>>
crontab 不执行
查看>>
避免用for循环写数据
查看>>
Dijkstra(变形) POJ 1797 Heavy Transportation
查看>>
关于Webpack详述系列文章 (第三篇)
查看>>
关于Webpack详述系列文章 (第四篇)
查看>>
分布式系统的面试题15
查看>>
个人代码库の创建快捷方式
查看>>
由strcat函数引发的C语言中数组和指针问题的思考
查看>>
无锁编程
查看>>
如何在loadrunner中做关联
查看>>
二叉树的六种遍历方法汇总(转)
查看>>
用wxpython制作可以用于 特征筛选gui程序
查看>>
【转载】 [你必须知道的.NET]目录导航
查看>>