mybatis学习:二、 Mybatis的Dao开发、mybatis-config.xml文件的详情

news2024/11/28 0:42:51

3. Mybatis的Dao开发

​ 使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。

3.1 Mybatis的核心对象

  • SqlSessionFactoryBuilder

    ​ SqlSessionFactoryBuilder用于创建SqlSessionFacoty,SqlSessionFacoty一旦创建完成就不需要SqlSessionFactoryBuilder了,因为SqlSession是通过SqlSessionFactory生产,所以可以将SqlSessionFactoryBuilder当成一个工具类使用,最佳使用范围是静态代码块中的局部变量

  • SqlSessionFactory

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

  • SqlSession

  1. SqlSession是一个面向用户的接口, sqlSession中定义了数据库操作,默认使用DefaultSqlSession实现类。

  2. SqlSession的实现类即DefaultSqlSession,此对象中对操作数据库实质上用的是Executor

  3. 每个线程都应该有它自己的SqlSession实例。SqlSession的实例不能共享使用,它也是线程不安全的。因此最佳的范围是请求或方法范围。绝对不能将SqlSession实例的引用放在一个类的静态字段或实例字段中。
    4. 打开一个 SqlSession;使用完毕就要关闭它。通常把这个关闭操作放到 finally 块中以确保每次都能执行关闭。

3.2 传统的DAO开发模式

​ 程序员需要写dao接口和dao实现类。

​ 需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

步骤:

  1. 编写到接口以及实现类
import java.util.List;

public interface IUserDao {
	/**
	 * 根据ID查询User
	 * @param id  用户Id
	 * @return  用户信息
	 * @throws Exception
	 */
	public User findUserById(int id) throws Exception;
	
	/**
	 * 根据用户的名字模糊查询
	 * @param name 用户的username
	 * @return  一组用户
	 * @throws Exception
	 */
	public List<User> findUserByName(String name) throws Exception;
	
	/**
	 * 添加用户
	 * @param user 用户信息
	 * @return 包含主键的用户
	 * @throws Exception
	 */
	public User addUser(User user) throws Exception;
}


public class UserDaoImpl implements IUserDao {
	//需要往UserDaoImpl注入SQLSessionFactory
	private SqlSessionFactory sqlSessionFactory;
	
	//通过构造方法注入
	public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
		this.sqlSessionFactory = sqlSessionFactory;
	}

	@Override
	public User findUserById(int id) throws Exception {
		/**
		 * 1.得到SqlSession
		 * 2.调用SqlSession对应的方法(selectOne)来操作数据库
		 * 3.关闭SqlSession
		 * 4.返回结果
		 */
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user = sqlSession.selectOne("test.findUserById", id);
		sqlSession.close();
		return user;
	}

	@Override
	public List<User> findUserByName(String name) throws Exception {
		/**
		 * 1.得到SqlSession
		 * 2.调用SqlSession对应的方法(selectList)来操作数据库
		 * 3.关闭SqlSession
		 * 4.返回结果
		 */
		SqlSession sqlSession = sqlSessionFactory.openSession();
		List<User> users = sqlSession.selectList("test.findUserByName", "%"+name+"%");
		sqlSession.close();
		return users;
	}

	@Override
	public void addUser(User user) throws Exception {
		/**
		 * 1.得到SqlSession
		 * 2.调用SqlSession对应的方法(insert)来操作数据库
		 * 3.提交事务
		 * 4.关闭SqlSession
		 */
		SqlSession sqlSession = sqlSessionFactory.openSession();
		sqlSession.insert("test.addUser", user);
		sqlSession.commit();
		sqlSession.close();
	}
}
  1. 编写SQL映射文件

    <!-- 根据ID查询 -->
    <select id="findUserById" parameterType="int" resultType="org.csmf.mybatis.entity.User">
    		select * from t_user where id = #{id}
    </select>
    <!-- 根据姓名模糊查询 -->
    <select id="findUserByName" parameterType="string" resultType="org.csmf.mybatis.entity.User">
    		select * from t_user where username like #{name}
    </select>
    <!—添加用户-->
    <insert id="addUser" parameterType="org.csmf.mybatis.entity.User">
    		<selectKey order="AFTER" resultType="int" keyProperty="id">
    			select last_insert_id()
    		</selectKey>
    		insert into t_user(username,password,sex,brithday,address) 
    			values(#{username},#{password},#{sex},#{brithday},#{address})
    </insert>
    

总结:

原始Dao开发中存在以下问题:

  • Dao方法体存在重复代码:通过SqlSessionFactory创建SqlSession,调用SqlSession的数据库操作方法

  • 调用sqlSession的数据库操作方法需要指定statement的id,这里存在硬编码,不得于开发维护。

3.3 Mapper代理模式

​ Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

  1. 在mapper.xml中namespace写的是对应Mapper接口的全限定名

>   [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vzXBi4kN-1669618738987)(assets/image-20220806114843395.png)]

  1. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同

  2. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
    在这里插入图片描述

