Introduction to MyBatis

Keywords: Session Mybatis xml JDBC

Introduction to MyBatis Foundation

content

1. Introduction to MyBatis
 2.MyBatis Starter Program
 3.MyBatis uses Mapper interface
 4. Config file configuration for MyBatis

I. Introduction to MyBatis

1. Introduction

1.Mybatis is consistent with Hibernate and is an open source ORM framework.
MyBatis was originally an open source apache project, iBatis, which was migrated by apache software foundation in 2010
 google code, and renamed MyBatis. Migrated to Github in November 2013. The term iBATIS comes from the combination of "internet" and "abatis", and is a persistent framework based on Java. The persistence framework provided by iBATIS includes SQL Maps and Data Access Objects (sDAO).
2.Mybaits is a lightweight packaging framework for JDBC.
3. XML and annotation are provided to construct the mapping relationship between Java objects and databases. In essence, the mapping between interfaces and Java POJO objects is provided.

The Concept of ORM

ORM:Object Relational Mapping Model for Object Relational Mapping
 The research is:
Java Object-Mapping Relation of Relational Data
 Java Class--Mapping Relation of Table Structure Corresponding to Relational Data
 Additional Mybatis research:
Java Dao Layer Interface--Mapping of Sql Statements

2. Download address

https://github.com/mybatis/mybatis-3/releases
 Version 3.4.6

3. Framework characteristics

1. Easy to learn: It's small and simple. Without any third-party dependencies, the simplest installation is as long as two jar files + configuring several sql mapping files
 It is easy to learn and use. Through the document and source code, we can fully grasp its design ideas and implementation.
2. Flexibility: mybatis does not impose any impact on the existing design of applications or databases. sql is written in xml for unified management and optimization
 Change. With sql, we can basically achieve all the functions we can achieve without using the data access framework, maybe more.
3. Decoupling sql and program code: By providing DAO layer, business logic and data access logic are separated to make the system design clearer and easier.
Maintenance, easier unit testing. The separation of sql and code improves maintainability.
4. Provide mapping labels to support mapping between object and database orm fields
 5. Provide object-relational mapping labels to support object-relational component maintenance
 6. Provide xml tags to support writing dynamic sql

II. MyBaits Starter Program

1. Implementation steps

1. Configure SqlMapConfig.xml(mybatis-config.xml)
2. Configure Mapper.xml file
 3. Create SqlSessionFactory objects
 4. Create SqlSession objects
 5. Use the API provided by SqlSession for CRUD operation

[External Link Picture Transfer Failure (img-AR2XlDgw-1564208065276)(1.bmp)]

2. Life Synchronization of Several Important Objects

1.SqlSessionFactoryBuilder
2.SqlSessionFactory
3.SqlSession
4.Mapper Instances
1. Life cycle of SqlSession FactoryBuilder:
This class can be instantiated, used, and discarded, and once SqlSessionFactory is created, it is no longer needed. Therefore, the best scope of the SqlSessionFactoryBuilder instance is the method scope (that is, local method variables). You can reuse the SqlSession Factory Builder to create multiple SqlSession Factory instances, but it's better not to keep them alive to ensure that all XML parsing resources are open to more important things.
2. Life Cycle of SqlSession Factory
 Once SqlSession Factory is created, it should always exist during the running of the application, and there is no reason to clean it up or rebuild it. The best practice for using SqlSessionFactory is not to create it many times during application run, and rebuilding SqlSessionFactory many times is considered a "bad smell" of code. Therefore, the best scope of SqlSession Factory is the application scope. There are many ways to do this. The simplest way is to use singleton mode or static singleton mode.
