“Reprint” the original link please click

The basic application

1. Quick start

1.1 website:www.mybatis.org/mybatis-3/

1.2. Development steps

1.2.1. Add Mybatis coordinates (add PAM.xml dependency)

<! --mybatis-->
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.5</version>
</dependency>
<! - mysql driver - >
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.6</version>
    <scope>runtime</scope>
</dependency>
<! -- Unit tests -->
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>
<! - log - >
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.12</version>
</dependency>
Copy the code

1.2.2. Create user table

.

1.2.3. Write the User entity

.

1.2.4. Compile the mapping file usermapper. XML and label description

<! - <? xml ... Mapping file DTD constraint header <mapper> root tag namespae namespace, < SELECT > Query operation <update> Update operation < INSERT > Add operation < DELETE > Delete operation ID Statement ID, ResultType Specifies the entity type of the query result parameterType Specifies the type of the query object.

       <! DOCTYPEmapper PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="UserMapper">
    <select id="find" resultType="com.otoom.pojo.User" parameterType="com.otoom.pojo.User">
        select * from User WHERE username = #{username}
    </select>
</mapper>
Copy the code

1.2.5. Compile the core file SQLmapconfig.xml

<! DOCTYPEconfiguration PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> 
        
       jdbc.properties"/ > <! -- environment, default environment :development--> <environments default="development"> <! --> <environment id="development"> <! <transactionManager type="JDBC"/ > <! --> <dataSource type="POOLED"> driver" value="${jdbc.driver}"/> url" value="${jdbc.url}"/> username" value="${jdbc.username}"/> password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <! --> <mappers> <! <mapper resource="com/xxx/mapper/UserMapper.xml"/ > -- > <! Resources: com/ XXX /mapper: resources: com/ XXX /mapper --> <package name="com.xxx.mapper"/>  Copy the code

1.2.6. Use

public static void main(String[] args){
    // Get the configuration information
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the factory class
    SqlSessionFactory sqlSessionFactory = 
        new SqlSessionFactoryBuilder().build(resourceAsStream); 
    // Start the SQL session
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    // The system starts to perform corresponding operations
    User query = new User();
    query.setUsername("Tom"); 
    int insert = sqlSession.insert("userMapper.find", query);
    // Commit the transaction
    //sqlSession.commit(); // The CUD operation needs to commit a transaction
	// Close the session
    sqlSession.close();
}
Copy the code

1.2.7.sqlconfig. XML Label description of the core configuration file

environments

Configure the database environment and support multi-environment configuration

environment

The environment variable

transactionManager

Transaction managers, which come in two types:

2. MANAGED: This configuration does almost nothing. It never commits and rolls back a link, leaving the container to manage the entire life cycle of a transaction. By default it closes the connection, and some containers don't want to close it, so you need to set the closeConnection property to false to prevent its default behaviorCopy the code
dataSource

Data sources, there are three types:

1. UNPOOLED: indicates the type of a non-connection pool. This data source implementation simply opens and closes connections on each request. 2. POOLED: Connection pool type. This data source implementation uses the concept of "pooling" to organize JDBC connection objects. 3. JNDI: This data source implementation is intended for use in a container such as an EJB or application server, which can centrally or externally configure the data source and then place a JNDI context referenceCopy the code
property

attribute

propertys

Property, which loads additional configured properties files, such as jdbc.properties under the Resource folder. Driver can be used as follows: ${jdbc.driver} can reference the corresponding value

mappers

Mapper, used to load SQL mapping:

1. Use relative to the class path: ` ` ` XML < mapper resource = "com/XXX/mapper/UserDao. XML" / > ` ` `Copy the code
  1. Use fully qualified resource locator (URL) :
```xml
<mapper url="file:///user/xx/project/xxx/UserDao.xml"/>
```
Copy the code
  1. Fully qualified class names for classes implemented using the mapper interface:

    <mapper class="com.xxx.UserDao"/>
    Copy the code
  2. Implement all registered as mappers using the mapper interface within the package:

    The name of the XML package must be the same as the name of the existing interface. For example, the resources directory contains the package com.xxx.mapper. All XML files need to be stored in this directory

    <package name="com.xxx.mapper"/>
    Copy the code

2. Complex mapping development

