Introduction of framework

Three layer architecture

A common architecture for software development is the three-tier architecture, which is popular because of the clear division of tasks. It generally consists of the following three layers:

  • Persistence layer: mainly completes the operations related to the database, that is, the increase, deletion, change and check of the database. Because the objects accessed by databases are generally called Data Access Objects (DAO for short), some people call the persistence layer DAO layer.
  • Business layer: mainly according to functional requirements to complete the definition and implementation of business logic. The Business layer is called the Service layer or Business layer because it mainly provides services for the upper layer.
  • Presentation layer: mainly to complete the interaction with the final software users, need to have an interactive interface (UI). Therefore, some people call the presentation layer the Web layer or the View layer.

The invocation relationship between the three layers is as follows: the presentation layer invokes the business layer, and the business layer invokes the persistence layer. There must be data interaction between the layers, and we typically use Java entity objects to pass data.

The framework

What is a framework?

A framework is a set of specifications, and since it is a specification, you must follow the constraints that the framework imposes. Framework can be understood as semi-finished software. After the framework is completed, it is developed on the basis of it.

Why use frames?

The framework encapsulates some redundant, low-reuse code for us. And the use of reflection and dynamic proxy mechanism, the code to achieve universal, let developers focus on the core business code implementation. For example, when using servlet for development, we need to get the parameters of the form in the servlet, and it is very troublesome to get the parameters every time, and the framework uses reflection mechanism and interceptor mechanism to help us get the values of the form. When using JDBC, we have to write SQL every time we do simple CRUD, but with the framework, we do not need such trouble. Just call the method. Of course, since you are using a framework, you still need to follow some of its specifications

Common Frameworks

There are a lot of frameworks in the Java world, and each one is designed to solve some part or problem. Here are a few frameworks that are popular in the enterprise today (it’s important to note which layer of problems they address) :

  • Persistence layer framework: a framework focused on data persistence. Mybatis, Hibernate, Spring JDBC, etc.
  • Presentation layer frameworks: Frameworks that focus on addressing user interactions. Common examples are Struts2, Spring MVC, and so on.
  • Full-stack framework: a framework that provides solutions at all levels. The famous one is Spring.

Spring + Spring MVC + Mybatis (SSM)

Introduction of Mybatis

MyBatis is an excellent semi-automatic lightweight persistence layer framework based on ORM, it encapsulates the process of JDBC operation database, so that developers only need to pay attention to SQL itself, You do not need to spend effort to deal with JDBC complex process code such as driver registration, connection creation, statement creation, manual parameter setting, result set retrieval, etc

Mybatis history

MyBatis is an open source project of Apache iBatis. In June 2010, this project was migrated to Google Code by Apache Software Foundation. As the development team moved to Google Code, IBatis officially changed its name to MyBatis, and the code was migrated to Github in November 2013. Github address: github.com/mybatis/myb…

The ORM thought

Relational Mapping O (Object model) : Entity objects, that is, we in the program according to the database table structure of each entity javaBean R (Relational database data structure) : Relational database domain M (mapping) : MAPPING from R (database) to O (object model) through XML file mapping: (1) let the entity class and database table one-to-one mapping relationship first let the entity class and database table corresponding to the entity class attributes and fields in the table corresponding (2) do not need to directly operate the database table, directly operate the table corresponding entity class object

ORM is an idea that helps us track entity changes and translate entity changes into SQL scripts that are executed in the database, that is, mapping entity changes to table changes. Mybatis uses ORM to solve the problem of entity and database mapping, encapsulates JDBC, shields the JDBC API access details, so that we do not need to deal with JDBC API, we can complete the database persistence operation

Mybatis quick start

MyBatis development steps

MyBatis official website address: www.mybatis.org/mybatis-3/ Case requirements: Query all records of the database user table through MyBatis, encapsulate the user object, and print to the console step analysis:

MySQL > create database and user table 2. Create maven project, import dependencies (MySQL driver, mybatis, junit) 3. Write User entity class 4. Write usermapper. XML mapping configuration file (ORM idea) 5. Sqlmapconfig. XML core configuration file Database environment configuration import mapping configuration (import mapping configuration file path) 6. Write test code // 1. Load core configuration file // 2. Get sqlSessionFactory factory object // 3. Obtain the sqlSession session object // 4. Run SQL // 5. Print a result // 6. Release resourcesCopy the code

