一、前言

从上一篇文章的junit单元测试环节可以看到,每一次调用MyBatis需要先加载SqlMapConfig.xml文件,再通过SqlSessionFactoryBuilder创建SqlSessionFactory,然后从SqlSessionFactory获取SqlSession,最后调用SqlSession的selectOne、selectList、insert、delete方法完成数据库操作,编码效率低下。

二、若干概念的解释

1、SqlSession的使用范围
SqlSession中封装了对数据库的操作,如:查询、插入、更新、删除等。SqlSession是通过SqlSessionFactory创建,而SqlSessionFactory是通过SqlSessionFactoryBuilder进行创建。 2、SqlSessionFactoryBuilder
SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不被需要了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围,即方法体内局部变量。 3、SqlSessionFactory
SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法。SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。 4、SqlSession
SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作方法。每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。打开一个SqlSession,使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。如下: SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}

三、使用MyBatis开发DAO的第一种方式:原始DAO开发方式

第一步:复用上一个实验中的文件(步骤1~步骤7)

第二步:创建接口UserDao(在接口中定义了操作数据库的Dao方法)

第三步:创建接口UserDao的实现类UserDaoImpl

第四步:单元测试(模拟日常使用)

public class UserDaoTest {

    private SqlSessionFactory sqlSessionFactory;

    /**
* 通过@Before完成sqlSessionFactory的创建
*/
@Before
public void setUp() throws Exception {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
} /**
* 每次使用DaoImpl时, 以构造函数传参的方式将sqlSessionFactory注入给DaoImpl, 然后调用DaoImpl的方法完成数据库操作
*/
@Test
public void testSelectById() throws Exception {
System.out.println(new UserDaoImpl(sqlSessionFactory).findUserById(10));
} @Test
public void testSelectByUsername() throws Exception {
List<User> userByUserName = new UserDaoImpl(sqlSessionFactory).findUserByUserName("王%"); for (User user : userByUserName) {
System.out.println(user);
}
}
}

问题:

原始Dao开发中存在以下问题:
  1、Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
  2、调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不利于开发维护。 代码位置:
https://github.com/echo1937/mybatis-demo的mybatis-dao模块

四、使用MyBatis开发DAO的第二种方式:Mapper接口动态代理方式

开发规范:

接口动态代理方式:
  仅编写 mapper接口(即Dao接口)和 SQL映射文件,由Mybatis框架自动生成接口的动态代理对象(实现了mapper接口定义的方法)。
Mapper接口开发需要遵循以下规范:
  1、mapper接口的类路径与Mapper.xml文件中的namespace相同。
  2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
  4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

第一步:复用上一个实验中的文件(步骤1~步骤5,不再需要第六步的sql映射文件Users.xml;第七步加载Users.xml自然也要修改)

第二步:创建UserMapper.xml映射文件

