单表的CRUD。 C:Create,创建;R:Retrieve,读取;U:Update,更新;D,Delete,删除。
1. 首先配置映射文件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"> <mapper namespace="com.alex.app.entity.User"> <select id="selectUser" parameterType="int" resultType="com.alex.app.entity.User"> select * from t_user where id = #{id} </select> <insert id="insertUser" parameterType="com.alex.app.entity.User"> insert into t_user(username,password) values(#{username},#{password}) </insert> <update id="updateUser" parameterType="com.alex.app.entity.User"> update t_user set username=#{username},password=#{password} where id = #{id} </update> <delete id="deleteUser" parameterType="int"> delete from t_user where id = #{id} </delete> </mapper>
2. 先提供一个工具类,方便测试
package com.alex.app.util; 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; public class MyBatisUtil { private MyBatisUtil() { } private static SqlSessionFactory factory; private static String configFile = "mybatis-config.xml"; static{ InputStream in; try { // 加载总配置文件 in = Resources.getResourceAsStream(configFile); // 创建SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); } catch (IOException e) { e.printStackTrace(); } } /** * 获取SqlSession,并关闭自动提交,打开事务。 * 通俗点说就是将自动提交事务,改为手动提交 * @return */ public static SqlSession openSession(){ return factory.openSession(); } /** * 关闭session * @param session */ public static void coloseSession(SqlSession session){ if(session != null){ session.close(); } } }
SqlSession创建的时候,会关闭自动提交,打开事务。我们扫一眼SqlSessionFactory的openSessoin方法的源码就知道了。
以下源码分析不是重点,可以略过
eclipse中,使用 maven构建的项目要把源码一并下载下来,右击pom.xml选择Run As-->Maven Build..,在对话框Goals中输入命令dependency:sources,点Run,相关maven的插件和源码就都下载下来。
源码已经关联上,图标上有了个文本的标识
SqlSessionFactory是个接口,这里调用到的是DefaultSqlSessionFactory实现类的openSessoin方法。
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }我们看到第4个参数的值就是false。往里看代码直到JdbcTransaction类中,构造方法有
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) { dataSource = ds; level = desiredLevel; autoCommmit = desiredAutoCommit; }flase这个值会传递给JdbcTransaction构造方法的desiredAutoCommit,设置了autoCommmit 这个值为false。
那么肯定有地方调用了这个构造方法,在哪里呢,是在SqlSessoin调用insert/update/delete方法的时候
public int insert(String statement, Object parameter) { return update(statement, parameter); }调用了update(statement, parameter)
public int update(String statement, Object parameter) { try { dirty = true; MappedStatement ms = configuration.getMappedStatement(statement); return executor.update(ms, wrapCollection(parameter)); } catch (Exception e) { throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } }继续往里跟executor.update(ms, wrapCollection(parameter));直到BatchExecutor类的doUpdate方法
public int doUpdate(MappedStatement ms, Object parameterObject) throws SQLException { //.....省略这些代码,节省篇幅 if (sql.equals(currentSql) && ms.equals(currentStatement)) { //.....省略这些代码,节省篇幅 } else { Connection connection = getConnection(ms.getStatementLog()); stmt = handler.prepare(connection); //.....省略这些代码,节省篇幅 } //.....省略这些代码,节省篇幅 }其中有一句代码是Connection connection = getConnection(ms.getStatementLog());
protected Connection getConnection(Log statementLog) throws SQLException { Connection connection = transaction.getConnection(); if (statementLog.isDebugEnabled()) { return ConnectionLogger.newInstance(connection, statementLog, queryStack); } else { return connection; } }Connection connection = transaction.getConnection();transaction对象这里是JdbcTransaction对象
public Connection getConnection() throws SQLException { if (connection == null) { openConnection(); } return connection; }openConnection();
protected void openConnection() throws SQLException { // 省略... setDesiredAutoCommit(autoCommmit); }
protected void setDesiredAutoCommit(boolean desiredAutoCommit) { try { if (connection.getAutoCommit() != desiredAutoCommit) { //..... connection.setAutoCommit(desiredAutoCommit); } } catch (SQLException e) { // .... } }connection.setAutoCommit(desiredAutoCommit);desiredAutoCommit参数的值就是在SqlSession调用openSessoin()方法的时候,第4个参数值 false
public SqlSession openSession() { return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false); }上面的源分析码可以无视,不是重点
3. 编写UserTest测试类。
package com.alex.app.test; import org.apache.ibatis.session.SqlSession; import org.junit.Assert; import org.junit.Test; import com.alex.app.entity.User; import com.alex.app.util.MyBatisUtil; public class UserTest { /** * C,Create 创建 */ @Test public void testInsertUser() { SqlSession session = null; try { // 获取SqlSession session = MyBatisUtil.openSession(); // 准备要添加的数据 User user = new User(); user.setUsername("belongtou"); user.setPassword("9988"); /*insert()方法说明 * 第一个参数,就是User.xml的namespace属性 + "." + insert标签的id属性 * 我们看到User.xml的namespace属性正好与我们的实体User的完整类名一致 * 所以我们可以使用反射的方式取到这个完整的类名,然再后 + "." + insert标签的id属性, * 一长串的字符写起来很容易出错的。我们说约定优与配置::: * */ session.insert(User.class.getName()+".insertUser",user); /* 需要手动提交事务 * mybaits的事务在创建SqlSessoin时,自动将作了一个操作:Connection.setAutoCommint(false),将事务设置为非自动提交。 */ session.commit(); } catch (Exception e) { e.printStackTrace(); // 异常回滚 session.rollback(); }finally{ // 关闭SqlSession MyBatisUtil.coloseSession(session); } } /** * R,Retrieve 读取 */ @Test public void testSelectUser() { SqlSession session = null; try { session = MyBatisUtil.openSession(); User user = (User)session.selectOne(User.class.getName()+".selectUser",2); // 断言 user不为空 Assert.assertNotNull(user); // 断言user对象的Id就是我们刚上面所查询到的ID值 2 // assertEquals第一个参数是预期值,第二个参数是实际 Assert.assertEquals(user.getId(), 2); } catch (Exception e) { e.printStackTrace(); } } /** * U, Update 更新 */ @Test public void testUpdateUser() { SqlSession session = null; try { session = MyBatisUtil.openSession(); User user = (User)session.selectOne(User.class.getName()+".selectUser", 1); Assert.assertNotNull(user);//断言user对象不为null user.setUsername("Nunu"); user.setPassword("7788"); session.update(User.class.getName()+".updateUser", user); session.commit(); User user2 = (User)session.selectOne(User.class.getName()+".selectUser", 1); Assert.assertNotNull(user2); //断言,user2所查询到的值,与我们上面更新时(更新user对象)所设置的值是否一致。一致则测试通过 Assert.assertEquals(user2.getUsername(), "Nunu"); Assert.assertEquals(user2.getPassword(), "7788"); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.coloseSession(session); } } /** * D ,Delete 删除 */ @Test public void testDeleteUser() { SqlSession session = null; try { session = MyBatisUtil.openSession(); session.delete(User.class.getName()+".deleteUser", 3); session.commit(); } catch (Exception e) { e.printStackTrace(); session.rollback(); }finally{ MyBatisUtil.coloseSession(session); } } }
注意,SqlSession在创建的时候,MyBatis把事务自动设置为了false,就是JDBC规范的Connection.setAutoCommit(false);事务不会自动提交。再做URD的时候,需要调用SqlSession的commint() 方法提交。
4. 映射文件问题
现在我们映射文件有很多重复主要是parameterType="com.alex.app.entity.User" resultType="com.alex.app.entity.User" 这里,都是重复的。
我们可以在mybatis-config.xml配置文件中properties标签和environments之前,使用typeAlias 标签配置一个别名
<?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> <!-- 引入外部properties文件 --> <properties resource="jdbc.properties" /> <typeAliases> <typeAlias type="com.alex.app.entity.User" alias="User"/> </typeAliases> <environments default="development"> <!-- 省略部分配置 --> </environments> <!-- 映射文件 --> <mappers> <mapper resource="com/alex/app/entity/User.xml"/> </mappers> </configuration>
那么在映射文件中,就可以使用这个别名来定义这些属性 parameterType="User" resultType="User"
<?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="com.alex.app.entity.User"> <select id="selectUser" parameterType="int" resultType="User"> select * from t_user where id = #{id} </select> <insert id="insertUser" parameterType="User"> insert into t_user(username,password) values(#{username},#{password}) </insert> <update id="updateUser" parameterType="User"> update t_user set username=#{username},password=#{password} where id = #{id} </update> <delete id="deleteUser" parameterType="int"> delete from t_user where id = #{id} </delete> </mapper>
单元的测试断言部分不用纠结,可以直接去数据库中查看。或者最笨的方式直接把信息打印到控制台上查看。
另外还有几个问题,就是在执行CRUD操作的时候,会破坏数据库中的数据;每个单元测都是独立的,不依赖与其它单元测试,假如我先执行一个删除动作,删除Id 为2的数据,之后执行了查询动作,查询ID为2的数据,这时候可能会出错。
单元测试是为了测试我们的功能片断是否正常,每个分支是否覆盖到,一些代码的边界是否存在的问题等等,这里不纠结它了,后面我们再研究。
相关推荐
本资源《精通MyBatis-Plus:高效单表查询与复杂联表查询实战指南》是一份详尽而实用的技术文档,专为希望深入掌握MyBatis-Plus框架在数据库操作领域应用的开发者设计。MyBatis-Plus作为MyBatis的增强工具,不仅继承...
只增强,MyBatis-Flex 支持 CRUD、分页查询、多表查询、批量操作,但不丢失 MyBatis 原有的任何功能。高性能,MyBatis-Flex 采用独特的技术架构、相比许多同类框架,MyBatis-Flex 的在增删改查等方面的性能均超越其 ...
MyBatis CRUD操作Java,MyBatis,单元测试,MySql,Maven的CRUD操作这包含构建和运行MyBatisCRUD应用程序所需的一组指令。建设项目。先决条件设置了JDK 1.6.x或更高版本的Maven 2或更高版本的java_home和m2_home。...
mybatis 增强工具包,简化 CRUD 操作。Mybatis-Plus 在 Mybatis 的基础上进行扩展,只做...内置通用 Mapper、通用 Service,仅仅通过少量配置即可实现单表大部分 CRUD 操作,更有强大的条件构造器,满足各类使用需求。
本项目为Java和Mybatis环境下设计的单表CRUD便捷源码,包含485个文件,其中Java源文件383个,XML配置文件51个,SQL文件22个,Markdown文件11个,YAML文件5个,FreeMarker模板4个,属性文件2个,Git忽略文件1个,Git...
然而,随着Java注解的普及,MyBatis也引入了注解方式来简化配置,让CRUD(创建、读取、更新、删除)操作更加便捷。下面我们将详细介绍如何使用注解实现MyBatis的CRUD。 1. **注解简介** MyBatis 的注解主要包括 `@...
互联网资讯,技术简介,IT、AI技术,人工智能互联网资讯,技术简介,IT、AI技术,人工智能互联网资讯,技术简介,IT、AI技术,人工智能互联网资讯,技术简介,IT、AI技术,人工智能互联网资讯,技术简介,IT、AI技术...
在本文中,我们将深入探讨如何使用Spring Boot整合Mybatis实现级联一对多的CRUD(创建、读取、更新、删除)操作。首先,我们需要理解什么是级联操作和一对多的关系。在关系型数据库中,级联操作涉及到一个表中的记录...
发现一些通用的操作,比如单表的CURD,在每一个xml文件中都需要定义一遍。而且每个人写的风格又不统一。于是寻找了一个解决 办法,使用maven插件mybatis-generator。使用一段时间之后,发现还是不能令人满意。每次...
MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs...
本项目实现了基于MyBatis的CRUD操作,即创建(Create)、读取(Read)、更新(Update)和删除(Delete),并以MySQL作为数据存储引擎。以下将详细介绍如何在MyBatis中进行这些操作。 1. 创建(Create) 创建操作...
它提供了灵活的SQL映射机制,使得Java对象和数据库表之间的映射变得简单易行。本篇文章将聚焦于MyBatis中的注解(Annotation)与XML配置的结合使用,旨在帮助开发者更深入地理解这一关键特性。 首先,MyBatis允许...
利用Mybatis的代码生成器,可以根据数据库表自动生成对应的Mapper接口、Mapper XML文件以及实体类,进一步减少手动编写的工作量。 8. **依赖注入**: 使用Spring框架进行依赖注入,将DAO实例注入到Service层,...
修改了删除确认的操作
MyBatis提供了简单易用的API,可以将复杂的数据库操作封装成简单的CRUD操作。 MyBatis-Plus是MyBatis的增强版,提供了更多的便捷方法和性能优化。它可以自动生成SQL语句,提高了开发效率。 前端开发框架 前端使用...
源代码,解压导入本地,主要数据库相关配置
这个"SpringBoot+MybatisCRUD 整合案例"是为初学者设计的,旨在帮助他们快速掌握这两个流行的框架的结合使用。 首先,我们需要在项目中引入Spring Boot和MyBatis的依赖。在`pom.xml`文件中,我们需要添加以下Maven...
本文将深入探讨如何在MyBatis中利用接口实现CRUD(创建、读取、更新、删除)模板。 首先,让我们了解MyBatis的核心概念。MyBatis是一个优秀的持久层框架,它允许开发者通过SQL映射文件或者注解来定义SQL语句,避免...
5. **DAO层**:DAO接口和实现类负责与数据库的交互,通常会使用MyBatis的SqlSession进行 CRUD(创建、读取、更新、删除)操作。 6. **示例应用**:可能包含一个简单的Web应用程序,演示如何在实际项目中集成MyBatis...