实现:

UserMapper.xml:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ahqabpln-1669618738989)(assets/wps1.jpg)]

UserMapper接口:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IwjOA0D4-1669618738991)(assets/wps2.jpg)]

测试代码:

import java.io.IOException;
import java.io.InputStream;

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.csmf.mybatis.entity.User;
import org.junit.Before;
import org.junit.Test;

/**
 * 测试UserMapper的测试类
 * @author pactera
 *
 */
public class UserMapperTest {
	private SqlSessionFactory sqlSessionFactory;
	@Before
	public void setUp(){
		InputStream inputStream = null;
		try {
			inputStream = Resources.getResourceAsStream("mybatis-config.xml");
		} catch (IOException e) {
			e.printStackTrace();
		}
		sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	}
	@Test
	public  void testFindUserById() throws Exception{
		SqlSession sqlSession = sqlSessionFactory.openSession();
		//创建UserMapper的休息,Mybatis可以自动生成UserMapper接口的代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		User user = userMapper.findUserById(2);
		System.out.println(user);
	}
}

总结:

  • selectOne和selectList

动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。

  • namespace

mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用包装类或map对象,保证dao的通用性。

4. mybatis-config.xml文件的详情

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

properties(属性) 加载properties文件

settings(全局配置参数) 缓存

typeAliases(类型别名) 类型别名

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件) 通用Mapper 分页插件

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

4.1 properties属性

​ 在实际开发中,我们通常会将数据库连接参数单独配置在db.properties中,只需要在mybatis-config.xml中加载db.properties的属性值。这样我们在mybatis-config.xml中就不需要对数据库连接参数硬编码。

​ 将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。

db.properties文件:

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root

mybatis-config.xml引用properties文件:

	<!-- 加载properties文件 -->
	<properties resource="db.properties"></properties>
	<!-- 和spring整合后 environments配置将废除-->
	<environments default="development">
		<!-- 可以配置多个environment -->
		<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>

4.2 settings全局参数配置

​ mybatis框架在运行时可以调整一些运行参数。

​ 比如:开启二级缓存、开启延迟加载。

全局参数将会影响mybatis的运行行为。