2.1. Preparation

  • Entities (corresponding to database tables)
public class User{
    private Integer id;
    private String userName;
    
    // A user with multiple orders (one to many)
    private List<Order> orderList;
    // User roles (many-to-many)
    private List<Role> roleList;
}
Copy the code
public class Order{
    private Integer id;
    private Integer userId;
    private String orderTime;
    
    // One order, only one user (one to one)
    private User user;
}
Copy the code
public class Role{
    private Integer id;
    private String roleName;
}
Copy the code
public class UserRole{
    private Integer userId
    private Integer roleid;
}
Copy the code
  • Mapper interfaces
public class OrderMapper{
    List<Order> findAll(a);
    // Query one-to-one
    List<Order> finUserAndOrder(a);
}
Copy the code
public class UserMapper{
    User findById(Integer userId);
    // Query one-to-many
    List<User> findAll(a);
    // query multiple pairs
    List<User> findAllUserAndRole(a);
}
Copy the code
public class RoleMapper{
    // query multiple pairs
    List<Role> findByUserId(Integer userId);
}
Copy the code

2.2. One-to-one query

OrderMapper. Writing XML

<mapper namespace="OrderMapper">
    
    <! One-to-one mapping configuration -->
    <resultMap id="orderMap" type="Order">
    	<result property="id" column="id"/>
    	<result property="userId" column="userId"/>
    	<result property="orderTime" column="orderTime"/>
        
        <! Mysql > select * from User; mysql > select * from User; mysql > select * from User;
        <association property="user" javaType="User">
            <result property="id" column="userId"/>
            <result property="username" column="username"/>
        </association>
    </resultMap>
    
    <! -- resultMap: manually configure the mapping between entity attributes and table fields -->
	<select id="finUserAndOrder" parameterType="Order" resultMap="orderMap">
    	select * from order o,user u where o.userId = u.id
    </select>
</mapper>
Copy the code

###2.3. One-to-many query

From the user’s point of view, query one-to-many results;

UserMapper. Write XML

<mapper namespace="UserMapper">
    
    <! -- One-to-many mapping configuration -->
    <resultMap id="userMap" type="User">
        <result property="id" column="id"/>
        <result property="username" column="username"/>
    	
        <! OrderList = orderList; orderList = orderList; orderList = orderList; orderList = orderList
        <collection property="orderList" ofType="Order">
            <result property="id" column="oid"/>
            <result property="userId" column="userId"/>
            <result property="orderTime" column="orderTime"/>
        </collection>
    </resultMap>
    
    <! -- resultMap: manually configure the mapping between entity attributes and table fields -->
	<select id="findAll" parameterType="User" resultMap="userMap">
    	select *,o.id oid from user u left join order o on o.userId = u.id
    </select>
</mapper>
Copy the code

2.4. Many-to-many queries

The relationship between user and role is many-to-many query;

UserMapper.xml

<mapper namespace="UserMapper">
	<! -- One-to-many mapping configuration -->.<! Many-to-many mapping configuration -->
    <resultMap id="userRoleMap" type="User">
        <result property="id" column="id"/>
        <result property="username" column="username"/>
        <! Select * from roleList; select * from roleList;
        <collection property="roleList" ofType="Role">
            <result property="id" column="rid"/>
            <result property="roleName" column="roleName"/>
        </collection>
    </resultMap>
    
	<select id="findAllUserAndRole" parameterType="User" resultMap="userRoleMap">
    	select u.*,r.*,r.id rid from user u 
        	left join user_role ur on u.id = ur.userId
        	left join role r on r.id = ur.roleId
    </select>
    
</mapper>
Copy the code

2.5. Test complex mappings

public static void main(String[] args){
    // Get the configuration input stream
	InputStream inputStream = Resources.getResourceAsSteam("splMapConfig.xml");
	// Get the SQL session
	SqlSession sqlSession = SqlSessionFactoryBuilder.build(inputStream).openSession();
	UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    // Execute the query
    
    /* One to one */
    List<Order> orderList = orderMapper.finUserAndOrder();
    for(Order order : orderList){
        System.out.println(order)
    }
    
    /*
    一对多
    */
	List<User> userList = userMapper.findAll();
    for(User user : userList){
        System.out.println(user)
    }
    
    /* Many-to-many */
	List<User> userList = userMapper.findAllUserAndRole();
    for(User user : userList){
        System.out.println(user)
    }
    
    sqlSession.close();

}
Copy the code