Code implementation

1) Create table user

CREATE DATABASE `mybatis_db`; 
USE `mybatis_db`; 

CREATE TABLE `user` ( 
    `id` int(11) NOT NULL auto_increment, 
    `username` varchar(32) NOT NULL COMMENT 'User name'.`birthday` datetime default NULL COMMENT 'birthday'.`sex` char(1) default NULL COMMENT 'gender'.`address` varchar(256) default NULL COMMENT 'address',
    PRIMARY KEY (`id`))ENGINE=InnoDB DEFAULT CHARSET=utf8;

-- insert.... 
insert into `user`(`id`.`username`.`birthday`.`sex`.`address`) values (1.'son desire'.'2020-11-11 00:00:00'.'male'.'Beijing Haidian'), (2.'should be Britain'.'2020-12-12 00:00:00'.'male'.'Beijing Haidian');
Copy the code

2) Import the coordinates of MyBatis and other relevant coordinates

<! -- Specify code and version --> 
<properties> 
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.encoding>UTF-8</maven.compiler.encoding>
    <java.version>1.11</java.version>
    <maven.compiler.source>1.11</maven.compiler.source>
    <maven.compiler.target>1.11</maven.compiler.target>
</properties> 

<! - mybatis coordinates - > 
<dependency> 
    <groupId>org.mybatis</groupId> 
    <artifactId>mybatis</artifactId> 
    <version>3.5.4</version> 
</dependency> 

<! -- Mysql driver --> 
<dependency> 
    <groupId>mysql</groupId> 
    <artifactId>mysql-connector-java</artifactId> 
    <version>5.1.6</version> 
    <scope>runtime</scope> 
</dependency> 

<! -- Unit test coordinates --> 
<dependency> 
    <groupId>junit</groupId> 
    <artifactId>junit</artifactId> 
    <version>4.12</version> 
    <scope>test</scope> 
</dependency>
Copy the code

3) Write the User entity

public class User { 
    private Integer id; 
    private String username; 
    private Date birthday; 
    private String sex; 
    private String address; 
    / / getter/setter slightly
}
Copy the code

4) Write UserMapper mapping file


       
<! DOCTYPEmapper 
    PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="UserMapper"> 
    <! Select * from 'all'; 
    <select id="findAll" resultType="com.lagou.domain.User"> 
        select * from user 
    </select> 
</mapper>
Copy the code

5) Compile MyBatis core file


       
<! DOCTYPEconfiguration 
    PUBLIC "- / / mybatis.org//DTD Config / 3.0 / EN" 
    "http://mybatis.org/dtd/mybatis-3-config.dtd"> 
<configuration> 
    <! -- Environment Configuration --> 
    <environments default="mysql"> 
        <! -- Use MySQL --> 
        <environment id="mysql"> 
            <! Jdbc-type transaction manager --> 
            <transactionManager type="JDBC"></transactionManager> 
            <! -- Use connection pool --> 
            <dataSource type="POOLED"> 
                <property name="driver" value="com.mysql.jdbc.Driver"> </property>
                <property name="url" value="jdbc:mysql:///mybatis_db"> </property>
                <property name="username" value="root"></property> 
                <property name="password" value="root"></property> 
            </dataSource> 
        </environment> 
    </environments> 
    
    <! -- Load mapping configuration --> 
    <mappers> 
        <mapper resource="com/lagou/mapper/UserMapper.xml"></mapper> 
    </mappers> 
</configuration>
Copy the code

6) Write test classes

@Test 
public void testFindAll(a) throws Exception { 
    // Load the core configuration file
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the SqlSessionFactory object
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 
    // Obtain the SqlSession session object
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    / / SQL execution
    List<User> list = sqlSession.selectList("UserMapper.findAll"); 
    for (User user : list) { 
        System.out.println(user); 
    }
    // Release resources
    sqlSession.close(); 
}
Copy the code

