Mybatis的基本运行流程

匿名 (未验证) 提交于 2019-12-02 23:26:52

Mybatis基本运行流程

总结JDBC的问题:

1、数据库连接创建、释放频繁造成系统资源浪费,从而影响系统性能。如果使用数据库连接池可解决此问题。

2、Sql语句在代码中硬编码,造成代码不易维护,实际应用中sql变化的可能较大,sql变动需要改变java代码。

3、使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。

4、对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。

1.Mybatis介绍

SQL查询存储过程高级映射的优秀持久层框架MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO映射成数据库中的记录

自动映射生成最终执行的sql语句,并将sql语句执行结果自动映射成java对象,返回给业务层(service)应用。

Mybatis的整体架构

2.Mybatis的生命周期

(1)SqlSessionFactoryBuilder:作用就是创建一个构建器,一旦创建了SqlSessionFactory,它的任务就算完成了,可以回收。

(2)SqlSessionFactory:作用是创建SqlSession,而SqlSession相当于JDBC的一个Connection对象,每次应用程序需要访问数据库,我们就要通过SqlSessionFactory创建一个SqlSession,所以SqlSessionFactory在整Mybatis整个生命周期中(每个数据库对应一个SqlSessionFactory,是单例产生的)。

(3)SqlSession:生命周期是存在于请求数据库处理事务的过程中,是一个线程不安全的对象(在多线程的情况下,需要特别注意),即存活于一个应用的请求和申请,可以执行多条SQL保证事务的一致性。

(4)Mapper:是一个接口,它的作用是发送SQL(其中的方法相当于JDBC中的Statement),返回我们需要的结果,或者发送SQL修改数据库表,所以它存活于一个SqlSession内,是一个方法级别的东西。当SqlSession销毁的时候,Mapper也会销毁。

为什么SqlSessionFactory是单例的:

3.Mybatis的配置

3.1单独使用Mybatis的配置


1.按照上面的步骤首先定义一个User类

User.java

public class User { 	private Integer id; 	private String username; 	private Integer[] ids; 	private List<Integer> idlist; 	public Integer[] getIds() { 		return ids; 	} 	public void setIds(Integer[] ids) { 		this.ids = ids; 	} 	public List<Integer> getIdlist() { 		return idlist; 	} 	public void setIdlist(List<Integer> idlist) { 		this.idlist = idlist; 	} 	public Integer getId() { 		return id; 	} 	public void setId(Integer id) { 		this.id = id; 	} 	public String getUsername() { 		return username; 	} 	public void setUsername(String username) { 		this.username = username; 	} 	@Override 	public String toString() { 		return "User [id=" + id + ", username=" + username + "]"; 	} } 

2.接着定义一个Mapper接口:定义了一些方法来操作数据库,方法中具体sql语句的实现在相应的xml文件中。

UserMapper.interface

public interface UserMapper { 	/* 	 * 遵循四个原则: 	 * 		1.方法名和UseMapper.xml中<mapper>标签中sql标签的id属性值相同 	 * 		2.方法的返回值和<mapper>标签中标签的resultType属性值相同 	 * 		3.方法的参数类型和<mapper>标签中标签的parameterType属性值相同 	 * 		4.xml中<mapper>标签的namespace属性值和此接口的全类名相同 	 */ 	 User findUserById(Integer id); } 

3.接着定义Mapper的映射文件UserMapper.xml,此文件的作用就是映射方法实现具体的SQL语句。

<mapper namespace="Mapper.UserMapper"> 	<!-- 设置一个sql片段 可以SQL语句中在引用--> 	<sql id="selector"> 		select * from user 	</sql> 	<select id(方法名)="findUserById" parameterType(方法的参数类型)="Integer" resultType(方法的返回类型)="pojo.User"> 		<include refid="selector"/>         where id = #{id} 	</select> </mapper> 

4.定义了UserMapper和UserMapper.xml之后那么程序如何才能寻找到呢,通过Mybatis的配置文件。

sqlMapConfig.xml

<configuration> 	<!-- 指定加载配置文件 --> 	<properties resource="jdbc.properties"/> 	<!-- 别名设置 --> 	<typeAliases> 		<package name="pojo"/>	 	</typeAliases>  	<!-- 和Spring整合后这个标签就没用了 --> 	<environments default="development"> 		<environment id="development"> 			<!-- 使用jdbc事务管理 --> 			<transactionManager type="JDBC" /> 			<!-- 数据库连接池 --> 			<dataSource type="POOLED"> 				<property name="driver" value="${jdbc.driver}" /> 				<property name="url" 					value="jdbc:mysql://localhost:3306/student" /> 				<property name="username" value="root" /> 				<property name="password" value="123456" /> 			</dataSource> 		</environment> 	</environments> 	<!-- 引入User的xml映射文件 我的UserMapper.java 和UserMapper.xml都在Mapper包下--> 	<mappers> 		<package name="Mapper"/> 		<!-- package这种方式需要接口名和xml文件名相同,直接导入包下所有配置文件 		--> 	</mappers> </configuration> 

5.配置好了配置文件创建一个demo实例来加载配置文件并创建sqlSessionFactory

UserDemo.java

public class UserDemo { 	@Test 	//通过id查询值 	public void fun() throws IOException{ //		1.加载配置文件 		InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml"); //		2.创建SqlSessionFactory 		SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(in); //		3.创建sqlSession 		SqlSession sqlSession=sqlSessionFactory.openSession(); //		4.sqlSeesion动态创建UserMapper实现类 		UserMapper userMapper = sqlSession.getMapper(UserMapper.class); //		5.实现类调用接口的方法,方法和映射文件一一对应 		User user=userMapper.findUserById(1); 		System.out.println(user); 	} 

3.2Mybatis整合Spring

applicationContext.xml

context:property-placeholder location="classpath:jdbc.properties"/> 	<!-- 将连接池注入容器 --> 	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" 		destroy-method="close"> 		<property name="driverClassName" value="${jdbc.driver}" /> 		<property name="url" value="${jdbc.url}" /> 		<property name="username" value="${jdbc.username}" /> 		<property name="password" value="${jdbc.password}" /> 		<property name="maxActive" value="10" /> 		<property name="maxIdle" value="5" /> 	</bean> 	<!--配置工厂 --> 	<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean"> 		<property name="dataSource" ref="dataSource"/> 		<!-- 核心配置文件的位置 --> 		<property name="configLocation" value="classpath:sqlMapConfig.xml"/> 	</bean> 	<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> 		<!-- 扫描包下的所有接口 --> 		<property name="basePackage" value="mapper"/> 		<!-- 这里会自动注入mapper接口 			<bean name="userMapper" class="mapper.UserMapper"/> 		 --> 	</bean> </beans> 

这里的SqlSessionFactoryBean在Spring中最后创建的并不是Bean本身而是sqlSessionFactory

sqlMapConfig.xml文件只需设置一个别名(或者也不设置)

<configuration> 	<!-- 设置别名 --> 	<typeAliases> 		<!-- 2. 指定扫描包,会把包内所有的类都设置别名,别名的名称就是类名,大小写不敏感 --> 		<package name="pojo" /> 	</typeAliases> </configuration> 

UserDemo.java

	@Test 	public void testMapper() throws Exception { 		ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); 		UserMapper mapper = ac.getBean(UserMapper.class); 		User user = mapper.selectUserById(1); 		System.out.println(user); 	} 

这里的getBean会创建UserMapper的实现类

文章来源: https://blog.csdn.net/qq_38238296/article/details/89292943
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!