3. Annotation development of Mybatis

3.1. Common annotations

  • @ Insert new

  • @ the Update to Update

  • @ the Delete Delete

  • @ the Select query

  • @result encapsulates the Result set

    Instead of the and tags in XML

    Has the following properties:

    • Column Indicates the database field name
    • Property Specifies the property name of the object
    • @result (one= @one)
    • @result (many= @many)
  • @results can be used with @result to encapsulate multiple Result sets

    Instead of tags in XML, you can also use the @result collection, using the format:

    @Results({ @Result(),@Result() })
    Copy the code
  • @one one-to-one result set encapsulation

    Instead of labels, this is the key to multi-table queries and is used in annotations to specify that subqueries return a single object

    Has the following properties:

    • Select specifies the SQLMapper for multi-table queries

      @Result(column="",property="",one=@One(select=""))
      Copy the code
  • @many one-to-many result set encapsulation

    Instead of labels, this is the key to multi-table queries and is used in annotations to specify the collection of objects to be returned by subqueries

    • Has the following properties:

      • Select specifies the SQLMapper for multi-table queries

        @Result(column="",property="",one=@Many(select=""))
        Copy the code

3.2. Develop with annotations

3.2.1. One-to-one query

public class OrderMapper{

    // Query one-to-one
    @Select("select * from order")
    @Results({ @Result(id=true,property="id",column="id"), @Result(property="userId",column="userId"), @Result(property="orderTime",column="orderTime") @Result(property="user",column="userId", javaType=User.class, one=@One(select="com.xxx.mapper.UserMapper.findById") ) })
    List<Order> finUserAndOrder(a); . }Copy the code
public class UserMapper{
    
    @Select("select * from user where id=#{userId}")
    User findById(Integer userId); . }Copy the code

3.2.2. One-to-many query

public class OrderMapper{    
	
    @Select("select * from order where userId=#{userId}")
   	List<Order> findByUserId(Integer userId); . }Copy the code
public class UserMapper{
    
    // Query one-to-many
    @Select("select * from user")
    @Results({ @Result(id=true,property="id",column="id"), @Result(id=true,property="username",column="username"), @Result(property="orderList",column="id", javaType=List.class, many=@Many(select="com.xxx.mapper.OrderMapper.findByUserId") }) List
      
        findAllUserAndOrder(); . }
      Copy the code

3.2.3. Multiple heap multiple query

public class UserMapper{
    
    // query multiple pairs
    @Select("select * from user")
	@Results({ @Result(id=true,property="id",column="id"), @Result(property="username",column="username"), @Result(property="roleList",column="id", javaType=List.class, many=@Many(select="com.xxx.mapper.RoleMapper.findByUserId")) })
    List<User> findAllUserAndRole(a);
}
Copy the code
public class RoleMapper{
    // query multiple pairs
    @Select("select * from role r,user_role ur where r.id=ur.roleId and ur.userId = #{userId}")
    List<Role> findByUserId(Integer userId);
}
Copy the code

4. Level 1 cache

  • What is level 1 caching?

  • Why level 1 caching?

Mybatis will recommend a simple cache in the session object SqlSession object, cache the query result, the next query, will determine whether there is a exactly the same query, if there is directly returned from the cache. Otherwise, the database is queried, cached, and finally returned to the user.

By doing this, we avoid repeatedly executing the same query statement in a short period of time and getting the same results. This is a huge waste of resources.

4.1. Principle and source code analysis of level 1 cache

  • At the bottom is data structure storage using HashMap

  • Caches are created in the Executor, where caches are added and removed

  • The default cache Key consists of five parts (see class BaseExecutor) :

    1. StatementId: indicates the id of a MapStatement

    2. Offset: Paging setting, 0 by default, obtained from the RowBound paging object

    3. Limit: The maximum number of pages to page, obtained from the RowBound page object

    4. BoundSql: The SQL statement for the query, obtained from the boundSql object

    5. Value: indicates the SQL parameter, which is obtained from parameter

    6. Env: the current environment. If sqlmapconfig. XML has

