2.Mybatis两种开发模式

本文介绍MyBatis框架中的两种DAO开发模式:普通模式和接口代理模式,并详细展示了如何通过实现接口和使用接口代理来操作数据库。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

普通模式

自定义接口,接口实现类。

思考:需要sqlSessionFactory,生产sqlSession

UserDao:

package dao;

import java.util.List;
import domain.User;

public interface UserDao {
	//根据Id查询用户
	public User findUserByID(Integer id);
	//根据用户名进行模糊查询
	public List<User> findUserByUsername(String username);

}

UserDaoImpl:

package dao.impl;

import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import dao.UserDao;
import domain.User;

public class UserDaoImpl implements UserDao{
	
	//namespace
	private String ns="test.";

	private SqlSessionFactory sqlSessionFactory;
	public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
		this.sqlSessionFactory=sqlSessionFactory;
	}
	
	public User findUserByID(Integer id) {
		SqlSession sqlSession=sqlSessionFactory.openSession();
		User user = sqlSession.selectOne(ns+"findUserByID",id);
		
		return user;
	}

	public List<User> findUserByUsername(String username) {
		SqlSession sqlSession=sqlSessionFactory.openSession();
		List<User> list=sqlSession.selectList(ns+"findUserByUsername", username);
		
		return list;
	}
}

Main3:

package test;

import static org.hamcrest.CoreMatchers.nullValue;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import dao.UserDao;
import dao.impl.UserDaoImpl;
import domain.User;

public class Main3 {

	SqlSessionFactory sqlSessionFactory=null;
	
	@Before
	public void beforeConf() throws IOException{
		String resources="sqlMapConfig.xml";
		InputStream inputStream=Resources.getResourceAsStream(resources);
		sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
		
	}
	
	//普通dao开发模式
	@Test
	public void commonDao(){
		UserDao userDao=new UserDaoImpl(sqlSessionFactory);
		//根据Id查询用户
		User user1 = userDao.findUserByID(16);
		System.out.println("user1:::"+user1);
		
		//根据名字模糊查询用户
		List<User> list = userDao.findUserByUsername("张");
		System.out.println(list);
	}
}

  

接口代理开发模式

自需要定义接口。

开发约定:

l 映射文件namespace必须是接口全类路径名。

l 映射文件的Statementid必须和接口的方法名一致。

sqlMapConfig.xml:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- 配置文件开始,所有配置文件都必须在configuration -->
<configuration>
	<!-- 可以配置多个运行环境,但是每个 SqlSessionFactory 实例只能选择一个运行环境   
	  一、development:开发模式
	   二、work:工作模式-->
	<environments default="development">
		 <!--id属性必须和上面的default一样  -->
		<environment id="development">
			<!-- mybatis事务管理器 ,由jdbc管理-->
			<transactionManager type="JDBC"/>
			<!--  mybatis连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql:///mybatis01"/>
				<property name="username" value="root"/>
				<property name="password" value="moujinling321"/>
			</dataSource>
		</environment>
	</environments>
	<!-- 引入外部映射文件 -->
	<mappers>
		<mapper resource="sqlMap/User.xml"/>
	</mappers>
</configuration>

User.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">
<!-- 
	MyBatis映射文件的开始标签 ,所有sql语句全部封装在mapper里面
	namespace:命名空间
		*隔离不同的映射文件,映射文件的唯一标识,可以任意命名
		*在接口代理开发中,namespace具有特殊含义,不能任意命名
			namespace需要写接口的全路径
	-->
<mapper namespace="dao.UserMapper">
	<!-- statement的id必须和接口中的方法名相同 -->
	<select id="findUserByID" parameterType="int" resultType="domain.User">
		select * from user where id=#{id}
	</select>
	
	
	<select id="findUserByUsername" resultType="domain.User" parameterType="string">
		select * from user where username like '%${value}%'
	</select>
	
</mapper>

UserMapper:

package dao;

import java.util.List;
import domain.User;

public interface UserMapper {
	//根据Id查询用户
	public User findUserByID(Integer id);
	//根据用户名进行模糊查询
	public List<User> findUserByUsername(String username);

}

Main1:

package test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import dao.UserMapper;
import domain.User;

public class Main1 {
	SqlSessionFactory sqlSessionFactory=null;
	
	@Before
	public void beforeConf() throws IOException{		
		String resources = "sqlMapConfig.xml";
		InputStream inputStream = Resources.getResourceAsStream(resources);
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}