定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径(规范一)。将UserMapper.xml放在cn.it.mapper目录下。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
1、Mapper接口的全路径名称和Mapper.xml中的namespace相同
2、Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
3、Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
4、Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
--> <mapper namespace="cn.it.mapper.UserMapper"> <select id="findUserById" parameterType="java.lang.Integer" resultType="cn.it.pojo.User">
select * from user where id = #{id}
</select> <select id="findUserByUsername" parameterType="java.lang.String" resultType="cn.it.pojo.User">
SELECT * FROM user WHERE username LIKE '${value}'
</select> <insert id="insertUser" parameterType="cn.it.pojo.User">
<selectKey order="AFTER" resultType="java.lang.Integer" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
INSERT INTO user(username,birthday,sex,address)VALUES (#{username},#{birthday},#{sex},#{address})
</insert> </mapper>

第三步:创建UserMapper.java接口文件

package cn.it.mapper;

import cn.it.pojo.User;

import java.util.List;

/**
* A. 原生DAO实现 (需要写DAO接口和DAO实现类)
* B. 动态代理方式 (只需要写接口)
* 1、Mapper接口的全路径名称和Mapper.xml中的namespace相同
* 2、Mapper接口中的方法名和Mapper.xml中定义的statement的id相同
* 3、Mapper接口中的方法的输入参数类型和mapper.xml中定义的statement的parameterType的类型相同
* 4、Mapper接口中方法的输出参数类型和mapper.xml中定义的statement的resultType的类型相同
*/
public interface UserMapper {
User findUserById(int id); List<User> findUserByUsername(String username); void insertUser(User user); }

第四步:在SqlMapConfig.xml文件中配置sql映射文件,保证可以被读取

    <mappers>
<package name="cn.it.mapper"/>
<!--使用包扫描的方式批量引入Mapper接口: 1、接口名称和映射文件名称除扩展名外要完全相同; 2、接口和映射文件必须放在同一个目录中-->
</mappers>

第五步:单元测试(Dao接口 + SQL映射文件,MyBatis会自动生成DaoImpl)

public class UserMapperTest {

    private SqlSessionFactory sqlSessionFactory;

    @Before
public void setUp() throws Exception {
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
} /**
* 依然需要通过@Before生成sqlSessionFactory, 但不再需要注入给DaoImpl, 因为DaoImpl由MyBatis自动生成.
* 只需要在方法中生成线程安全的SqlSession, 然后获取我们需要的Mapper, 即可调用Dao接口中定义的方法
*/
@Test
public void findUserById() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper userMapper = openSession.getMapper(UserMapper.class);
System.out.println(userMapper.findUserById(10));
} @Test
public void fineUserByUserame() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper userMapper = openSession.getMapper(UserMapper.class); List<User> userList = userMapper.findUserByUsername("王%");
for (User user : userList) {
System.out.println(user);
}
} @Test
public void insertUser() throws Exception {
SqlSession openSession = sqlSessionFactory.openSession();
UserMapper userMapper = openSession.getMapper(UserMapper.class); User user = new User();
user.setUsername("阿拉蕾");
userMapper.insertUser(user); System.out.println(user.getId());
openSession.commit();
}
}

小结:

1、selectOne和selectList
  动态代理对象如何选取sqlSession.selectOne()和sqlSession.selectList()是根据接口方法的返回值决定,如果返回List则调用selectList方法,如果返回单个对象则调用selectOne方法。 2、namespace
  MyBatis官方推荐使用mapper接口动态代理的方式开发Dao层,程序员不用编写mapper接口实现类。使用动态代理方式时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。
SqlMapConfigxml中<Mapper>配置的几种方法:

<mapper resource="" />    使用相对于classpath的资源,如:<mapper resource="sqlmap/User.xml" />

<mapper class="" />       使用mapper接口类路径,如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。 <package name=""/> 注册指定包下的所有mapper接口,如:<package name="cn.itcast.mybatis.mapper"/>
注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。
代码位置:
https://github.com/echo1937/mybatis-demo的mybatis-mapper模块

MyBatis基本配置和实践(二)的更多相关文章

  1. Nginx配置try_files实践二

    本文内容承接<Nginx配置try_files实践一> 1. 环境: OS:Ubuntu 15.10 nginx:nginx/1.9.3 (Ubuntu) 假设有三台虚拟机db1(IP:1 ...

  2. MyBatis基本配置和实践(三)

    一.输入映射和输出映射 mapper.xml映射文件中定义了操作数据库的sql,每条sql就是一个statement,映射文件是MyBatis的核心. 1.parameterType(输入类型) 简单 ...

  3. MyBatis基本配置和实践(一)

    第一步:创建Java工程和数据库表user 第二步:使用Maven管理项目依赖 第三步:在resources目录下加入log4j.properties 第四步:在resources目录下加入SqlMa ...

  4. Spring MVC基本配置和实践(二)

    1. springmvc: 是一个表现层框架,作用是从请求中接收传入的参数,将处理后的结果数据返回给页面展示 2. ssm整合: 1)Dao层 pojo.mapper接口.mapper映射文件(使用逆 ...

  5. MyBatis基本配置和实践(五)

    第一步:创建一个Maven工程 第二步:编辑Maven工程的pom.xml,引入mybatis-generator-maven-plugin <?xml version="1.0&qu ...

  6. MyBatis基本配置和实践(四)

    一.Mybatis整合spring 1.整合思路 SqlSessionFactory对象应该放到spring容器中作为单例存在. 传统dao的开发方式中,应该从spring容器中获得sqlsessio ...

  7. Nginx配置try_files实践一

    参考资料: http://linuxplayer.org/2013/06/nginx-try-files-on-multiple-named-location-or-serverhttp://stac ...

  8. 2017.2.9 深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二)-----配置文件详解

    深入浅出MyBatis技术原理与实践-第八章 MyBatis-Spring(二) ------配置文件详解 8.2 MyBatis-Spring应用 8.2.1 概述 本文主要讲述通过注解配置MyBa ...

  9. DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描

    DB数据源之SpringBoot+MyBatis踏坑过程(二)手工配置数据源与加载Mapper.xml扫描 liuyuhang原创,未经允许进制转载  吐槽之后应该有所改了,该方式可以作为一种过渡方式 ...