配置选项描述可选值默认值
cacheEnabled全局启用或禁用任何Mapper中配置的缓存true|falsetrue
lazyLoadingEnabled全局启用或禁用延迟加载。当启用后,所有的关系都将被延迟加载。可以通过使用特定关系上的fetchType属性来取代该值。true|falsefalse
aggressiveLazyLoading当启用时,具有惰性加载属性的对象将完全在调用任何惰性属性时加载。否则,每个属性都将按需加载。true|falsetrue
multipleResultSetsEnabled允许或不允许从单个语句返回多个结果集(需要兼容的驱动程序)true|falsetrue
useColumnLabe使用列标签,而不是列名称。不同的驱动程序在这方面的行为也有所不同。请参考驱动程序文档,或测试这两种模式,以确定驱动程序的行为方式。true|falsetrue
useGeneratedKeys允许JDBC支持已生成的密钥。这时需要一个兼容的驱动程序。这个设置强制生成的键在设置为true时使用,因为一些驱动程序拒绝兼容性但仍然可以工作(例如Derby)。true|falsefalse
autoMappingBehavior指定MyBatis是否以及如何自动将列映射到字段/属性。NONE禁用自动映射。PARTIAL只自动映射简单,非嵌套的结果集。FULL将自动映射任何复杂度的结果集(包含嵌套或非嵌套的)。NONE, PARTIAL, FULLPARTIAL
defaultExecutorType配置默认的执行器(Executor):
SIMPLE: 简单执行器
REUSE:重用prepared statement的执行器
BATCH:重用statement并且执行批量更新的执行器
SIMPLE REUSE BATCHSIMPLE
defaultStatementTimeout设置数据库超时时间(单位:秒)任何正数Not Set (null)
safeRowBoundsEnabled允许在嵌套语句上使用行边界。true|falsefalse
mapUnderscoreToCamelCase是否开启, 数据库列:A_COLUMN自动映射为属性:aColumntrue|falsefalse
localCacheScopeMyBatis使用本地缓存来提高查询效率,本地缓存默认Scope是:SESSION, 在同一次SESSION期间执行的所有查询都将被缓存.
localCacheScope=STATEME:本地会话将仅用于stateme的执行,对同一Sql会话的两个不同调用之间将不共享任何数据
SESSION|STATEMENTSESSION
jdbcTypeForNull指定空值的JDBC类型,当没有为参数提供特定的JDBC类型时。一些驱动程序需要指定列JDBC类型,常用的值:NULL,VARCHAR,OTHERJdbcType enumeration.Most common are: NULL,VARCHAR and OTHEROTHER
lazyLoadTriggerMethods指定哪个对象的方法会触发延迟加载方法名列表,多个方法名之间使用逗号分割equlas,
clone,
hashCode,
toString
defaultScriptingLanguage指定动态SQL生成时默认使用的语言。一个类型的别名或完全限定的类名。
callSettersOnNulls指定在检索到的值为空时,是否会调用设置器或映射的put方法。当您依赖于Map.keySet()或空值初始化时,它很有用。请注意原语,如(int、布尔值等)。将不会被设置为null。true|falsefalse
logPrefix指定MyBatis将添加到日志记录器名称中的前缀字符串。任何字符串未设置
logImpl指定MyBatis应该使用哪些日志记录实现类。如果此设置日志记录类不存在,则将自动发现日志记录实现。SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING为设置
proxyFactory代理工厂指定MyBatis将用于创建能够实现延迟加载功能的对象的代理工具。CGLIB|JAVASSISTCGLIB

4.3 typeAliases(类型别名)

4.3.1 mybatis支持别名:

别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerint
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dateDate
decimalBigDecimal
bigdecimalBigDecimal

4.3.2 自定义别名:

在mybatis-config.xml中配置:

<typeAliases>
	<!-- 单个别名定义 -->
	<typeAlias alias="user" type="org.csmf.mybatis.entity.User"/>
	<!-- 批量别名定义,扫描整个包下的类,别名为类名(首字母大写或小写都可以) -->
	<package name=" org.csmf.mybatis.entity "/>
	<package name="其它包"/>
</typeAliases>

使用别名:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nR6V6bm3-1669618738993)(assets/wps3.jpg)]

4.4 mappers(映射器)

Mapper配置的几种方法:

  • <mapper resource=" " />

使用相对于类路径的资源

如:<mapper resource="sqlmap/User.xml" />

  • <mapper url=" " />

使用完全限定路径

如:<mapper url="file:///D:\workspace_spingmvc\mybatis_01\config\sqlmap\User.xml" />

  • <mapper class=" " />

使用mapper接口类路径

如:<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>

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

  • <package name=""/>

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

如:<package name="org.csmf.mybatis.dao"/>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/49678.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

nginx学习使用

nginx学习使用一、nginx安装与使用1、linux安装2、linux卸载3、升级4、linux环境下&#xff0c;把nginx设置为开启自启动二、nginx常用命令1、部署命令2、其他命令三、配置文件解析1、系统配置2、各配置指令详解3、日志配置4、跟据上面的命令&#xff0c;实现一个代理配置案例5…

