Mybatis入门学习

在研究一项技术之前,我们要想一下为什么会出现这种技术,对于本文要研究的Mybatis我们讨论一下他为什么会出现,他的出现又是为了解决什么问题的呢?

首先,我们来看一下传统的JDBC方式是如何工作的:

package cn.xd.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JdbcTest {
	/**
	 * @通过分析jdbc程序发现存在的问题
	 */
	public static void main(String[] args) {	
		        	//数据库连接
				Connection connection = null;
				//预编译的Statement,使用预编译的Statement提高数据库性能
				PreparedStatement preparedStatement = null;
				//结果 集
				ResultSet resultSet = null;				
				try {
					//1.加载数据库驱动
					Class.forName("com.mysql.jdbc.Driver");					
					//2.通过驱动管理类获取数据库链接
					connection =  DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "162636");
					//3.定义sql语句 ?表示占位符
					String sql = "select * from user where username = ?";
					//获取预处理statement
					preparedStatement = connection.prepareStatement(sql);
					//设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
					preparedStatement.setString(1, "张三丰");
					//向数据库发出sql执行查询,查询出结果集
					resultSet =  preparedStatement.executeQuery();
					//遍历查询结果集
					while(resultSet.next()){
						System.out.println(resultSet.getString("id")+"  "+resultSet.getString("username"));
					}
				} catch (Exception e) {
					e.printStackTrace();
				}finally{
					//释放资源
					if(resultSet!=null){
						try {
							resultSet.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
					if(preparedStatement!=null){
						try {
							preparedStatement.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
					if(connection!=null){
						try {
							connection.close();
						} catch (SQLException e) {
							e.printStackTrace();
						}
					}
				}
	}

}
我们来分析一下其中存在的问题:

1、数据库的连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。
解决设想:使用数据库连接池管理数据库连接。

2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。
解决设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。
设想:将sql语句及占位符号和参数全部配置在xml中。

4、从resutSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。
设想:将查询的结果集,自动映射成java对象。

补充:所谓的硬编码就是什么都在你的程序代码里面写死了,如果你想稍微修改一下效果,都得修改你的代码。


解决方式:Mybatis框架(当然还有其他的持久层框架也可以解决这些问题,hibernate等)

1、什么是Mybatis

MyBatis 是一个支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
注:Mybatis的着力点在于POJO和SQL之间的映射关系,而Hibernate(典型的ORM---对象关系映射框架)的着力点则在于POJO和数据库表之间的映射。

2.Mybatis的执行流程


(1)加载配置并初始化
触发条件:加载配置文件
处理过程:将SQL的配置信息加载成为一个个MappedStatement对象(包括了传入参数映射配置、执行的SQL语句、结果映射配置),存储在内存中。
(2)接收调用请求
触发条件:调用Mybatis提供的API
传入参数:为SQL的ID和传入参数对象
处理过程:将请求传递给下层的请求处理层进行处理。
(3)处理操作请求
触发条件:API接口层传递请求过来
传入参数:为SQL的ID和传入参数对象
处理过程:
(A)根据SQL的ID查找对应的MappedStatement对象。
(B)根据传入参数对象解析MappedStatement对象,得到最终要执行的SQL和执行传入参数。
(C)获取数据库连接,根据得到的最终SQL语句和执行传入参数到数据库执行,并得到执行结果。
(D)根据MappedStatement对象中的结果映射配置对得到的执行结果进行转换处理,并得到最终的处理结果。
(E)释放连接资源。
(4)返回处理结果将最终的处理结果返回。

3、下面我们按照流程进行一次简单的Mybatis开发演示

3.1、开发需求:根据用户id查询用户信息

3.2、开发环境准备

在数据库中建表(User表),建立web工程并将Mybatis需要的jar包导入工程中,将Mysql的驱动jar包导入工程中。

3.3 、开始编写示例程序(使用mapper接口方法)

工程结构如下图:


使用mapper接口开发应该遵循以下的规范:

  1、在mapper.xml中的namespace等于mapper接口地址
 
  2、mapper.java接口中的方法名和mapper.xml中statement的id一致

  3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

  4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

下面是主要代码:

a、UserMapper.java

public interface UserMapper {	
	public User findUserById(int id) throws Exception;
}
b、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">

<mapper namespace="cn.xd.mybatis.mapper.UserMapper">
	<select id="findUserById" parameterType="int" resultType="user">
		SELECT * FROM USER WHERE id=#{value}
	</select>		
</mapper>
可以分别对照一下上面的四条规范。

注意:不要忘记在SqlMapConfig的配置文件中配置UserMapper.xml,否则会报错:Type interface UserMapper is not known to the MapperRegistry.(还有一种情况会报这种错误,就是包名写错了。。。。)

3.4、编写测试程序,并执行(本文使用的是Junit测试,要加入Junit的jar包)

public class UserMapperTest {	
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp() throws Exception {
		   // mybatis配置文件
		String resource = "SqlMapConfig.xml";
		// 得到配置文件流
		InputStream inputStream = Resources.getResourceAsStream(resource);
		// 创建会话工厂,传入mybatis的配置文件信息
		sqlSessionFactory = new SqlSessionFactoryBuilder()
				.build(inputStream);
	}

	@Test
	public void testFindUserById() throws Exception {
		SqlSession sqlSession=sqlSessionFactory.openSession();
		UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
		User user=userMapper.findUserById(31);
		System.out.println(user.getUsername());
	}
	
}

至此,一个简单的Mybaits示例就完成了,同时可以看出Mybatis已经解决了上面Jdbc存在的问题。
最后要注意一点:

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
因此SqlSession的最佳应用场合在方法体内,定义成局部变量使用。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值