3. SqlSession (equivalent to the state object in JDBC)
Each thread should have its own SqlSession instance. An instance of SqlSession is not thread-safe and therefore cannot be shared, so its best scope is the request or method scope. It is absolutely impossible to place references to SqlSession instances in the static domain of a class, even instance variables of a class. References to SqlSession instances should never be placed in any type of administrative scope, such as HttpSession in the Servlet architecture. If you are using a Web framework now, consider SqlSession in a scope similar to HTTP request objects. In other words, every time an HTTP request is received, an SqlSession can be opened, a response returned, and it can be closed. This closing operation is very important. You should put this closing operation in the final block to ensure that closing can be performed every time.
4.Mapper Instances Life Cycle (Generated Dynamic Proxy Objects)
A mapper is an interface you create to bind the statements you map. An example of the mapper interface is obtained from SqlSession. So technically, the maximum scope of any mapper instance is the same as the SqlSession that requests them. Nevertheless, the best scope for a mapper instance is the method scope. That is to say, mapper instances should be requested in the method that calls them, and then discarded. There's no need to explicitly close the mapper instance, and although there's no problem keeping the mapper instance throughout the request scope, you'll soon find it difficult to manage too many resources in this scope, like SqlSession. So to keep it simple, it's better to put the mapper in the method scope.

3. Initial Procedures

1. Create mybatis-config.xml in the resources directory

<?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>
    <! - Load the external properties file - >
    <properties resource="db.properties"></properties>
    <! -- default denotes the database connection environment currently in use, if it points to the ID of an environment tag,
    Represents using this environment as the current connection environment - >
    <environments default="development">
        <! - Id represents the identity of the current connection environment - >.
        <environment id="development">
            <! - Transaction management:
            type has two values (JDBC|MANAGED)
       1.JDBC - This configuration uses JDBC's commit and rollback settings directly and relies on connections from data sources to manage transaction scopes.
       2.MANAGED - This configuration does little. It never commits or rolls back a connection, but lets the container manage the entire lifecycle of the transaction.
            (For example, the context of a JEE application server)
            Note: If you are using Spring + MyBatis, there is no need to configure the transaction manager.
            Because the Spring module uses its own manager to override the previous configuration.
            -->
            <transactionManager type="JDBC"/>
            <! - Data source configuration:
            There are three type s (UNPOOLED|POOLED|JNDI)
            1.UNPOOLED - The implementation of this data source is to open and close the connection each time it is requested. Although a little slow,
            But it's a good choice for simple applications that don't require too much database connection availability.
            Different databases perform differently in terms of performance. For some databases,
            It's not important to use connection pools, and this configuration is suitable for this situation.
            2.POOLED - The implementation of this data source uses the concept of "pool" to organize JDBC connection objects.
            The initialization and authentication time required to create a new connection instance is avoided.
            This is a popular way to make concurrent Web applications respond quickly to requests.
            3.JNDI - This data source is implemented for use in containers such as EJB or application servers.
            Containers can centralize or configure data sources externally, and then place a reference to the JNDI context
            -->
            <dataSource type="POOLED">
                <! - Database Connection Information - >
                <property name="driver" value="${db.driver}"/>
                <property name="url" value="${db.url}"/>
                <property name="username" value="${db.username}"/>
                <property name="password" value="${db.password}"/>
            </dataSource>
        </environment>
    </environments>

    <! - The introduction of mapping relations - >
    <mappers>
        <mapper resource="mapper/UserMapper.xml"/>
    </mappers>
</configuration>

2. Create db.properties in the resources directory

db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://192.168.1.165:3306/javaee
db.username=root
db.password=123456

3. Create log4j.properties in the resources directory

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# MyBatis logging configuration...
#log4j.logger.org.mybatis.example.BlogMapper=TRACE
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

4.pom.xml file configuration

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.sy</groupId>
    <artifactId>mybatis_day01</artifactId>
    <version>1.0-SNAPSHOT</version>

    <dependencies>

        
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
      
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.17</version>
        </dependency>

      
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.40</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>
    <build>
        <resources>
            <resource>
                <directory>src/main/java</directory>
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
                <includes>
                    <include>**/*.xml</include>
                    <include>**/*.properties</include>
                </includes>
            </resource>
        </resources>
    </build>