2022FW柯罗芭KLOVA 用极简主义演绎服装美学

万物伊始&#xff0c;一切都是最简单的&#xff0c;后疫情时代&#xff0c;时尚似乎也开始化繁为简&#xff0c;回归本真。LESS IS MORE 诉说着真实的高贵&#xff0c;从不喧哗&#xff0c;服装里讲究的极简风&#xff0c;正是当下时尚和生活方式的最佳体现。 款式极简 极简又高…

Spring Boot中添加Thymeleaf模板

Spring Boot中添加Thymeleaf模板 前面我们讲解了Spring Boot项目的创建、Spring Boot结构信息&#xff0c;自动配置功能等&#xff0c;那么Springboot创建出来&#xff0c;我们最终是要做web开发的&#xff0c;所以我们这章讲解如何用SpringBoot做web开发。 一. Web开发方式 …

Maven 高级篇,Maven常用操作、高级操作、nexus私服搭建

&#x1f600;&#x1f600;&#x1f600;创作不易&#xff0c;各位看官点赞收藏. Maven 高级篇 文章目录Maven 高级篇1、Maven 安装2、Maven 核心概念2.1、坐标2.2、基础操作2.3、依赖2.4、继承2.5、生命周期3、Maven 深入3.1、Spring Boot 打包3.2、超级 POM3.3、build 标签…

计算机网络第八章知识点回顾(自顶向下)

1. 网络安全 1.1 什么是网络安全&#xff1f; 1.2网络中的通信安全 1.2.1 安全攻击的类型&#xff1a;被动攻击 1.2.2 安全攻击的类型&#xff1a;主动攻击 1.3 常见的安全机制 2. 密码学术语 2.1 密码学术语&#xff08;图示&#xff09; 2.2加密算法的分类 2.3 传统加密方法&…

专访D-Wave CEO:量子计算的过去、现在和未来

&#xff08;图片来源&#xff1a;网络&#xff09; 量子计算可能成为一项颠覆性技术&#xff1a;它建立在听起来非常奇特的物理学基础上&#xff0c;并有望以前所未有的速度和效率解决某些类别的问题。一些人认为&#xff0c;目前在量子计算领域的承诺太多&#xff0c;交付却不…

【wms平台化】一个简单的wms九表架构

仓库管理软件的未来有几个方向&#xff1a;平台化、行业化、一体化、精简化。 然而其中行业化跟精简化&#xff0c;其实都离不开平台化。 也就是说&#xff0c;不论wms软件如何发展&#xff0c;唯有平台化一择。 在本人从事的传统型wms项目中&#xff0c;对于库存的定义是【在…

ch1_系统启动_setup.S

1 功能分析 大写的.s 后缀名&#xff0c; 是为了说明是一个16位&#xff0c; 实模式下的汇编语言&#xff0c; 小写的 s 是保护模式下的汇编语言&#xff1b; 1.1 使用中断&#xff0c;读取机器参数 setup.S 是一个操作系统的加载程序&#xff0c; 主要作用使用 ROM BIOS 中…

我为什么拒绝了一个5年测开经验的候选人

某互联网大厂的测试开发岗位招聘时&#xff0c;收到一位 5 年测试开发经验的候选人&#xff0c;是南京大学软件学院的硕士&#xff0c;毕业后一直在国内的互联网巨头公司从事测试框架和工具平台的开发工作。 他简历中参与开发过的测试框架和工具和当时该公司在做的项目很匹配&…

一. 编程规则

命名风格 1.不能以下划线或美元符号开头或结尾,不许使用中英文混合的模式命名. 2.必须使用驼峰命名,DO/BO/DTP/Vo/AO例外 3.常量名全部大写,单词用下划线隔开 4.抽象命名使用Abstract或Base开头,异常命名使用Exception结尾,测试类以Test结尾,枚举类名带上Enum后缀,枚举成员…

认真学习MySQL的事务日志-Redo日志

