本次全部学习内容:MyBatisLearning

 
 
 
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 Connection
DEBUG [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 Connection
DEBUG [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: 1
DEBUG [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 Connection
DEBUG [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: 1
DEBUG [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/.........
........
 
 
 
 
代码的实现开始了:
 

创建包,类,已经映射文件
此时添加了新的映射文件一定要在全局配置文件中添加:
     <mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>

在UserMapper.java接口中:

     //根据id查询用户信息
public User findUserById(int id) throws Exception;
在UserMapper.xml文件中;
namespace:是接口类的全类名
id:是接口类中的方法
<mapper namespace="com.MrChengs.mapper.UserMapper">
<!-- 根据id查询 -->
<!-- public User findUserById(int id) throws Exception; -->
<select id="findUserById" parameterType="int" resultType="com.MrChengs.po.User">
select * from user where id=#{id}
</select>
</mapper>

在测试类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 Connection
DEBUG [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: 1
User [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<User> findByName(String name) throws Exception;
UserMapper.xml文件
   <!-- 根据用户名查询 -->
<select id="findByName" parameterType="java.lang.String" resultType="com.MrChengs.po.User" >
select * from user where username Like '%${value}%'
</select>

测试类:

    @Test
public void testfindByName() throws Exception{
SqlSession sqlSession = getSqlSessionFactory().openSession(); //创建UserMapper的代理对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class); //调用userMapper的方法
List<User> 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: 3
User [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....不建议使用(不利于扩展)
 
 
 
 
 
 
 

MyBatis(3)开发dao方法的更多相关文章

  1. 使用mybatis开发dao方法

    使用mybatis开发dao的时候, 主要涉及到SqlSessionFactoryBuilder.SqlSessionFactory.SqlSession 这三个类 现在将这三个类的使用方法简单的说下 ...

  2. Mybatis的mapper代理开发dao方法

    看完了之前的mybatis原始的dao开发方法是不是觉得有点笨重,甚至说没有发挥mybatis 作为一个框架的优势.总结了一下,原始的dao方法有以下几点不足之处 dao接口实现方法中存在大量的模板方 ...

  3. 09_Mybatis开发Dao方法——mapper代理开发规范

    一.开发规范 需要编写mapper.xml映射文件(本项目为userMapper.xml,类似于前面的user.xml). 编写mapper接口需要遵循一些开发规范,这样MyBatis可以自动生成ma ...

  4. 10_Mybatis开发Dao方法——mapper代理实现

    [工程截图(几个关键的标红框)] [UserMapper.xml] <?xml version="1.0" encoding="UTF-8"?> & ...

  5. 【mybatis深度历险系列】深入浅出mybatis中原始dao的开发和mapper代理开发

    使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法.mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder ...

  6. MyBatis学习--mybatis开发dao的方法

    简介 使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法. 主要概念介绍: MyBatis中进行Dao开发时候有几个重要的类,它们是SqlSessionFac ...

  7. 四 mybatis开发dao的方法

    mybatis开发dao的方法 1.1     SqlSession使用范围 1.1.1     SqlSessionFactoryBuilder //以流的方式读取总的配置文件 Reader rea ...

  8. 【mybatis基础】mybatis开发dao两种方法

    mybatis是一个支持普通SQL查询,存储过程和高级映射的优秀的持久层的框架,是apache下的顶级项目.mybatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.mybat ...

  9. mybatis由浅入深day01_5mybatis开发dao的方法(5.1SqlSession使用范围_5.2原始dao开发方法)

    5 mybatis开发dao的方法 5.1 SqlSession使用范围 5.1.1 SqlSessionFactoryBuilder 通过SqlSessionFactoryBuilder创建会话工厂 ...

随机推荐

  1. Win7 开机启动

    1.注册表里面写代码,设置程序以开机启动; 但这样会需要管理员权限,添加程序以管理员权限启动后,又无法直接进入到软件启动界面,UAC控制 代码一: /// <summary> /// 设置 ...

  2. JavaMail 邮件发送

    jar包部署 /** * 通过SMTP进行邮件集成 */ public class CmpSendMail { // 邮件发送服务器主机 private final static String HOS ...

  3. Gradle sync failed: Cannot set the value of read-only property 'outputFile'

    错误 Gradle sync failed: Cannot set the value of read-only property 'outputFile' 原因 gradle打包,自定义apk名称代 ...

  4. php 正则验证

      PHP 正则验证字符串是否为数字 方法一: php中利用正则表达式验证字符串是否为数字一件非常容易的事情,最主要的是如何写好正则表达式以及掌握正则表达式的写法,在此利用正则表达式的方式来列举一下判 ...

  5. SZU5

    A - Couple doubi 这种题不要想复杂,直接找规律.找不出规律就打表找规律 #include <iostream> #include <string> #inclu ...

  6. JavaEE之会话技术Cookie&Session

    会话技术简介 存储客户端的状态 由一个问题引出今天的内容,例如网站的购物系统,用户将购买的商品信息存储到哪         里?因为Http协议是无状态的,也就是说每个客户访问服务器端资源时,服务器并 ...

  7. Grunt实践之简易教程

    以前自己太low了,都没用过高大上的前端自动化打包工具,开发方式也是偏传统的.加入到新的团队后得拼命赶上啊,前端技术更迭太快,各种技术层出不穷,智商都快不够用了.看人家都用的牛逼哄哄的技术,自己还守着 ...

  8. 01_Nginx入门

    [Nginx概述] Nginx是一款轻量级的Web服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,并在一个BSD-Like协议下发行.其特点是占有内存少,并发能力强,事实上Nginx ...

  9. Ganglia安装

    一.rrdtool安装 1.1 安装依赖包 由于rrdtool依赖的包比较多,而且包之间也存在依赖,故使用yum安装由于服务器无法联网,故使用iso文件创建本地yum源,方法见下: (1)创建iso存 ...

  10. tomcat本地部署正常linux服务器报404

    tomcat主页访问正常,tomcat自带的examples项目也可以访问,可自己的项目就报404,这是什么问题那? 仔细看了下 服务器webapp下面的文件,访问时候 我是访问的服务器ip/Wech ...