随机推荐

  1. 20190416 OSX系统使用VMware Fusion安装CentOS7踩的那些坑

    一.创建虚拟机 (1)在虚拟机资源库中点击[+添加]按钮,选择“新建...”选项 (2)选择创建自定义虚拟机 (3)选择系统类型为CentOS (4)选择虚拟磁盘类型 (5)选择虚拟机存储位置:点击[ ...

  2. [Xamarin]測試帳號申請與到期後如何續用 (转帖)

    在Xamarin網站上可以申請30天試用的測試帳號.試用期內,Xamarin會提供完整的功能試用. 30天試用時間到期後,在Visual Studio裡面你載入你的專案的時候,專案旁會標註(無法使用) ...

  3. Visual Studio 跨平台開發實戰(5) - Xamarin Android 多頁面應用程式開發 (转帖)

    前言 大部份的Android 都具有實體或虛擬的Back鍵. 因此在處理多頁面應用程式時, 與先前所介紹的iOS Navigation controller 比較起來會簡單許多. 1. 開啟Visua ...

  4. php7安装并apache

    1.下载php7 选择THREAD SAFE版本,如果是64位系统要下载x64的,x86的不行 2.解压到想要安装的目录 3.apache配置 1) 添加PHP模块 查找“Dynamic Shared ...

  5. 第1章—Spring之旅—容纳你的Bean

    容纳你的Bean 在基于Spring的应用中,你的应用对象生存于Spring容器中.Spring负责创建对象,装配他们,配置他们并管理他们整个生命周期,从生存到死亡(在这里 可能是new 到 fina ...

  6. VMware虚拟机配置

    VMware虚拟机配置 背景 在做学习Linux时经常会在win环境下安装虚拟机,这其中涉及到一些细节操作,需要对虚拟机工作模式加以理解. 本文在学习hadoop分布式环境搭建时写作. 1.虚拟交换机 ...

  7. 多线程并发问题解决之redis锁

    一 问题背景 我们做的是医疗信息化系统,在系统中一条患者信息对医院中当前科室中的所有诊断医生是可见的,当有一个诊断医生点击按钮处理该数据时,数据的状态发生了变化,其他的医生就不可以再处理此患者的数据了 ...

  8. 端口扫描工具nmap

    nmap 使用介绍 nmap是目前为止最广为使用的国外端口扫描工具之一.我们可以从[url]http://www.insecure.org/[/url]进行下载,可以很容易的安装到Windows和un ...

  9. [linux] C语言Linux系统编程-socket回声客户端

    回声客户端: 1.所谓“回声”,是指客户端向服务器发送一条数据,服务器再将数据原样返回给客户端,就像声音一样,遇到障碍物会被“反弹回来”. 2.客户端也可以使用 write() / send() 函数 ...

  10. 十七、ThreadPoolExecutor线程池

    一.简介 executor接口 executor接口在JDK的java.util.concurrent包下,它只有一个抽象方法: void execute(Runnable command); 这意味 ...