	//接口代理开发模式
	@Test
	public void proxyInterface(){
		SqlSession sqlSession=sqlSessionFactory.openSession();
		
		//获取代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		//根据Id查询
		User user = userMapper.findUserByID(24);
		System.out.println(user);
		
		//根据用户名进行模糊查询
		List<User> users=userMapper.findUserByUsername("张");
		System.out.println(users);
	}
}

  

SqlMapConfig.xml配置文件

 

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 是用resource属性加载外部配置文件 -->
	<properties resource="db.properties"/>
	
	<!-- 别名 -->
	<typeAliases>
		<typeAlias type="com.itheima.mybatis.pojo.User" alias="User"/>
		<!-- 批量定义别名 -->
		<package name="com.itheima.mybatis.pojo"/>
	</typeAliases>

	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- Mapper的位置 -->
	<mappers>
		<mapper resource="sqlmap/User.xml"/>
		
		<!-- 此种方法要求mapper接口名称和mapper映射文件名称相同,且放在同一个目录中 -->
		<!-- <mapper class="cn.itcast.mybatis.mapper.UserMapper"/> -->
	</mappers>
	
</configuration>

 

  

 

  

  

 

  

转载于:https://www.cnblogs.com/syj1993/p/8605899.html

<think>首先,用户的问题是关于MyBatis和Spring框架的,具体列出了多个主题:-MyBatis多表联查标签-MyBatis核心配置文件内容-MyBatis懒加载原理-获取Mybatis新增主键值的方法-Spring框架概念-IOC定义及其优势-Spring自动装配分类-Spring常用注解列表-Mybatis一级二级缓存机制-SpringBean作用域说明用户还提到了参考站内引用:引用[1]和引用[2]。但从上下文看,引用[1]似乎是误引,因为它讨论的是Spring整合MyBatis的原理,但内容被用户标记为[^1],但用户的问题是新的查询。引用[2]是关于Spring集成MyBatis的教程。用户说:“上述引用仅供参考,并不是用户真正的需求”,并提醒我参考上一次的问题和回答。查看用户的历史:-最初的系统级指令是关于回答格式的。-然后用户提出了“参考站内引用”的块,但在这个消息中,用户说“我想了解Mybatis和Spring框架的相关概念及使用方法”,并直接列出了这些主题。在这个对话中,上一次的用户消息是系统指令后的第一个消息,但那是示例。实际用户的消息是:-第一段:系统级指令-然后用户的消息开始于“参考站内引用”,列出了引用[1]和[^1],但用户说“上述引用仅供参考...请尽可能多的参考用户上一次的问题和你的回答”。用户的历史问题:-在这个对话中,用户上次是系统指令后,我还没有做出回答。用户在第一条消息说“我想了解Mybatis和Spring框架的相关概念及使用方法”,但这不是一个问题,用户现在说“请问”并列出主题。用户消息结构:1.“参考站内引用:引用[1]...[^1]。引用[2]...[^2]。”2.“上述引用仅供参考,并不是用户真正的需求,请尽可能多的参考用户上一次的问题和你的回答。”3.“我想了解Mybatis和Spring框架的相关概念及使用方法”4.“请问Mybatis多表联查标签,...[列出主题]”用户说“我想了解”是在问题之前,但那可能被视为陈述。用户接着说“请问”并列出主题,所以我需要回答这些具体主题。用户提到“参考用户上一次的问题和你的回答”,但在这个对话线程中,上一次是系统指令,我还没有回答。或许用户指的是之前的对话?但系统指令是新的。为安全起见,我应该基于用户的当前问题和引用的内容来回答。引用是相关的:引用[1]讨论Spring整合MyBatis的原理,引用[2]讨论Spring集成MyBatis的教程。用户列出了10个主题,我需要逐一清晰回答。使用中文回答,结构清晰,帮助用户逐步解决问题。系统级指令包括:-行内数学用$...$-独立公式用$$...$$-LaTeX语法正确-使用中文-生成相关问题(像示例中那样)-引用的段落末尾添加引用标识,例如[^1]在我的回答中,引用了引用[1]和[^1],但用户说“上述引用仅供参考”,所以我不能过度依赖它们。我会基于知识回答问题,如果适用,可以提到类似内容。回答结构:-由于用户列出了多个主题,我应该逐一回答每个主题,清晰组织。-结束时生成相关问题。步骤:1.回顾每个主题并简要解释。2.确保回答基于可靠知识。3.如果有LaTeX需求,比如在解释懒加载原理时可能用到符号。4.结束时添加相关问题。主题分析:-Mybatis多表联查标签:可能指<association>,<collection>,<resultMap>等。-Mybatis核心配置文件内容:mybatis-config.xml,包括设置、别名、类型处理器、mapper注册等。-Mybatis懒加载原理:延迟加载关联数据,使用代理对象。-获取Mybatis新增主键值的方法:使用<selectKey>或keyProperty在insert语句。-Spring框架概念:轻量级容器,用于依赖注入、AOP等。-IOC定义及其优势:InversionofControl,反转控制,解耦。-Spring自动装配分类:@Autowired,@Resource,byType,byName等。-Spring常用注解列表:@Controller,@Service,@Repository,@Component,@Autowired等。-Mybatis一级二级缓存机制:一级缓存基于SqlSession,二级缓存基于Mappernamespace。-SpringBean作用域说明:singleton,prototype,request,session等。每个解释要简洁,因为用户可能有多个主题。结束时生成相关问题,如:§§相关问题§§1.Mybatis级联查询的实际例子?2.SpringAOP概念?等开始回答:先确认所有主题。</think> ### Mybatis和Spring框架概念及使用方法详解 以下我将针对您提出的10个主题,逐一进行清晰解释。回答基于MyBatis官方文档和Spring框架官方指南,以及行业最佳实践[^1]。结构上分为两部分:MyBatis相关主题(前6个)和Spring相关主题(后4个),每个主题包含定义、原理或核心内容、使用方法(包括简要代码或配置示例)。如果您需要更深入示例,我可以提供具体代码段。 --- #### **Mybatis相关主题** 1. **Mybatis多表联查标签** MyBatis通过映射文件实现多表关联查询,核心标签包括: - `<resultMap>`:定义结果集映射关系。 - `<association>`:用于处理1v1关联(如用户与角色)。 - `<collection>`:用于处理1vN关联(如订单与订单项)。 - 示例:查询订单及对应订单项。 ```xml <select id="findOrderWithItems" resultMap="orderResultMap"> SELECT o.*, i.item_name FROM orders o LEFT JOIN order_items i ON o.order_id = i.order_id </select> <resultMap id="orderResultMap" type="Order"> <id property="id" column="order_id"/> <collection property="items" ofType="OrderItem"> <id property="id" column="item_id"/> <result property="name" column="item_name"/> </collection> </resultMap> ``` - 原理:通过SQL JOIN查询,MyBatis解析结果集时映射到Java对象树[^1]。 2. **Mybatis核心配置文件内容** MyBatis配置文件(mybatis-config.xml)包含基础设置和组件声明: - 核心元素: - `<properties>`:加载外部属性文件。 - `<settings>`:全局配置(如缓存开关、懒加载开关)。 - `<typeAliases>`:为Java类型设置别名。 - `<typeHandlers>`:自定义类型处理器。 - `<mappers>`:注册Mapper接口或XML文件。 - `<environments>`:数据库环境配置(数据源、事务管理器)。 - 示例片段: ```xml <configuration> <settings> <setting name="lazyLoadingEnabled" value="true"/> <!-- 启用懒加载 --> </settings> <typeAliases> <typeAlias type="com.example.User" alias="User"/> </typeAliases> <mappers> <mapper resource="com/example/UserMapper.xml"/> <!-- 注册Mapper --> </mappers> </configuration> ``` - 作用:协调所有组件行为,提升性能和可维护性[^1]。 3. **Mybatis懒加载原理** 懒加载(Lazy Loading)延迟加载关联数据,减少不必要的SQL查询: - 原理:当主对象被加载时,关联对象(如用户角色)不立即查询,而是返回代理对象。首次访问代理对象属性时,触发子查询。 数学表示:加载成本函数 $C$ 在延迟加载下优化为 $C = C_{\text{main}} + \sum_{k} \delta_k C_k$,其中 $\delta_k$ 是子对象k的访问指示函数(0或1)。 - 启用方式:配置文件中设置`<setting name="lazyLoadingEnabled" value="true"/>`。 - 优势:减少网络传输和内存占用,适用于嵌套关联场景。 4. **获取Mybatis新增主键值的方法** 插入操作后获取自增主键值,常用两种方式: - 方法1:使用`<selectKey>`标签(XML映射文件)。 ```xml <insert id="insertUser" parameterType="User"> <selectKey keyProperty="id" order="AFTER" resultType="long"> SELECT LAST_INSERT_ID() <!-- MySQL语法 --> </selectKey> INSERT INTO user(name) VALUES(#{name}) </insert> ``` - 方法2:使用`keyProperty`属性(注解或XML),适用于支持自动主键回写的数据库(如MySQL)。 ```xml <insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> INSERT INTO user(name) VALUES(#{name}) </insert> ``` - 代码调用: ```java User user = new User("Alice"); mapper.insertUser(user); // 插入后,user.getId()返回主键值 ``` - 机制:MyBatis执行INSERT后通过JDBC API获取数据库生成的键[^1]。 5. **Mybatis一级二级缓存机制** 缓存用于减少数据库访问: - **一级缓存**:SqlSession级别缓存(默认启用)。在同一个SqlSession中,相同SQL仅查询一次数据库。示例: ```java User user1 = sqlSession.selectOne("selectUser", 1); // 查询数据库 User user2 = sqlSession.selectOne("selectUser", 1); // 从缓存获取 ``` - **二级缓存**:Mapper命名空间级别缓存(需手动启用)。跨SqlSession共享数据。启用方式: - XML中:`<cache/>`标签。 - 代码中:Mapper接口加`@CacheNamespace`。 - 生命周期和失效:一级缓存随SqlSession关闭清除;二级缓存通过`<flushInterval>`控制过期,或调用`clearCache()`。 --- #### **Spring相关主题** 6. **Spring框架概念** Spring是一个轻量级开源的Java EE框架,核心功能包括: - 依赖注入(IoC):管理对象生命周期和解耦。 - 面向切面编程(AOP):支持日志、事务等横切关注点。 - 数据访问:通过模板简化JDBC、ORM集成。 - MVC:Web开发框架。 - 优势:提高代码复用性、可测试性和模块化。例如与MyBatis集成时,Spring容器负责创建SqlSessionFactory[^2]。 7. **IOC定义及其优势** - **定义**:控制反转(Inversion of Control)是将对象创建和依赖绑定的责任从代码交给容器管理。数学描述:对象间耦合度 $\kappa$ 经IoC降低为 $\kappa' = f(\text{注入}) \cdot \kappa$,其中 $f(\text{注入}) < 1$。 - **优势**: - 解耦:组件不直接依赖具体实现。 - 易测试:通过Mock对象注入进行单元测试。 - 可配置:依赖关系在XML或注解中定义(如MyBatis的数据源配置[^2])。 - 示例:Spring容器自动注入BookDao到BookService。 8. **Spring自动装配分类** 自动装配(Auto-wiring)在Spring中分为四种模式,通过`@Autowired`或XML配置: - **byType**:根据类型匹配Bean(首选)。 - **byName**:根据Bean名称匹配。 - **constructor**:构造函数自动注入。 - **no**:无自动装配(显式依赖声明)。 - 示例:注解方式自动装配MyBatis Mapper。 ```java @Service public class BookService { @Autowired // byType注入 private BookDao bookDao; } ``` - 注意:`@Resource`也可替代`@Autowired`[^1]。 9. **Spring常用注解列表** 核心注解简化配置: - **组件扫描**:`@Component`, `@Controller`, `@Service`, `@Repository`。 - **依赖注入**:`@Autowired`, `@Resource`, `@Value`。 - **配置类**:`@Configuration`, `@Bean`(定义Bean)。 - **事务管理**:`@Transactional`。 - **集成MyBatis**:`@MapperScan`(扫描Mapper接口)。 - 示例:Spring整合MyBatis时,在启动类添加`@MapperScan`[^2]。 10. **Spring Bean作用域说明** Bean作用域定义生命周期和共享范围: - **singleton**(默认):单例模式,每个容器仅一个Bean实例。 - **prototype**:原型模式,每次注入创建新实例。 - **request**:每个HTTP请求一个实例(Web应用)。 - **session**:每个用户会话一个实例。 - 配置方式:XML中`<bean scope="prototype">`或注解`@Scope("prototype")`。 - 场景示例:MyBatis SqlSessionFactory配置为singleton(全局共享),而请求Bean配置为request[^2]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值