Knowledge summary

Alter table mybatis_DB; alter table user; Create a mapping file usermapper.xml 5. Write the core file SQLmapconfig. XML 6. Write the test classCopy the code

Mybatis mapping file overview

Mybatis add delete change check

new

1) Write the mapping file usermapper.xml

<! -- -- -- > new 
<insert id="save" parameterType="com.lagou.domain.User"> 
    insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) 
</insert>
Copy the code

2) Write test classes

@Test 
public void testSave(a) throws Exception { 
    // Load the core configuration file
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the SqlSessionFactory object
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 
    // Obtain the SqlSession session object
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    / / SQL execution
    User user = new User(); 
    user.setUsername("jack"); 
    user.setBirthday(new Date()); 
    user.setSex("Male"); 
    user.setAddress("Haidian, Beijing"); 
    sqlSession.insert("UserMapper.save", user); 
    
    // DML statement to manually commit transaction
    sqlSession.commit(); 
    // Release resources
    sqlSession.close(); 
}
Copy the code

3) Added notes

- Insert statements use insert tags - specify the data type to be inserted using the parameterType attribute in the mapping file - Sql statements use #{entity attribute name} to reference attribute values in the entity - The API used for the insert operation is sqlSession.insert(" namespace.id ", entity object); - Insert operations involve database data changes, so use the commit transaction displayed in the sqlSession object, sqlSession.com MIT ()Copy the code

Modify the

1) Write the mapping file usermapper.xml

<! - change - > 
<update id="update" parameterType="com.lagou.domain.User"> 
    update user set username = #{username},birthday = #{birthday}, sex = #{sex},address = #{address} where id = #{id} 
</update>
Copy the code

2) Write test classes

@Test 
public void testUpdate(a) throws Exception { 
    // Load the core configuration file
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the SqlSessionFactory object
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 
    // Obtain the SqlSession session object
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    / / SQL execution
    User user = new User(); 
    user.setId(4); 
    user.setUsername("lucy"); 
    user.setBirthday(new Date()); 
    user.setSex("Female"); 
    user.setAddress("Beijing Chaoyang"); 
    sqlSession.update("UserMapper.update", user); 
    
    // DML statement to manually commit transaction
    sqlSession.commit(); 
    // Release resources
    sqlSession.close(); 
}
Copy the code

3) Modify notes

Update (" namespace.id ", entity object); update(" namespace.id ", entity object);Copy the code

delete

1) Write the mapping file usermapper.xml

<! - delete - > 
<delete id="delete" parameterType="java.lang.Integer"> 
    delete from user where id = #{id} 
</delete>
Copy the code

2) Write test classes

@Test 
public void testDelete(a) throws Exception { 
    // Load the core configuration file
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the SqlSessionFactory object
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 
    // Obtain the SqlSession session object
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    / / SQL execution
    sqlSession.delete("UserMapper.delete".50); 
    // DML statement to manually commit transaction
    sqlSession.commit(); 
    // Release resources
    sqlSession.close(); 
}
Copy the code

3) Delete notes

- Delete statement using delete tag - Sql statement using #{arbitrary string} reference to a single parameter passed - delete operation using API sqlsession. delete(" namespace.id ",Object);Copy the code

Knowledge summary

List<User> List = sqlsession.selectList (" usermapper.findAll "); <select id="findAll" resultType="com.lagou.domain.User"> select * from User </select> *  sqlSession.insert("UserMapper.save", user); Mapping file:  <insert id="save" parameterType="com.lagou.domain.User"> insert into user(username,birthday,sex,address) Values (#{username},#{birthday},#{sex},#{address}) </insert> Mapping file:  <update id="update" parameterType="com.lagou.domain.User"> update user set username = #{username},birthday = #{birthday}, sex = #{sex},address = #{address} where id = #{id} </update>  sqlSession.delete("UserMapper.delete", 4); ParameterType ="java.lang.Integer"> delete from user where id= #{id} </delete>Copy the code

Mybatis core file overview

MyBatis core profile hierarchy

The MyBatis configuration file contains Settings and property information that will deeply affect MyBatis behavior. The top-level structure of the configuration document is as follows:

MyBatis common configuration parsing

1) environments

