本次全部学习内容: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. How to push master to QA branch in GIT

    1.  git branch -d QA2.  git branch QA master3.  git checkout QA4.  git push origin QA(if push error, ...

  2. visual studio 安装与sqlserver 安装

    先sqlserver再visual studio ,避免安装目录重复(sqlserver 中包含一部分visual  而  visual studio 中也包含有部分sqlserver内容) 安装vi ...

  3. Be opinionated out of the box but get out of the way quickly as requirements start to diverge from

    Be opinionated out of the box but get out of the way quickly as requirements start to diverge from t ...

  4. Maven --- <distributionManagement>标签

    1.<distributionManagement>的作用: 负责管理构件的发布.这是一个环境变量    <downloadUrl> URL </downloadUrl& ...

  5. JAVA学习之路(多线程)---模拟售票(细解)

    首先看题目描述: 假设有火车票100张,创建4个线程模拟4个售票点,每100ms售出一张,打印出售票过程,格式如下: 窗口3:卖出第100张票 窗口4:卖出第99张票 ............ ... ...

  6. Discuz x3 UCenter实现同步登陆原理

    1.Discuz x3 的登录页面URL是:/member.php?mod=logging&action=login 2.这个登录页面,登录提交的地址是: <form method=&q ...

  7. JDK自带工具keytool生成ssl证书 和 HTTPS双向认证

    创建证书(第一步) keytool -genkey -alias "baidu" -keypass "123456" -keystore "D:/ba ...

  8. 我的Java编码规范

    1.类名采用驼峰命名法,首字母大写. 2.类变量采用驼峰命名法,首字母小写. 3.方法名是一个动词短语,首字母小写,尽量能描述清楚这个方法的意图. 4.注释在精不在多,一个好的注释要尽量描述出这段代码 ...

  9. 廖雪峰JavaScript练习题

    练习:不要使用JavaScript内置的parseInt()函 数,利用map和reduce操作实现一个string2int()函数: <!DOCTYPE html> <html&g ...

  10. windows server 2008远程桌面最大连接数设置

    1. 运行gpedit.msc: 2. 选择计算机配置-->管理模板-->Windows组件-->远程桌面服务-->远程桌面会话主机-->连接: 3. 双击“限制连接的数 ...