      , it will also be set to the key

    Related source code:

    CacheKey cacheKey = new CacheKey(); 
    //MappedStatement 的 id 
    // id is the package name + class name + Sql name
    cacheKey.update(ms.getId()); 
    // offset 就是 0 
    cacheKey.update(rowBounds.getOffset());
    // limit 就是 Integer.MAXVALUE 
    cacheKey.update(rowBounds.getLimit()); 
    // A specific SQL statement
    cacheKey.update(boundSql.getSql()); 
    // Update the SQL with the parameterscacheKey.update(value); .if(configuration.getEnvironment() ! =null) {
        // issue #176 
        cacheKey.update(configuration.getEnvironment().getId());
    }
    
    Copy the code
  • BaseExecutor; BaseExecutor;

    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter,RowBounds rowBounds,ResultHandler resultHandler) throws SQLException {
        In queryFromDatabase, write to localCache. The put method of the localCache object is ultimately handed over to Map for storage
        BoundSql boundSql = ms.getBoundSql(parameter); 
        // Create a cache
        CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql); 
        return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
    }
    
    @SuppressWarnings("unchecked") 
    @Override
    public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException{... list = resultHandler ==null ? (List<E>) localCache.getObject(key) : null;
        if(list ! =null) { 
            // This is mainly used for processing stored procedures.
            handleLocallyCachedOutputParameters(ms, key, parameter, boundSql); 
        } else {
            // Query from the databaselist = queryFromDatabase(ms, parameter,rowBounds,resultHandler,key,boundSql); }... }/** * queryFromDatabase method */
    private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
        List<E> list;
        localCache.putObject(key, EXECUTION_PLACEHOLDER);
        try {
            // Execute the query
            list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
        } finally {
            // Clear the data in the cache
            localCache.removeObject(key);
        }
        // Put the queried data back into the level 1 cache
        localCache.putObject(key, list);
        if (ms.getStatementType() == StatementType.CALLABLE) {
            localOutputParameterCache.putObject(key, parameter);
        }
        return list;
    }
    Copy the code

4.2. Level 2 cache

  • What is level 2 cache?

  • What does level 2 cache do?

  • How is level 2 cache implemented?

  1. Level 2 caching works the same way as level 1 caching, the first query will put the data in the cache, and then the second query will go straight to the cache

The cache to take

  1. Level 2 caching needs to be enabled manually, unlike level 1 caching, which is enabled by default.

  2. Level 2 cache stores not objects, but objects’ data;

  3. The Serializable object needs to implement the Serializable interface, because the level 2 cache can be stored in many media, such as memory, disk, etc. So when fetching data, deserialization is required.

  4. The level 2 cache is based on the namespace of mapper files. Multiple SQLSessions can share a level 2 cache area in a Mapper

4.2.1. Enable level 2 Cache
  • XML Enabled

    1. Add the following configuration to the global configuration file sqlmapconfig.xml:

      <! -- Enable level 2 cache -->
      <settings>
          <setting name="cacheEnabled" value="true"/>
      </settings>
      Copy the code
    2. Add configuration to mapper.xml:

      <! -- Enable level 2 cache -->
      <cache></cache>
      Copy the code
  • Annotations to open

    1. Add annotations to the Mapper class:
    // Use level 2 cache, etc., for the 
            
              attribute
            
    @CacheNamespace
    public interface UserMapper{... }Copy the code
4.2.2. Redis is used to achieve two level cache
  • What are the drawbacks of using the default second-level cache implementation?
  • What problems are solved by implementing level 2 caching using caching middleware?

Use the default level 2 cache implementation, can only be used in a single system, not distributed cache.

The cache middleware Redis is introduced as the storage medium of the secondary cache, which can realize multi-machine distributed cache data storage and centralized management of the cache data

  1. Add dependencies. Add the following dependencies to pom.xml:

    <dependency>
        <groupId>org.mybatis.caches</groupId>
        <artifactId>mybatis-redis</artifactId>
        <version>1.0.0 beta 2 -</version>
    </dependency>
    Copy the code
  2. Add the configuration redis.properties to the Resources directory

    redis.host=localhost
    redis.port=6379
    redis.connectionTimeout=5000
    redis.password=
    redis.database=0
    Copy the code

    By default, if it is a local redis and there is no other special configuration, mybatis-redis already has the default configuration

  3. Specifies the use of RedisCache as a level 2 cache

    • XML. In mapper.xml, add the following configuration:

      <cache type="org.mybatis.caches.redis.RedisCache" />
      Copy the code
    • Annotation mode. Use implementation to specify RedisCache

      @CacheNamespace(implementation=RedisCache.class)
      public interface UserMapper{... }Copy the code
4.2.3.RedisCache source code analysis
  • How is it done?

  • How is the cache accessed?

  • What data structures are used?

  1. The Cache interface of Mybatis is realized
  2. CURD operations on Redis are encapsulated internally using JDIS
  3. Redis Hash data structure is used to store data after serialization
  4. RedisCache is created by Mybatis CacheBuilder when mybatis is started

RedisCache RedisCache

public final class RedisCache implements Cache {
    public RedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require anID");
        }
        this.id = id;
        / / call RedisConfigurationBuilder RedisConfig creation
        RedisConfig redisConfig = RedisConfigurationBuilder.getInstance()
            // The RedisConfig core method, which loads and parses the redis configuration file
            .parseConfiguration();
		pool = new JedisPool(redisConfig,redisConfig.getHost(),redisConfig.getPort(),redisConfig.getConnectionTimeout(),redisConfig.getSoTimeout(), redisConfig.getPassword(), redisConfig.getDatabase(), redisConfig.getClientName());
    }
    ...
}