Configure the database environment and support multi-environment configuration

1. There are two types of transactionManager: - JDBC: this configuration directly uses the commit and rollback Settings of JDBC. It relies on the connection from the data source to manage transaction scope. - MANAGED: This configuration does almost nothing. It never commits or rolls back a connection, but lets the container manage the entire life cycle of the transaction. For example, after mybatis is integrated with Spring, transactions are managed by the Spring container. -unpooled: the implementation of this dataSource only opens and closes the connection each time it is requested. - POOLED: This data source implementation uses the concept of "pooling" to organize JDBC connection objects. -JNDI: This data source implementation is intended for use in a container such as an EJB or application server. The container can centrally or externally configure the data source and then place a data source reference for the JNDI contextCopy the code

2) Properties tag

In practice, it is customary to extract the data source configuration information separately into a properties file. This tag can load additional configured properties:

jdbc.driver=com.mysql.jdbc.Driver 
jdbc.url=jdbc:mysql:///mybatis_db 
jdbc.username=root 
jdbc.password=root
Copy the code

3) typeAliases tag

A type alias is a short name for a Java type. In order to simplify the mapping file Java type setting, mybatis framework set some common type aliases for us:

The original type name is as follows:

Configure typeAliases to alias com.lagou.domain.User to User:

4) Mappers tag

The label is used to load the mapping. The loading methods are as follows:

1. Using the relative to the classpath resource references, for example: < mapper resource = "org/mybatis/builder/userMapper. XML" / > 2. Use fully qualified resource locator (URL), for example: < mapper URL = "file:///var/mappers/userMapper.xml" / > "the development of the following two mapper agent used in: temporary understanding, 3. Using the mapping interface implementation class's fully qualified class name, for example: < mapper class = "org. Mybatis. Builder. UserMapper" / > 4. Register all mapper interface implementations within the package as mapper, for example: <package name="org.mybatis. Builder "/>Copy the code

Knowledge summary

Common configuration of core configuration files:

Properties tag: This tag loads external properties files

<properties resource="jdbc.properties"></properties>
Copy the code

TypeAliases tag: Sets the type alias

<typeAlias type="com.lagou.domain.User" alias="user"></typeAlias>
Copy the code

Mappers tag: loads the mapping configuration

<mapper resource="com/lagou/mapper/UserMapping.xml"></mapper>
Copy the code

The Environments TAB: Data source environment configuration

<environments default="development"> 
    <environment id="development"> 
        <transactionManager type="JDBC"/> 
        <dataSource type="POOLED"> 
            <property name="driver" value="${jdbc.driver}"/> 
            <property name="url" value="${jdbc.url}"/> 
            <property name="username" value="${jdbc.username}"/> 
            <property name="password" value="${jdbc.password}"/> 
        </dataSource> 
    </environment> 
</environments>
Copy the code

Mybatis API Overview

The API is introduced

SqlSessionFactoryBuilder SqlSessionFactoryBuilder

SqlSessionFactory build(InputStream InputStream) builds an SqlSessionFactory object by loading the InputStream of the mybatis core file

String resource = "org/mybatis/builder/mybatis-config.xml"; 
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
Copy the code

The Resources utility class is in the org.apache.ibatis. IO package. The Resources class helps you load resource files from the classpath, file system, or a Web URL.

SqlSessionFactory object SqlSessionFactory

SqlSessionFactory has several methods for creating SqlSession instances. There are two commonly used ones as follows:

SqlSession Session object

SqlSession instances are a very powerful class in MyBatis. Here you’ll see all the methods for executing statements, committing or rolling back transactions, and getting mapper instances. The main methods for executing a statement are:

<T> T selectOne(String statement, Object parameter) 
<E> List<E> selectList(String statement, Object parameter) 
int insert(String statement, Object parameter) 
int update(String statement, Object parameter) 
int delete(String statement, Object parameter)
Copy the code

The main methods of handling transactions are:

void commit(a) 
void rollback(a)
Copy the code

Mybatis basic principle introduction

Mybatis dao layer development use