事务有4种特性&#xff1a;原子性、一致性、隔离性和持久性。那么事务的四种特性到底是基于什么机制实现呢&#xff1f; 事务的隔离性由锁机制执行。事务的原子性、一致性和持久性由事务的redo日志和undo日志来保证。 redo log称为重做日志&#xff0c;提供再写入操作&#x…

考研数据结构大题整合_组一(ZYL组)_做题版

考研数据结构大题整合 目录考研数据结构大题整合一、ZYL组ZYL组一ZYL组二ZYL组三ZYL组四ZYL组五ZYL组六ZYL组七ZYL组八一、ZYL组 ZYL组一 1.一棵树有度为i的结点ni 个(i1,2,3,…m), 求叶结点的个数.&#xff08;10分&#xff09; ∑i1m(ni∗i)1−∑i1m(ni)\sum_{i1}^m(n_i *i…

C++单例模板:使用宏函数实现

C单例模板&#xff1a;使用宏函数实现 在我们日常开发中&#xff0c;无可避免需要使用单例模式进行设计类对象&#xff0c;那么实际上我们写单例格式基本都是一样的&#xff0c;那么每次都要写几乎一模一样的代码来实现我们需要的单例对象是不是会觉得很累&#xff1f;下面博主…

新体验经济@2022: 世界杯、啤酒与供应链

【潮汐商业评论/原创】 四年后&#xff0c;世界杯再一次刷屏&#xff0c;绿茵场上挥洒着汗水与泪水&#xff0c;而绿茵场下的观众们也在对诸如“馄饨皮”、“卡塔尔小王子”和球队输赢等话题展开着热烈地讨论。 这其中当然也包括Hans&#xff0c;Hans是一名忠实的足球球迷&am…

mapper-reducer编程搭建

一.虚拟机安装CentOS7并配置共享文件夹 二.CentOS 7 上hadoop伪分布式搭建全流程完整教程 三.本机使用python操作hdfs搭建及常见问题 四.mapreduce搭建 五.mapper-reducer编程搭建 mapper-reducer编程搭建一、打开hadoop二、创建mapper.py、reducer.py及参数文件1.创建 mapper.…

Android Framework 如何学习,如何从应用深入到Framework?

1、为什么要学Android Framework呢&#xff1f; 一方面&#xff0c;面试考察相关内容的可能性高。随着Android开发者越来越多&#xff0c;企业对Android程序员的筛选也有了更高的要求&#xff0c; 考察对Android底层逻辑的理解和思考就是很重要的一个方面&#xff0c;尤其是An…

遥感测深方法综述(一)遥感测深方兴未艾

众所周知&#xff0c;当前世界上许多沿海近岸区域的海图数据更新滞后&#xff0c;甚至直接空白&#xff0c;大约有50%的沿海国家不具备国家级海图制图能力&#xff0c;特别是发展中国家常缺乏足够的水深数据或海图&#xff0c;总体上的浅海测深和制图能力处于从“贫乏”到“具备…

智慧社区管理系统08(维修和柱状图显现)

目录 后端代码 实体类 mapper层 mappers sql语句 Service层 接口 实现类 Controller层 前端部分 列表显示 后端代码 实体类 package com.woniu.community.entity;import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor;Data…

跨境电商:圣诞前的狂欢,超级星期六营销白皮书

“黑五”和“网一”的促销大戏终于告一段落了。Nox聚星获悉&#xff0c;Adobe Analytics的初步统计显示&#xff0c;美国购物者在今年黑色星期五的线上支出达到创纪录的91.2亿美元&#xff0c;增长2.3%。今年的市场表现比预期的要好&#xff0c;对跨境卖家而言&#xff0c;是个…

01-Maven高级

回顾 知识目标 第一单元、父子工程 1、为什么使用父子工程&#xff1f; 1.1、痛点1&#xff1a;提高了代码的重用性 父控制器的存在就是为了去除重复&#xff0c;一个项目存在多个模块&#xff0c;可能由多个人开发&#xff0c;比如abc3个模块&#xff0c;3个模块都是基于…