/** * Load the redis configuration resource through the class loader, */
public RedisConfig parseConfiguration(ClassLoader classLoader) {
    Properties config = new Properties();
    InputStream input = classLoader.getResourceAsStream(redisPropertiesFilename);
    if(input ! =null) {
        try {
            // Load configuration information into the Properties container
            config.load(input);
		}catch (IOException e) {
            throw new RuntimeException( "An error occurred while reading classpath property '" + redisPropertiesFilename + "', see nested exceptions", e);
        } finally {
            try {
                input.close();
            } catch (IOException e) {
                // close quietly }}}//redisConfig inherits JedisPoolConfig
    RedisConfig jedisConfig = new RedisConfig();
    // Start setting the Redis configuration
    setConfigProperties(config, jedisConfig);
    return jedisConfig;
}
Copy the code

##5.Mybatis plugin mechanism

  • What are the benefits of using plug-ins?

  • What are the 4 components of Mybatis?

  • What interception methods are provided by the four components of Mybatis?

Benefits of using plug-ins:

  1. Is to increase the flexibility of the framework

  2. Developers can expand the framework to make it work better based on actual needs

5.1. Four components of Mybatis

  • Interceptors, in fact

  • Dynamic proxy is used, and all four components are proxy objects

5.1.1. Executor components

Executor. The following main functions are provided:

  • update

    • query
    • commit
    • rollback

5.1.2. StatementHandler components

SQL syntax builder StatementHandler. The following main functions are provided:

  • parameterize
  • batch
  • updates
  • query

5.1.3. ParameterHandler components

ParameterHandler ParameterHandler. The following main functions are provided:

  • getParameterObject
  • setParameters

5.1.4 ensuring ResultSeetHandler components

ResultSetHandler ResultSetHandler. The following main functions are provided:

  • handleResultSets
  • handleOutputParameters

5.2. Plug-in principle of Mybatis

  • Through dynamic proxy

  • Every time four object creation, through InterceptorChain. PluginAll () function returns an agent

  • ParameterHandler provides an example of ParameterHandler’s source code:

public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object object, BoundSql sql, InterceptorChain interceptorChain){
    ParameterHandler parameterHandler =
        mappedStatement.getLang().createParameterHandler(mappedStatement,object,sql);
    // Generate a proxy for the target object, and then the target object calls the method instead of the original method
    parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
    return parameterHandler; 
}

public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors){
        target = interceptor.plugin(target);
    }
    return target;
}
Copy the code

The interceptorChain holds all interceptors, which are created when mybatis is initialized.

Interceptors in the interceptor chain are called to intercept or enhance the target in turn.

The target in interceptor.plugin(target) can be understood as the four objects in Mybatis. The target returned is the re-proxied object

5.3. Basic implementation of Mybatis custom plug-in