Traditional development

1) Write UserMapper interface

public interface UserMapper { 
    
    public List<User> findAll(a) throws Exception; 
    
}
Copy the code

2) Write UserMapper implementation

public class UserMapperImpl implements UserMapper { 
    @Override 
    public List<User> findAll(a) throws Exception { 
        // Load the configuration file
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
        // Get the SqlSessionFactory object
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
        // Get the SqlSe session object
        SqlSession sqlSession = sqlSessionFactory.openSession(); 
        / / SQL execution
        List<User> list = sqlSession.selectList("UserMapper.findAll"); 
        // Release resources
        sqlSession.close(); 
        returnlist; }}Copy the code

3) Write usermapper.xml


       
<! DOCTYPEmapper 
    PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="UserMapper"> 
    <! Select * from 'all'; 
    <select id="findAll" resultType="user"> 
        select * from user 
    </select> 
</mapper>
Copy the code

4) test

@Test 
public void testFindAll(a) throws Exception { 
    // Create UserMapper implementation class
    UserMapper userMapper = new UserMapperImpl(); 
    // Execute the query
    List<User> list = userMapper.findAll(); 
    for(User user : list) { System.out.println(user); }}Copy the code

5) Knowledge summary

Traditional development

Write UserMapper interface 2. Write UserMapper implementation 3. Write UserMapper. XMLCopy the code

Traditional way of thinking:

1. Mybatis template code duplication exists in the implementation class 2. SQL statement in XML is hardcoded into Java code when the implementation class calls methods. Just write the interface and mapper.xml? Sqlsession is used similarly in dao (Mapper) implementation classes. Therefore, Mybatis provides dynamic proxy of the interface.

Agent development approach

1) introduction

Mybatis based on the interface proxy way to achieve the development of persistent layer, this way is we later into the mainstream of the enterprise. The development based on interface proxy only requires programmers to write Mapper interface, and Mybatis framework will dynamically generate the object of the implementation class for us.

This approach requires us to follow certain specifications:

  • The namespace in the mapper. XML mapping file is the same as the fully qualified name of the Mapper interface
  • The Mapper interface method name is the same as the ID of each statement defined in the mapper. XML mapping file
  • The input parameter types for the Mapper interface methods are the same type as parameterType for each SQL defined in the mapper.xml mapping file
  • The output parameter type of the Mapper interface method is the same type as the resultType of each SQL defined in the mapper.xml mapping file

Mapper interface development method only requires programmers to write Mapper interface (equivalent to Dao interface), and Mybatis framework creates dynamic proxy object of interface according to interface definition. The method body of proxy object implements class method with Dao interface above.

2) Write UserMapper interface

public interface UserMapper { 
    
    public List<User> findAll(a) throws Exception; 
    
}
Copy the code

3) Write usermapper.xml


       
<! DOCTYPEmapper 
    PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> 
<mapper namespace="com.lagou.mapper.UserMapper"> 
    <! Select * from 'all'; 
    <select id="findAll" resultType="user"> 
        select * from user 
    </select> 
</mapper>
Copy the code

4) test

@Test 
public void testFindAll(a) throws Exception { 
    // Load the core configuration file
    InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml"); 
    // Get the SqlSessionFactory object
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); 
    // Get the SqlSession session object
    SqlSession sqlSession = sqlSessionFactory.openSession(); 
    // Get the Mapper proxy object
    UserMapper userMapper = sqlSession.getMapper(UserMapper.class); 
    // Execute the query
    List<User> list = userMapper.findAll(); 
    for (User user : list) { 
        System.out.println(user); 
    }
    // Release resources
    sqlSession.close(); 
}
Copy the code

5) Internal execution principle of Mybatis based on interface proxy

Our persistence layer now has only one interface, and the interface doesn’t actually do the work, so who does the actual work of the query?

  • Here is a look at the source code by tracking:

1. By tracing the source code, we will find that the Mapper we use is actually a proxy object, which is generated by MapperProxy.

2. Trace the invoke method of MapperProxy and find that it ends up calling mapperMethod.execute(sqlSession, args).

SQL > execute (); sqlSession ()