Mybatis

    技术2023-11-09  75

    Mybatis

    简介

    Mybatis是一款在持久层使用的SQL映射框架,可以将SQL语句单独写在XML配置文件中,或者使用带注解的Mapper映射类来完成数据库记录。

    优点

    消除了大量的JDBC冗余代码,包括参数设置,结果计封装SQL语句可控制,方便优化查询,使用更加灵活学习成本低,对于新用户能够快速学习使用提供了与主流IOC框架Spring的集成支持引入了缓存机制,提供了与第三方缓存类库的集成支持

    JDBC

    使用JDBC操作数据源

    与数据源建立连接

    JDBC API定义了Connection接口,用来表示与底层数据源的连接。

    获取Connection对象的两种方式:

    1.DriverManager:其会自动加载CLASSPATH下所有的JDBC驱动。

    Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mysql","你的mysql数据库用户名","用户名密码"));

    2.DataSource:他提供了更多底层数据源相关的细节,一个DataSource对象的属性被设置后,它就代表一个特定的数据源。当DataSource实例的getConnection方法被调用后,DataSource实例就会返回一个与数据源建立连接的Connection对象。

    注意:JDBC API只提供了DataSource接口,没有其具体实现。其具体实现由驱动程序和主流的数据库连接池提供。

    //Mybatis提供的DataSource接口实现 DataSource dataSource = new UnpooledDataSource("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/mysql","你的mysql数据库用户名","用户名密码"); Connection connection = dataSource.getConnection(); // Mybatis提供的DataSource工厂,工厂模式创建DataSource DataSourceFactory dsf = new UnpooledDataSourceFactory(); Properties properties = new Properties(); InputStream configStream = Thread.currentThread().getConTextClassLoader().getResourceAsStream("database.properties"); properties.load(configStream); dsf.setProperties(properties); DataSource dataSource = dsf.getDataSource(); Connection connection = dataSource.getConnection();

    执行SQL语句

    Statement: Statement接口以及他的子接口PreparedStatement和CallableStatement.Statement中定义了执行SQL语句的方法,这些方法不支持参数输入,PreparedStatement接口中增加了设置SQL参数的方法,CallableStatement接口继承PreparedStatement,中增加了调用存储过程以及检索存储过程调用结果的方法。

    检索SQL执行结果

    ResultSet:主要体现在两个方面:游标可操作方式,ResultSet对象的修改对数据库的影响。

    DatabaseMetaData:用于获取数据源信息,确定数据源是否支持某一特性或功能,获取数据源限制,确定数据源包含哪些SQL对象以及这些对象的属性,获取数据源对事务的支持。

    package com.lonelywolf.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; public class DatabaseMetaData { public static void main(String[] args) throws ClassNotFoundException, SQLException { Class.forName("com.mysql.jdbc.Driver"); Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","admin"); java.sql.DatabaseMetaData dmd = connection.getMetaData(); System.out.println("数据库用户名:"+ dmd.getUserName()); System.out.println("数据库产品名:"+ dmd.getDatabaseProductName()); } }

    保存点通过在事务中标记一个中间的点来对事务进行更细粒度的控制。一旦设置保存点,事务就可以回滚到保存点,而不影响保存点之前的操作。

    关闭连接

    // Java JDBC连接mysql数据库实例 package com.lonelywolf.Test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; public class JDBCTest { public static void main(String[] args) throws SQLException { // TODO Auto-generated method stub Connection connection = null; Statement statement = null; ResultSet resultSet =null; try { Class.forName("com.mysql.jdbc.Driver"); connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","admin"); statement = connection.createStatement(); resultSet = statement.executeQuery("select * from user"); ResultSetMetaData metaData = resultSet.getMetaData(); int columCount = metaData.getColumnCount(); while(resultSet.next()) { for(int i = 1; i <= columCount; i++) { String columName = metaData.getColumnName(i); String columVal = resultSet.getString(columName); System.out.println(columName+":"+columVal); } System.out.println("------------------------"); } }catch(Exception e) { e.printStackTrace(); }finally { if(resultSet != null) { resultSet.close(); } if(statement != null) { statement.close(); } if(connection != null) { connection.close(); } } } } // DataSource连接mysql数据库 package com.lonelywolf.Test; import java.sql.Connection; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.sql.Statement; import javax.sql.DataSource; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; public class Mybatis_JDBC { public static void main(String[] args) throws SQLException { Connection connection = null; Statement statement = null; ResultSet resultSet =null; try { DataSource dataSource = new UnpooledDataSource("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","admin"); connection = dataSource.getConnection(); statement = connection.createStatement(); resultSet = statement.executeQuery("select * from user"); ResultSetMetaData metaData = resultSet.getMetaData(); int columCount = metaData.getColumnCount(); while(resultSet.next()) { for(int i = 1; i <= columCount; i++) { String columName = metaData.getColumnName(i); String columVal = resultSet.getString(columName); System.out.println(columName+":"+columVal); } System.out.println("------------------------"); } //自增长主键 String sql = "insert into user(create_time,name,password,phone,nick_name) values ('2010-1--24','User3','test','18700000001','User3');"; statement.executeUpdate(sql,Statement.RETURN_GENERATED_KEYS); ResultSet genKeys = statement.getGeneratedKeys(); if(genKeys.next()) { System.out.println("自增长主键:" + genKeys.getInt(1)); } genKeys.close(); }catch(Exception e) { e.printStackTrace(); }finally { if(resultSet != null) { resultSet.close(); } if(statement != null) { statement.close(); } if(connection != null) { connection.close(); } } } }

    Java SPI简介

    SPI(Service Provider Interface)是JDK内置的一种服务提供发现机制。SPI是一种动态替换的发现机制。如一个接口,想在运行时动态给它添加实现,只需要添加一个实现,SPI机制在程序运行时就会发现该实现类

    当服务的提供者提供了一种接口的实现之后,需要在classpath下的META-INF/services目录中创建一个以服务接口命名的文件,这个文件中的内容就是这个接口具体的实现类。当其他的程序需要这个服务的时候,就可以查找这个JAR包中META-INF/services目录的配置文件,配置文件中有接口的具体实现类名,可以根据这个类名加载服务实现类,然后就可以使用该服务了

    JDK查找服务实现的工具类是java.util.ServiceLoader.

    //ServiceLoader的相关使用 package com.lonelywolf.Test; import java.sql.Driver; import java.util.ServiceLoader; public class SPIExample { public static void main(String[] args) { ServiceLoader<Driver> drivers = ServiceLoader.load(java.sql.Driver.class); for(Driver driver:drivers) { System.out.println(driver.getClass().getName()); } } }

    SqlRunner操作数据库

    该类对JDBC做了很好的封装,结合SQL工具类,能够很方便地通过Java代码执行SQL语句并检索SQL执行结果

    package com.lonelywolf.Test; import java.sql.Connection; import java.sql.SQLException; import java.time.LocalDateTime; import java.time.format.DateTimeFormatter; import java.util.Map; import javax.sql.DataSource; import org.apache.ibatis.datasource.unpooled.UnpooledDataSource; import org.apache.ibatis.jdbc.SQL; import org.apache.ibatis.jdbc.SqlRunner; import org.junit.Before; import org.junit.Test; import com.alibaba.fastjson.JSON; public class SqlRunnerTest { DataSource dataSource =null; Connection connection =null; @Before public void init() throws SQLException { dataSource = new UnpooledDataSource("com.mysql.jdbc.Driver","jdbc:mysql://localhost:3306/mybatis?useSSL=false","root","admin"); connection = dataSource.getConnection(); } @Test public void testSelectOne() throws SQLException{ SqlRunner sqlRunner = new SqlRunner(connection); String qryUserSql = new SQL() {{ SELECT("*"); FROM("user"); WHERE("id = ?"); }}.toString(); Map<String,Object> resultMap = sqlRunner.selectOne(qryUserSql, Integer.valueOf(1)); System.out.println(JSON.toJSONString(resultMap)); } @Test public void testDelete() throws SQLException { SqlRunner sqlRunner = new SqlRunner(connection); String deleteUserSql = new SQL() {{ DELETE_FROM("user"); WHERE("id = ?"); }}.toString(); sqlRunner.delete(deleteUserSql, Integer.valueOf(1)); } @Test public void testUpdate() throws SQLException { SqlRunner sqlRunner = new SqlRunner(connection); String updateUserSql = new SQL() {{ UPDATE("user"); SET("nick_name = ?"); WHERE("id = ?"); }}.toString(); sqlRunner.update(updateUserSql, "Jane",Integer.valueOf(2)); } @Test public void testInsert() throws SQLException { SqlRunner sqlRunner = new SqlRunner(connection); String insertUserSql = new SQL() {{ INSERT_INTO("user"); INTO_COLUMNS("create_time,name,password,phone,nick_name"); INTO_VALUES("?,?,?,?,?"); }}.toString(); String createTime = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd")); sqlRunner.insert(insertUserSql, createTime,"Jane","Test","18843438984","J"); } }

    Mybatis 核心组件

    使用Mybatis的步骤

    编写Mybatis的主配置文件

    <?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> <settings> <setting name="useGeneratedKeys" value="true"/> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="UNPOOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&amp;characterEncoding=utf-8&amp;useSSL=false"/> <property name="username" value="root"/> <property name="password" value="admin"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/UserMapper.xml"/> </mappers> </configuration>

    新增Java实体与数据库记录建立映射

    package com.lonelywolf.Entity; import java.util.Date; import lombok.Data; @Data public class UserEntity { private Long id; private String name; private Date createTime; private String password; private String phone; private String nickName; }

    定义用于执行SQL的Mapper

    <?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.lonelywolf.dao.UserMapper"> <sql id="userAllField"> id,create_time,name,password,phone,nick_name </sql> <select id="listAllUser" resultType="com.lonelywolf.Entity.UserEntity"> select <include refid="userAllField"/> from user </select> </mapper>

    通过Mybatis提供的API执行我们定义的Mapper

    //Dao层 API接口 package com.lonelywolf.dao; import java.util.List; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import com.lonelywolf.Entity.UserEntity; public interface UserMapper { List<UserEntity> listAllUser(); @Select("select * from user where id = #{userId,jdbcType=INTEGER}") UserEntity getUserById(@Param("userId") String userId); } //测试类 package com.lonelywolf.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.Test; import com.alibaba.fastjson.JSON; import com.lonelywolf.Entity.UserEntity; import com.lonelywolf.dao.UserMapper; public class TestMybatis { @Test public void testMybatis() throws Exception { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<UserEntity> userList = userMapper.listAllUser(); System.out.println(JSON.toJSONString(userList)); } }

    Mybatis核心组件

    Configuration:用于描述Mybatis的主配置信息,其他组件需要获取配置信息时,直接通过Configuration对象获取

    MappedStatement:MappedStatement用于描述Mapper中的SQL配置信息,是对MapperXML配置文件中<select|update|delete|insert>等标签或者@Select/@Update等注解配置信息的封装。

    SqlSession:SqlSession是MyBatis提供的面向用户的API,表示和数据库交互时的会话对象,用于完成数据库的增删改查功能

    Executor:SqlSession是Mybatis提供的操作数据库的API,但真正执行的SQL的是Executor组件。

    Executor接口定义了对数据库的增删改查方法,其中,query()和queryCursor()方法用于执行查询操作,update()用于执行插入,删除和修改操作。

    @Test public void testExecutor() throws Exception { InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); Configuration configuration = sqlSessionFactory.getConfiguration(); //从Configuration对象中获取描述SQL配置的MappedStatement对象 MappedStatement listAllUserStmt = configuration.getMappedStatement("com.lonelywolf.dao.UserMapper.listAllUser"); Executor reuseExecutor = configuration.newExecutor(new JdbcTransaction(sqlSession.getConnection()), ExecutorType.REUSE); List<UserEntity> userList = reuseExecutor.query(listAllUserStmt, null, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER); System.out.println(JSON.toJSONString(userList)); }

    SqlSession创建过程

    XPATH方式解析XML文件

    JDK API中提供了3种解析XML的方式,分别是:DOM,SAX和XPath.

    Mybatis框架种采用XPath方式解析XML文件。

    //实例XPath方式解析XML文件 package com.lonelywolf.Test; import java.io.InputStream; import java.util.ArrayList; import java.util.Date; import java.util.List; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.xpath.XPath; import javax.xml.xpath.XPathConstants; import javax.xml.xpath.XPathFactory; import org.apache.ibatis.io.Resources; import org.junit.Test; import org.w3c.dom.Document; import org.w3c.dom.NodeList; import com.alibaba.fastjson.JSON; import com.lonelywolf.Entity.UserEntity; public class SqlSessionTest { public UserEntity buildUserEntity(Long id,String name,Date createTime,String password,String phone,String nickName) { UserEntity userEntity = new UserEntity(); userEntity.setId(id); userEntity.setName(name); userEntity.setCreateTime(createTime); userEntity.setPassword(password); userEntity.setPhone(phone); userEntity.setNickName(nickName); return userEntity; } @Test public void testXPathParser() { try { DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = factory.newDocumentBuilder(); InputStream inputSource = Resources.getResourceAsStream("User.xml"); Document doc = builder.parse(inputSource); XPath xpath = XPathFactory.newInstance().newXPath(); NodeList nodeList = (NodeList)xpath.evaluate("/users/*", doc,XPathConstants.NODESET); List<UserEntity> userList = new ArrayList<UserEntity>(); for(int i=1; i<nodeList.getLength()+1; i++) { String path = "/users/user["+i+"]"; String id= (String)xpath.evaluate(path+"/@id", doc,XPathConstants.STRING); String name = (String)xpath.evaluate(path+"/name", doc,XPathConstants.STRING); String password = (String)xpath.evaluate(path+"/password", doc,XPathConstants.STRING); String phone = (String)xpath.evaluate(path+"/phone", doc,XPathConstants.STRING); String nickName = (String)xpath.evaluate(path+"/nickName", doc,XPathConstants.STRING); Date createTime = new Date(); Long idtest = Long.parseLong(id); UserEntity userEntity = buildUserEntity(idtest,name,createTime,password,phone,nickName); userList.add(userEntity); } System.out.println(JSON.toJSONString(userList)); }catch (Exception e) { // TODO: handle exception e.printStackTrace(); } } } //User.xml <?xml version="1.0" encoding="UTF-8"?> <users> <user id="1"> <name>张三</name> <createTime>2018-06-06</createTime> <password>admin</password> <phone>18000000000</phone> <nickName>阿毛</nickName> </user> <user id="2"> <name>李四</name> <createTime>2018-06-06</createTime> <password>admin</password> <phone>18000000001</phone> <nickName>明明</nickName> </user> </users>
    Configuration创建过程

    作用:

    用于描述Mybatis配置信息作为容器注册Mybatis其他组件提供给工厂方法

    Mybatis通过XMLConfigBuilder类完成Configuration对象的构建过程。

    package com.lonelywolf.Test; import java.io.IOException; import java.io.Reader; import org.apache.ibatis.builder.xml.XMLConfigBuilder; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.Configuration; import org.junit.Test; public class ConfigurationTest { @Test public void testConfiguration() throws IOException { Reader reader = Resources.getResourceAsReader("mybatis-config.xml"); XMLConfigBuilder builder = new XMLConfigBuilder(reader); Configuration conf = builder.parse(); System.out.println(conf); } }

    Mapper执行过程

    在创建SqlSession实例后,需要调用SqlSession的getMapper()方法获取一个UserMapper的引用,然后通过该引用调用Mapper接口中定义的方法。

    SqlSession对象的getMapper()方法返回的是一个类的实例,其实质是返回一个动态代理的对象。,Configuration对象中有一个mapperRegistry属性,MyBatis通过mapperRegistry属性注册Mapper接口与MapperProxyFactory对象之间的对应关系。MapperRegistry类有一个knownMappers属性,用于注册Mapper接口对应的Class对象和MapperProxyFactory对象之间的关系。另外,MapperRegistry提供了addMapper()方法,用于向knownMappers属性中注册Mapper接口信息。在addMapper()方法中,为每个Mapper接口对应的Class对象创建一个MapperProxyFactory对象,然后添加到knownMappers属性中。MapperRegistry还提供了getMapper()方法,能够根据Mapper接口的Class对象获取对应的MapperProxyFactory对象,然后就可以使用MapperProxyFactory对象创建Mapper动态代理对象了。

    Mapper SQL配置信息注册过程

    Mybatis通过MappedStatement类描述Mapper的SQL配置信息。SQL配置有两种方式,一种通过XML文件配置,另一种是通过Java注解,而Java注解的本质是一种轻量级的配置信息。

    Configuration类中有一个mappedStatements属性,该属性用于注册Mybatis中所有的MappedStatement对象

    protected final Map<String MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");

    mappedStatements属性是一个Map对象,它的Key为Mapper SQL配置id,如果SQL是通过XML配置的,则Id为命名空间加上<select|update|delete|insert>标签的id,如果SQL通过Java注解配置,则Id为Mapper接口的完全限定名加上方法名称。

    Mybatis配置

    主配置文件

    configuration(配置)

    properties(属性)

    属性可以在外部进行配置,并可以进行动态替换

    <properties resource="org/mybatis/example/config.properties"> <property name="username" value="dev_user"/> <property name="password" value="F2Fa3!33TYyg"/> </properties>

    设置好的属性可以在整个配置文件中用来替换动态配置的属性值

    dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource>

    若属性在不止一个地方进行了配置,则Mybatis将按照下面的顺序进行加载:首先读取在properties元素体内指定的属性。然后根据properties元素中的resource属性读取类路径下的属性文件,或根据url属性指定的路径读取属性文件。并覆盖之前读取过的同名文件。最后读取作为方法参数传递的属性,并覆盖之前读过的同名属性。

    settings(设置)

    用于改变Mybatis的运行时行为

    typeAliases(类型别名)

    为java类型设置一个缩写别名,仅用于XML配置,意在降低冗余的全限定类名的书写。

    <typeAliases> <typeAlias alias="Author" type="domain.blog.Author"/> <typeAlias alias="Blog" type="domain.blog.Blog"/> <typeAlias alias="Comment" type="domain.blog.Comment"/> <typeAlias alias="Post" type="domain.blog.Post"/> <typeAlias alias="Section" type="domain.blog.Section"/> <typeAlias alias="Tag" type="domain.blog.Tag"/> </typeAliases> //包的形式 <typeAliases> <package name="domain.blog"/> </typeAliases>

    typeHandlers(类型处理器)

    objectFactory(对象工厂)

    Mybatis创建结果对象的新实例时,会使用一个对象工厂实例来完成实例化工作。默认的对象工厂需要做的仅仅是实例化目标类,包括默认无参构造方法和有参构造方法。

    plugins(插件)

    用于利用插件进行拦截

    environments(环境配置)

    environment(环境变量)

    transactionManager(事务管理器)

    dataSource(数据源)

    三种内建的数据源

    1.UNPOOLED:这个数据源的实现会每次请求时打开或者关闭连接。

    2.POOLED这种数据源的实现利用池的概念来将JDBC连接对象组织起来,避免了创建新的连接实例时所必须的初始化和认证时间。

    3.JNDI:这个数据源实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的数据源引用

    databaseIdProvider(数据库厂商标识)

    mappers(映射器):mapper文件的映射路径

    <!-- 使用相对于类路径的资源引用 --> <mappers> <mapper resource="org/mybatis/builder/AuthorMapper.xml"/> <mapper resource="org/mybatis/builder/BlogMapper.xml"/> <mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers> <!-- 将包内的映射器接口实现全部注册为映射器 --> <mappers> <package name="org.mybatis.builder"/> </mappers>

    Mapper配置文件

    mapper cachecache-refresultMapsqlinsertupdatedeleteselect <select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY"> <insert id="insertAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20"> <update id="updateAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20"> <delete id="deleteAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20">

    动态SQL语句

    <select id="findActiveBlogWithTitleLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <if test="title != null"> AND title like #{title} </if> </select> <select id="findActiveBlogLike" resultType="Blog"> SELECT * FROM BLOG WHERE state = ‘ACTIVE’ <choose> <when test="title != null"> AND title like #{title} </when> <when test="author != null and author.name != null"> AND author_name like #{author.name} </when> <otherwise> AND featured = 1 </otherwise> </choose> </select> <update id="updateAuthorIfNecessary"> update Author <set> <if test="username != null">username=#{username},</if> <if test="password != null">password=#{password},</if> <if test="email != null">email=#{email},</if> <if test="bio != null">bio=#{bio}</if> </set> where id=#{id} </update> <select id="selectPostIn" resultType="domain.blog.Post"> SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> </select> <insert id="insert"> <selectKey keyProperty="id" resultType="int" order="BEFORE"> <if test="_databaseId == 'oracle'"> select seq_users.nextval from dual </if> <if test="_databaseId == 'db2'"> select nextval for seq_users from sysibm.sysdummy1" </if> </selectKey> insert into users values (#{id}, #{name}) </insert>

    Mybatis-plus

    Mybatis-plus是Mybatis的增强工具,在Mybatis的基础上只做增强,不做改变。

    具体操作和使用说明参考官方文档

    Processed: 0.013, SQL: 10