MyBatis can load plug-ins at startup and save the plug-in instance into the relevant object (InterceptorChain).

After the preparation, MyBatis is in a ready state. When executing SQL, we need to create SqlSession with DefaultSqlSessionFactory first. An Executor instance is created during SqlSession creation. After an Executor instance is created,

MyBatis generates proxy classes for instances using JDK dynamic proxies. This way, the plug-in logic can be executed before executor-related methods are called.

5.3.1. Plug-in interface

The Interceptor interface has the following methods:

  • Intercept, the core method of the plug-in
  • Plugin to generate a proxy object for Target
  • SetProperties, which passes the parameters required by the plug-in

5.3.2. Start implementing custom plug-ins

  • Code implementation

    /** * To implement a custom plug-in, you need to implement the Interceptor interface. * <p> * use@InterceptsAnnotations, marking interceptors, and the classes and methods that are destined to be intercepted */
    
    StatementHandler type = StatementHandler. Class, // If the prepare precompile method is executed, // Args = {connection.class, integer.class}))
    public class Myplugin implements Interceptor {
    
        /** * Core intercepting method. The Intercept method is executed every time the target method being intercepted is executed@param invocation
         * @return
         * @throws Throwable
         */
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            //TODO business logic
    
            // Invocation. Proceed is returned to the original method
            return invocation.proceed();
        }
    
        /** * basically adds the current interceptor generation proxy class to the interceptor chain **@param target
         * @return* /
        @Override
        public Object plugin(Object target) {
            // This represents the current interceptor, target represents the target object, and wrap creates a proxy object for the target object using methods wrapped in Mybatis.
            Object wrap = Plugin.wrap(target, this);
            return wrap;
        }
    
        /** * Get the configured parameters **@param properties
         */
        @Override
        public void setProperties(Properties properties) {
            //properties corresponds to the property of the XML configuration}}Copy the code
  • In sqlmapconfig.xml:

    <! -- Configure plugins -->
    <plugins>
        <plugin interceptor="com.otoomo.plugin.Myplugin">
            <! Set plugin parameters, available in the plugin setProperties method -->
            <property name="name" value="tom"/>
        </plugin>
    </plugins>
    
    Copy the code

    The location of the configuration file needs to be paid attention to, do not put the wrong, Mybatis has strict order verification, put the wrong position

5.3.3. Source code analysis of plug-ins

5.3.4. Write a generic Mapper using plug-ins

  • Plugin mechanism based on Mybatis
  • There is no need to write SQL to solve common single-table CURD operations
  1. Introduce dependencies in POM.xml

    <dependency>
        <groupId>tk.mybatis</groupId>
        <artifactId>mapper</artifactId>
        <version>3.1.2</version>
    </dependency>
    Copy the code
  2. Add plugin configuration to sqlmapconfig.xml

    <plugins>
        <! -- Mapper plugin configuration -->
        <plugin interceptor="tk.mybatis.mapper.mapperhelper.MapperInterceptor">
    		<! Mapper = Mapper; Mapper = Mapper;
            <property name="mappers" value="tk.mybatis.mapper.common.Mapper"/>
        </plugin>
    </plugins>
    Copy the code
  3. Writing entity classes

    @Table("user")
    public class User{
        // Specify the primary key
        @Id
        // Specify the ID generation policy
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        private Integer id;
        private String username;
    }
    Copy the code
  4. Create Mapper

    /** * Mapper */
    public interface UserMapper extends Mapper<User>{}Copy the code
  5. Code demo

    @org.junit.Test
    public void testCommonMapper(a) {
        / / insert
        Order addOrder = new Order();
        addOrder.setUserId(1);
        addOrder.setOrderTime(new Date());
        orderMapper.insert(addOrder);
        System.out.println(addOrder);
    
        / / query
        Order query = new Order();
        query.setId(1);
        Order order = orderMapper.selectOne(query);
        System.out.println(order);
    
        // Customize the query
        Example example = new Example(Order.class);
        // create a query condition e
        // There are many other ways, such as andLike, andBetween...
        example.createCriteria().andEqualTo("userId".1);
    
        List<Order> orders = orderMapper.selectByExample(example);
        for(Order order1 : orders) { System.out.println(order1); }}Copy the code