【MyBatis框架】MyBatis入门程序第二部分

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
云数据库 RDS MySQL,高可用系列 2核4GB
简介:
我们通过写一个简单的MyBatis小项目来在实战中学习MyBatis,接着上一篇继续

我们开始实现需求中的添加和删除用户功能

(1)向数据库中添加用户数据
使用User.xml,加入添加用户的sql语句。
<!-- 添加用户
parameterType:指定输入参数类型是pojo(包括用户信息) 
#{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis通过OGNL获取对象的属性
-->
<insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User">
	insert into user(username,birthday,sex,address) value(#{username}.#{birthday,jdbcType=DATE}.#{sex},#{address})
</insert>

*注:在字段中有Date和DateTime类型,在插入数据时只要将实体的属性设置成Timestamp就会对应mysql的DateTime类型,Date会对应mysql的Date类型:
#{modified_date,jdbcType=TIMESTAMP}、#{date,jdbcType=DATE}。

测试方法:
//添加用户
	@Test
	public void insertUserTest(){
		
		//mybatis配置文件
		String resource="SqlMapConfig.xml";
		
		//将配置文件加载成流
		InputStream inputStream;
		
		try {
			
			inputStream = Resources.getResourceAsStream(resource);
			//创建会话工厂,传入mybatis配置文件的信息
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			
			//通过工厂得到sqlSession
			sqlSession=sqlSessionFactory.openSession();
			
			//插入用户对象
			User user=new User();
			user.setUsername("李云华");
			user.setBirthday(new Date());
			user.setSex("男");
			user.setAddress("云南大理");
			//通过SqlSession操作数据库
			//第一个参数:映射文件中的statement的Id,等于=namespace+"."+statement的Id
			//第二个参数:指定和映射文件所匹配的parameterType类型的参数
			//sqlSession.selectOne最终结果与你映射文件中所匹配的resultType类型
			sqlSession.insert("test.insertUser",user);
			
			//提交事务
			sqlSession.commit();
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			//释放资源
			sqlSession.close();
		}
		
	}

测试结果:
在数据库中插入了
李云华(String), 2015-06-07(Date), 男(String), 云南大理(String)

输出的日志信息:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 30685694.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - ==>  Preparing: insert into user(username,birthday,sex,address) value(?,?,?,?) 
DEBUG [main] - ==> Parameters: 李云华(String), 2015-06-07(Date), 男(String), 云南大理(String)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Returned connection 30685694 to pool.

(2)主键返回

a.自增主键的返回
mysql的自增主键,执行insert之前自动生成一个自增主键
通过mysql函数获取到刚插入记录的自增主键
LAST_INSERT_ID
(当插入一个数据后,立即用这个函数就会返回刚加的主键:SELECT LAST_INSERT_ID())

在刚刚的User.xml中这么写:
<!-- 添加用户
parameterType:指定输入参数类型是pojo(包括用户信息) 
#{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis通过OGNL获取对象的属性
-->
<insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User">
	<!-- 将插入数据的主键返回,返回到user对象中。
	SELECT_INSERT_ID():得到刚insert进去的主键值,只适用于自增主键 
	KeyProperty:将查询到主键值设置到parameterType指定对象的哪个属性。
	order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
	-->
	<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
		SELECT LAST_INSERT_ID()
	</selectKey>
	insert into user(username,birthday,sex,address) value(#{username},#{birthday,jdbcType=DATE},#{sex},#{address})
</insert>

我们在刚刚的方法后面输出user的ID
//插入用户对象
User user=new User();
user.setUsername("李云华");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("云南大理");
//通过SqlSession操作数据库
//第一个参数:映射文件中的statement的Id,等于=namespace+"."+statement的Id
//第二个参数:指定和映射文件所匹配的parameterType类型的参数
//sqlSession.selectOne最终结果与你映射文件中所匹配的resultType类型
sqlSession.insert("test.insertUser",user);
			
//提交事务
sqlSession.commit();
			
System.out.println(user.getId());

结果:6
为啥能得到,就是在配置文件里设置了当insert完成之后就把id取出来存到user对象中

b.非自增主键的返回
使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。

执行思路:
先通过uuid()查询到主键,将主键输入到sql语句中。

执行uuid()语句顺序相对于insert语句之前执行。

在刚刚的User.xml中这么写:
<!-- 使用MySql的UUID来生成主键
		执行过程:
		首先通过uuid()得到主键,将主键设置到user对象的id属性中
		其次在insert执行时,从user对象中取出id属性值 -->
		<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT uuid()
		</selectKey>
		insert into user(id,birthday,sex,address) value(#{id},#{birthday,jdbcType=DATE},#{sex},#{address})

如果使用的数据库是oracle那么通过oracle的序列生成主键写法:
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT 序列名.nextval()
</selectKey>
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday,jdbcType=DATE},#{sex},#{address})

测试略

(3)删除和更新用户
映射文件User.xml中添加的语句:
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
	delete from user where id=#{id}
</delete>
	
<!-- 更新用户 
分析:
需要传入用户的id,需要传入用户的更新信息.
parameterType指定user对象,包括id和更新信息(注意:id必须存在)
#{id}:从输入user对象中获取id属性值-->
<update id="updateUser" parameterType="cn.edu.hpu.mybatis.PO.User">
	update user set username=#{username},birthday=#{birthday,jdbcType=DATE},sex=#{sex},address=#{address} 	
        where id=#{id}
</update>

测试代码:
删除测试代码:
//删除用户
	@Test
	public void deleteUserTest(){
		
		//mybatis配置文件
		String resource="SqlMapConfig.xml";
		
		//将配置文件加载成流
		InputStream inputStream;
		
		try {
			
			inputStream = Resources.getResourceAsStream(resource);
			//创建会话工厂,传入mybatis配置文件的信息
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			
			//通过工厂得到sqlSession
			sqlSession=sqlSessionFactory.openSession();
			
			//传入id删除用户
			sqlSession.delete("test.deleteUser",6);
			
			//提交事务
			sqlSession.commit();
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			//释放资源
			sqlSession.close();
		}
		
	}
	

测试结果:从数据库删除了id为6的数据

输出日志:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 30685694.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - ==>  Preparing: delete from user where id=? 
DEBUG [main] - ==> Parameters: 6(Integer)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Returned connection 30685694 to pool.

更新测试代码:
	//更新用户
	@Test
	public void updateUserTest(){
		
		//mybatis配置文件
		String resource="SqlMapConfig.xml";
		
		//将配置文件加载成流
		InputStream inputStream;
		
		try {
			
			inputStream = Resources.getResourceAsStream(resource);
			//创建会话工厂,传入mybatis配置文件的信息
			SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
			
			//通过工厂得到sqlSession
			sqlSession=sqlSessionFactory.openSession();
			
			//更新用户信息(更改id=5的用户数据)
			User user=new User();
			user.setId(5);
			user.setUsername("刘三姐");
			user.setBirthday(new Date());
			user.setSex("女");
			user.setAddress("云南大理");
			sqlSession.update("test.updateUser",user);
			
			//提交事务
			sqlSession.commit();
			
		} catch (IOException e) {
			e.printStackTrace();
		}finally{
			//释放资源
			sqlSession.close();
		}
		
	}

测试结果:
id=5的数据被更新

输出日志:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 30685694.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - ==>  Preparing: update user set username=?,birthday=?,sex=?,address=? where id=? 
DEBUG [main] - ==> Parameters: 刘三姐(String), 2015-06-07(Date), 女(String), 云南大理(String), 5(Integer)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.Connection@1d439fe]
DEBUG [main] - Returned connection 30685694 to pool.

小结:
a.parameterType
在映射文件中通过parameterType指定输入 参数的类型。

b.resultType
在映射文件中通过resultType指定输出结果的类型。

c.#{}和${}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,#{}中可以写成value或其它名称。
#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。


${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。
如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

d.selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。

selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。

如果使用selectOne报错:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4



最后来说说hibernate与mybatis,大家如果用过hibernate,刚学mybatis就会很疑惑,mybatis的执行效率并不比hibernate高多少,而且还要多写sql语句,为什么要用它呢?下面来看一下它们的区别,你就会明白mybatis的存在是有一定道理的

看看 mybatis和hibernate本质区别和应用场景:

hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。
对sql语句进行优化、修改比较困难的。
应用场景:
适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。
应用场景:
适用与需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本 高回报作为技术选型的原则,根据项目组的技术力量进行选择。


转载请注明出处:http://blog.csdn.net/acmman/article/details/46455411

相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
16天前
|
SQL Java 数据库连接
持久层框架MyBatisPlus
持久层框架MyBatisPlus
33 1
持久层框架MyBatisPlus
|
1月前
|
前端开发 Java Apache
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
本文详细讲解了如何整合Apache Shiro与Spring Boot项目,包括数据库准备、项目配置、实体类、Mapper、Service、Controller的创建和配置,以及Shiro的配置和使用。
319 1
Springboot整合shiro,带你学会shiro,入门级别教程,由浅入深,完整代码案例,各位项目想加这个模块的人也可以看这个,又或者不会mybatis-plus的也可以看这个
|
1月前
|
SQL Java 数据库连接
Mybatis入门(select标签)
这篇文章介绍了Mybatis中`select`标签的基本用法及其相关属性,并通过示例展示了如何配置和执行SQL查询语句。
41 0
Mybatis入门(select标签)
|
30天前
|
缓存 Cloud Native 安全
探索阿里巴巴新型ORM框架:超越MybatisPlus?
【10月更文挑战第9天】在Java开发领域,Mybatis及其增强工具MybatisPlus长期占据着ORM(对象关系映射)技术的主导地位。然而,随着技术的发展,阿里巴巴集团推出了一种新型ORM框架,旨在提供更高效、更简洁的开发体验。本文将对这一新型ORM框架进行探索,分析其特性,并与MybatisPlus进行比较。
30 0
|
3月前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
3月前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
187 0
|
3月前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
40 0
|
3月前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
341 0
|
3月前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(5、分页)
这篇文章介绍了如何在MyBatis框架中实现分页功能,包括使用SQL的`limit`语句进行分页和利用MyBatis的`RowBounds`对象进行分页的方法。
|
1月前
|
Java 数据库连接 Maven
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和MyBatis Generator,使用逆向工程来自动生成Java代码,包括实体类、Mapper文件和Example文件,以提高开发效率。
113 2
mybatis使用一:springboot整合mybatis、mybatis generator,使用逆向工程生成java代码。