Mybatis笔记二---开发Dao层

Mybatis开发Dao层(Mapper动态代理开发):

​ 使用Mybatis开发Dao,通常有两种方法,一种是原始Dao开发,另一种是Mapper动态代理开发。

​ 在演示这两种方法之前,首先介绍一下SqlSessionFactoryBuilder,SqlSessionFactory,和SqlSession

### 1.SqlSessionFactoryBuilder

SqlSessionFactoryBuilder用于创建SqlSessionFacotySqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory创建的。所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是方法范围即方法体内局部变量。

2.SqlSessionFactory

​ SqlSessionFactory是一个接口,接口中定义了openSession的不同重载方法,SqlSessionFactory的最佳使用范围是整个应用运行期间,一旦创建后可以重复使用,通常以单例模式管理SqlSessionFactory。

###3.SqlSession

​ SqlSession是一个面向用户的接口,sqlSession中定义了数据库操作方法。

​ 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。

​ 打开一个SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到finally 块中以确保每次都能执行关闭。

SqlSession session = sqlSessionFactory.openSession();
try {
	 // do work
} finally {
	session.close();
}

4.原始Dao开发方式

​ 原始Dao开发方法需要程序员编写Dao接口和Dao实现类。这一种方式存在如下问题:

	Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法
	调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。

​ 下面主要介绍Mapper动态代理的方式开发Dao层。

5.Mapper动态代理开发Dao层

5.1开发规范
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的类型相同
#### 5.2开发准备

​ 5.2.1创建工程,导入所需jar包,在src同级目录下,创建source folder文件夹,在该文件夹下创建log4j.properties和SqlMapConfig.xml文件(相关内容请查看我的Mybatis入门博客),继续创建实体类和数据库表

​ 5.2.2在config目录下,创建mapper包,在该包下创建UserMapper.xml文件,内容如下:

<?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">
<!-- namespace:命名空间,用于隔离sql -->
<!-- 还有一个很重要的作用,使用动态代理开发DAO,1. namespace必须和Mapper接口类路径一致 -->
<mapper namespace="cn.pdsu.mybatis.mapper.UserMapper">
	<!-- 根据用户id查询用户 -->
	<!-- 2. id必须和Mapper接口方法名一致 -->
	<!-- 3. parameterType必须和接口方法参数类型一致 -->
	<!-- 4. resultType必须和接口方法返回值类型一致 -->
	<select id="queryUserById" parameterType="int"
		resultType="cn.pdsu.mybatis.pojo.User">
		select * from user where id = #{id}
	</select>

	<!-- 根据用户名查询用户 -->
	<select id="queryUserByUsername" parameterType="string"
		resultType="cn.pdsu.mybatis.pojo.User">
		select * from user where username like '%${value}%'
	</select>

	<!-- 保存用户 -->
	<insert id="saveUser" parameterType="cn.pdsu.mybatis.pojo.User">
		<selectKey keyProperty="id" keyColumn="id" order="AFTER"
			resultType="int">
			select last_insert_id()
		</selectKey>
		insert into user(username,birthday,sex,address) values
		(#{username},#{birthday},#{sex},#{address});
	</insert>

</mapper>
#### 5.3创建UserMapper.java接口
package cn.pdsu.mybatis.mapper;

import java.util.List;

import cn.pdsu.mybatis.pojo.User;

public interface UserMapper {
	/**
	 * 根据id查询
	 * 
	 * @param id
	 * @return
	 */
	User queryUserById(int id);

	/**
	 * 根据用户名查询用户
	 * 
	 * @param username
	 * @return
	 */
	List<User> queryUserByUsername(String username);

	/**
	 * 保存用户
	 * 
	 * @param user
	 */
	void saveUser(User user);
}

#### 5.4加载UserMapper.xml文件

修改SqlMapConfig.xml文件,添加以下所示的内容:

	<!-- 加载映射文件 -->
	<mappers>
		<mapper resource="sqlmap/User.xml" />
		<mapper resource="mapper/UserMapper.xml" />
	</mappers>
5.5使用junit单元测试,测试结果
public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;

	@Before
	public void init() throws Exception {
		// 创建SqlSessionFactoryBuilder
		SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
		// 加载SqlMapConfig.xml配置文件
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
		// 创建SqlsessionFactory
		this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
	}

	@Test
	public void testQueryUserById() {
		// 获取sqlSession,和spring整合后由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 执行查询方法
		User user = userMapper.queryUserById(27);
		System.out.println(user);

		// 和spring整合后由spring管理
		sqlSession.close();
	}

	@Test
	public void testQueryUserByUsername() {
		// 获取sqlSession,和spring整合后由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 执行查询方法
		List<User> list = userMapper.queryUserByUsername("张");
		for (User user : list) {
			System.out.println(user);
		}

		// 和spring整合后由spring管理
		sqlSession.close();
	}

	@Test
	public void testSaveUser() {
		// 获取sqlSession,和spring整合后由spring管理
		SqlSession sqlSession = this.sqlSessionFactory.openSession();

		// 从sqlSession中获取Mapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 创建保存对象
		User user = new User();
		user.setUsername("刘备");
		user.setBirthday(new Date());
		user.setSex("1");
		user.setAddress("蜀国");
		// 执行查询方法
		userMapper.saveUser(user);
		System.out.println(user);


		// 和spring整合后由spring管理
		sqlSession.commit();
		sqlSession.close();
	}
}

在测试之前先看一下我的数据库中得数据:

[外链图片转存失败(img-DN7FaH1q-1564213076734)(C:\Users\ADMINI~1.ZG-\AppData\Local\Temp\1564211288633.png)]

##### 5.5.1根据id查询用户,效果如下:

[外链图片转存失败(img-pc7Sm3vj-1564213076736)(C:\Users\ADMINI~1.ZG-\AppData\Local\Temp\1564211388635.png)]
#####5.5.2根据名字查询用户,效果如下:
在这里插入图片描述

5.5.3保存用户,效果如下:

在这里插入图片描述

6.SqlMapConfig.xml配置文件

配置内容
SqlMapConfig.xml中配置的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)

7.mappers(映射器)配置的几种方法

#### 	7.1<mapper resource=" " />

​ 使用相对于类路径的资源(现在的使用方式)

​ 如:

#### 	7.2 <mapper class=" " />

​ 使用mapper接口类路径

​ 如:<mapperclass=“cn.itcast.mybatis.mapper.UserMapper”/>

​ 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

#### 	7.3<package name=""/>

​ 注册指定包下的所有mapper接口

​ 如:

#### 	7.2 <mapper class=" " />

​ 使用mapper接口类路径

​ 如:<mapperclass=“cn.pdsu.mybatis.mapper.UserMapper”/>

​ 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

#### 	7.3<package name=""/>

​ 注册指定包下的所有mapper接口

​ 如:

​ 注意:此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值