</project>

5. Create the XXXMapper.xml file under the mapper package

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Interfaces and sql Statement mapping-->
<mapper namespace="mapper.UserMapper">

    <select id="selectAll" resultType="model.User">
        select * from User
    </select>
    <!--If it is a basic type and String type,#{parameter name} is unrestricted. -->
    <select id="selectById" resultType="model.User" parameterType="java.lang.Integer">
        select * from user where id = #{id}
    </select>
    <!--If the parameter is POJO,#{parameter name}, the parameter name must be the get method suffix string in the POJO, initially lowercase - >
    <insert id="insert" parameterType="model.User">
        insert into user (username,password) values(#{username},#{password})
    </insert>

    <delete id="delete" parameterType="java.lang.Integer">
        delete from User where id = #{id}
    </delete>

    <update id="update" parameterType="model.User">
        update user set username=#{username},password=#{password} where id=#{id}
    </update>

</mapper>

6. Create SqlSession objects

public class DBUtil {

    static SqlSessionFactory factory;

    static{
        String config = "mybatis-config.xml";
        try {
            SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
            InputStream is =  Resources.getResourceAsStream(config);
            factory = builder.build(is);
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    /**
     * Return SqlSession object
     * @return
     */
    public static SqlSession openSqlSession(){
        return factory.openSession();
    }
}

7. Implementing Dao Layer CRUD Operation

public class UserDao {
    public void insert(User user){
		//SqlSession as Method Scope
        SqlSession session = DBUtil.openSqlSession();
        try {
            session.insert("mapper.UserMapper.insert",user);
            //Submission transaction
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            //rollback
            session.rollback();
        }finally {
            //Close session
            session.close();
        }

    }

    public void delete(int id){
        SqlSession session = DBUtil.openSqlSession();
        try {
            session.delete("mapper.UserMapper.delete",id);
            //Submission transaction
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }

    public void update(User user){

        SqlSession session = DBUtil.openSqlSession();
        try {
            session.update("mapper.UserMapper.update",user);
            //Submission transaction
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }

    public User selectById(int id){

        SqlSession session = DBUtil.openSqlSession();
        User user = null;
        try {
            user = session.selectOne("mapper.UserMapper.selectById",id);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            session.close();
        }
        return user;
    }

    public List<User> selectAll(){

        SqlSession session = DBUtil.openSqlSession();
        List<User> users = null;
        try {
            users = session.selectList("mapper.UserMapper.selectAll");
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            session.close();
        }
        return users;
    }
}

8. Unit testing

public class TestDao {
    UserDao dao;
    @Before
    public void init(){
        dao = new UserDao();
    }

    @Test
    public void testInsert(){
        User user = new User();
        user.setUsername("jack");
        user.setPassword("1234");
        dao.insert(user);
    }

    @Test
    public void testUpdate(){

        User user = new User();
        user.setId(4);
        user.setUsername("jack");
        user.setPassword("0000");
        dao.update(user);
    }

    @Test
    public void testDelete(){
        int id = 4;
        dao.delete(id);
    }

    @Test
    public void testSelectAll(){
       List<User> list = dao.selectAll();
        System.out.println(list);
    }

    @Test
    public void testSelectById(){
        int id = 1;
        User user = dao.selectById(id);
        System.out.println(user);
    }
}

Practice

1. Set up Mybatis environment and perform CURD operation on records in User table in data.

3. MyBatis uses Mapper interface

1. Use Mapper Mapper Mapper

In order to meet the requirement of Interface-oriented programming in Javak, mybatis will create proxy objects for interface layer (Dao layer) by using JDK dynamic proxy. Calling API in proxy objects can perform CRUD operations.

2. Development Specification

1. The fully qualified name of the mapper interface should have the same value as the namespace of the mapper mapping file.
	The mapper file and the interface are bound together to realize the mapping between the interface and the mapper file. Meanwhile, the mapping between the method in the interface and the sql statement in the mapper file is realized.
2. The method name of the mapper interface should be the same as the id of the state in the mapper mapping file.
3. The method parameters of the mapper interface can only have one, and the type should be kept with the value of the parameterType of the state in the mapper mapping file.
Agreement.
4. The return value type of the mapper interface should be the same as the resultType value of the state in the mapper mapping file or the type value in the resultMap.
Cause;

3. Code Implementation

//Mapper interface
/**
 * 1.Interface and UserMapper.xml file mapping (add mapper.xml file - > parse namespace - > find the bound interface)
 */
public interface UserMapper {

    /**
     * Mapping Method in Interface and sql Statement in Mapper.xml File
     * 1.The method name is identical to the id value of the sql tag
     * 2.The parameters must be single, and the parameter type is the same as the parameterType type.
     * 3.The return value type should be the same as the resultType type.
     * @param user
     */
    void insert(User user);

    void delete(int id);

    void update(User user);

    List<User> selectAll();

    User selectById(int id);

}
<!--Mapper.xml file-->

<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--Interfaces and sql Statement mapping-->
<mapper namespace="mapper.UserMapper">
    <!--Statement mapper_UserMapper_selectAll = Connection.prepareament()-->
    <select id="selectAll" resultType="model.User">
        select * from User
    </select>
    <!--If it is a basic type and String type,#{parameter name} is unrestricted. -->
    <select id="selectById" resultType="model.User" parameterType="java.lang.Integer">
        select * from user where id = #{id}
    </select>
    <!--If the parameter is POJO,#{parameter name}, the parameter name must be the get method suffix string in the POJO, initially lowercase - >
    <insert id="insert" parameterType="model.User">
        insert into user (username,password) values(#{username},#{password})
    </insert>

    <delete id="delete" parameterType="java.lang.Integer">
        delete from User where id = #{id}
    </delete>

    <update id="update" parameterType="model.User">
        update user set username=#{username},password=#{password} where id=#{id}
    </update>

</mapper>

//Service class
public class UserService {
    public void save(User user){
        SqlSession session = DBUtil.openSqlSession();
        try {
            //Returns a proxy object of the Mapper interface whose scope of action is method scope, the same as session scope
            //Create proxy objects through JDK dynamic proxy.
            UserMapper mapper = session.getMapper(UserMapper.class);
            mapper.insert(user);
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }

    public void remove(int id){

        SqlSession session = DBUtil.openSqlSession();
        try {
         
            UserMapper mapper = session.getMapper(UserMapper.class);
            mapper.delete(id);
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }

    public void modify(User user){

        SqlSession session = DBUtil.openSqlSession();
        try {
           
            UserMapper mapper = session.getMapper(UserMapper.class);
            mapper.update(user);
            session.commit();
        }catch (Exception e){
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }

    public List<User> findAll(){
        SqlSession session = DBUtil.openSqlSession();
        List<User> list = null;
        try {
           
            UserMapper mapper = session.getMapper(UserMapper.class);
            list = mapper.selectAll();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            session.close();
        }

        return list;
    }

    public User findById(int id){

        SqlSession session = DBUtil.openSqlSession();
        User user = null;
        try {
           
            UserMapper mapper = session.getMapper(UserMapper.class);
            user = mapper.selectById(id);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            session.close();
        }
        return user;
    }
}

//Test class
public class TestUserService {

    UserService ser = new UserService();

    @Test
    public void findAll(){

        List<User> list = ser.findAll();

        System.out.println(list);
    }

    @Test
    public void findById(){

        User user = ser.findById(1);

        System.out.println(user);
    }

    @Test
    public void testSave(){

        User user = new User();
        user.setUsername("kevin");
        user.setPassword("1111");

        ser.save(user);
    }

    @Test
    public void testModify(){

        User user = new User();
        user.setId(5);
        user.setUsername("kevin");
        user.setPassword("0000");

        ser.modify(user);
    }

    @Test
    public void testRemove(){

        ser.remove(5);
    }
}

4. Common Config File Configuration for MyBatis

1. Common configurations

1.properties Label Configuration
 2.settings Label Configuration
 3. TypeeAlias Label Configuration
 4. Environment Label Configuration
 5. Configuration of mappers mapping labels

2.properties Label Configuration

Corresponding attributes:
1.resource
	Generally, mapper mapping files are introduced by relative paths
2.url
	Generally, the mapping file of the corresponding disk location is introduced by absolute path, and the resource file on the network can also be introduced by http.
Sublabel property label:
Setting property attributes by key and value is equivalent to configuring external resources in the properties tag through the tag

If attributes are configured in more than one place, MyBatis will be loaded in the following order:

The external configuration loaded by the resource attribute overrides the configuration of the same name attribute in the property subtag.
<properties resource="db.properties">
  <property name="url" value="jdbc:mysql://192.168.1.165:3306/javaee"/>
  <property name="driver" value="com.mysql.jdbc.Driver"/>
  <property name="username" value="root"/>
  <property name="password" value="123456"/>
</properties>

3.settings Label Configuration

Used to set the global behavior of mybatis.
<settings>
	<setting name="logImpl" value="LOG4J" />
    ........
</settings>

4. TypeeAlias Label Configuration

Alias the model model class in the mapper.xml file.
  <typeAliases>
      	<!--Aliasing the corresponding type-->
        <typeAlias type="model.User" alias="User"></typeAlias>
   </typeAliases>
  <typeAliases>
        <! - Aliases all the classes in the model package with the corresponding class names - >.
        <package name="model"></package>
    </typeAliases>

5. Environment Label Configuration

<environments default="development">
  <environment id="development">
    <transactionManager type="JDBC">
      <property name="..." value="..."/>
    </transactionManager>
    <dataSource type="POOLED">
      <property name="driver" value="${driver}"/>
      <property name="url" value="${url}"/>
      <property name="username" value="${username}"/>
      <property name="password" value="${password}"/>
    </dataSource>
  </environment>
</environments>
1.default attribute:
	The default connection environment, usually pointing to the id of the environment label
 2.environment subtags
	Used to configure the connection environment, the id attribute refers to the unique identity of the connection environment.
3. Transaction Manager tag
	Set transaction management policy with type attribute values of JDBC or MANAGED
	JDBC: Represents using JDBC transaction management
	MANAGED: Represents having a designated application server container for transaction management
	If the transaction is managed by spring, this setting will be overwritten.
4. Data Source tag
	Used to configure data sources (database connection information), take values POOLED,UNPOOLED,JNDI
	POOLED: Represents the use of connection pools to manage connection objects
	UNPOOLED: Without connection pooling, a new Connection object is created each time and destroyed after use.
	JNDI: Connection pairs generated using the application server.
	If the data source is created by spring, this setting will be overwritten.

6. Configuration of mappers mapping labels

<! - Use resource references relative to class paths - >
<mappers>
  <mapper resource="mapper/UserMapper.xml"/>
  .....
</mappers>
<! - Use fully qualified resource locators (URL s) -->
<mappers>
  <mapper url="file:///var/mapper/UserMapper.xml"/>
  .....
</mappers>
<! - Fully qualified class names using mapper interfaces
 <! - Load the interface first, and then the mapper.xml file: The xml file under the package where the interface is located will be loaded, and the file name must be the same as the interface - >.
<mappers>
  <mapper class="mapper.UserMapper"/>
  ....
</mappers>
<! - Register all the mapper interfaces in the package as mappers. Scan the interfaces in the mapper package as follows
 <! - Load the interface first, and then the mapper.xml file: The xml file under the package where the interface is located will be loaded, and the file name must be the same as the interface - >.
<mappers>
  <package name="mapper"/>
</mappers>

Practice

CRUD operation by creating Mapper interface proxy object

Posted by hlstriker on Fri, 26 Jul 2019 23:23:55 -0700