MyBatis extended application

MyBatis extended application

Mybatis PageHelper (paging plug-in)

When using MySQL, we need to use the limit statement to create paging. The logic is very complex and troublesome. Mybatis PageHelper wraps these statements for us. We only need to write a query statement

Import dependent

Build maven project and directly introduce the following dependencies

<!-- mybatis Paging plug-in for -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>5.1.10</version>
</dependency>

Configure interceptor plug-in

Under normal MyBatis, you can directly configure the interceptor plug-in in the global configuration file

	<!--to configure mybatis plug-in unit-->
	<plugins>
		<plugin interceptor="com.github.pagehelper.PageInterceptor"/>
	</plugins>

Under the integrated SSM framework, Spring's attribute configuration method is used

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <!-- Note other configurations -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--Configure parameters in the following way, one per line -->
          <value>
            params=value1
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>

How to use in code

Calling PageHelper.startPage() before querying the method, by observing the official document, it is found that only the first query followed by this method will be paged.

You can use PageInfo to wrap the queried data, which is more powerful than page. You can view the specific usage in the document

https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md

	@Test
	public void test02() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		SqlSession sqlSession = sqlSessionFactory.openSession();
		try {
			EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
            //The first parameter represents the current page number, and the second parameter represents the number of records per page
			Page<Object> page = PageHelper.startPage(5, 2);
			List<Employee> emps = mapper.getEmps();
			//The second parameter is: how many pages are displayed continuously
			PageInfo<Employee> info = new PageInfo<>(emps,5);
			for(Employee emp : emps){
				System.out.println(emp);
			}
			System.out.println("Current page:" + page.getPageNum());
			System.out.println("Records per page:" + page.getPageSize());
			System.out.println("Total page:" + page.getPages());
			System.out.println("Total records:" + page.getTotal());
			System.out.println("First page:" + info.isIsFirstPage());
			int[] nums = info.getNavigatepageNums();
			System.out.println("show page numbers");
			for (int i = 0;i<nums.length;i++){
				System.out.println(nums[i]);
			}
		}finally {
			sqlSession.close();
		}
	}

Batch operation

Previously, when integrating the SSM framework, batch operations were performed through circular splicing of sql statements. Here is another method with stronger performance

When you create an executor by default, you create a simpleexecution, and a batch executor can perform batch operations

	<!--void insertEmp(Employee emp);-->
	<insert id="insertEmp">
		insert into employee (last_name,gender,email) values (#{lastName},#{gender},#{email})
	</insert>
	@Test
	public void test03() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		//Set the method of creating the executor to batch. This is the executor that can execute batch statements. The default is simple
		SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
		long start = System.currentTimeMillis();
		try {
			EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
			for(int i = 0;i < 10000;i++){
				mapper.insertEmp(new Employee(UUID.randomUUID().toString().substring(0 ,5),i + "@123.com","0"));
			}
			sqlSession.commit();
			long end = System.currentTimeMillis();
			System.out.println("Execution duration:" + (end-start));//Execution time: 1592
		}finally {
			sqlSession.close();
		}
	}

Enumeration type handling in MyBatis

MyBatis type processing is implemented by implementing the TypeHandler interface, while enumeration type processing can be used by two processors. Enumeration types are divided into index and name. EnumOrdinalTypeHandler is stored through index and EnumTypeHandle (default) is stored through name

We create an empStatus enumeration attribute based on the employee table

public enum EmpStatus {
    LOGIN,LOGOUT,REMOVE;
}

By default, EnumTypeHandle is used to store to the database, and the stored database value is LOGOUT

	@Test
	public void test04() throws IOException {
		SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
		//Set the method of creating the executor to batch. This is the executor that can execute batch statements. The default is simple
		SqlSession sqlSession = sqlSessionFactory.openSession();
		long start = System.currentTimeMillis();
		try {
			EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
			mapper.insertEmp(new Employee("enum","enum@123.com","1", EmpStatus.LOGOUT));
			sqlSession.commit();
		}finally {
			sqlSession.close();
		}
	}

By modifying the global configuration file, you can modify the default enumeration type processor to EnumOrdinalTypeHandler with a storage value of 1

	<typeHandlers>
		<typeHandler handler="org.apache.ibatis.type.EnumOrdinalTypeHandler" javaType="com.yellowstar.bean.EmpStatus"></typeHandler>
	</typeHandlers>

In the actual development process, we are often not satisfied with using the default enumeration type processor, such as modifying the enumeration class to the following form. If we want to insert custom code or msg data into the database, we need a custom type processor

public enum EmpStatus {
    LOGIN(100,"Logged in"),LOGOUT(200,"Logged out"),REMOVE(300,"non-existent");

    Integer code;
    String msg;
    EmpStatus(Integer code, String msg) {
        this.code = code;
        this.msg = msg;
    }
    public Integer getCode() {return code;}
    public void setCode(Integer code) {this.code = code;}
    public String getMsg() {return msg;}
    public void setMsg(String msg) {this.msg = msg;}
    //Returns an enumeration class object according to code
    public static EmpStatus getEmpStatusByCode(Integer code){
        switch (code){
            case 100:
                return LOGIN;
            case 200:
                return LOGOUT;
            case 300:
                return REMOVE;
            default:
                return LOGOUT;
        }
    }
}

There are two ways to create a custom processor: implement the TypeHandler interface or inherit the BaseTypeHandler class. We use the way to implement the interface and override the method

public class EmpStatusTypeHandler implements TypeHandler<EmpStatus> {
    // Defines how the current data is saved to the database
    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, EmpStatus empStatus, JdbcType jdbcType) throws SQLException {
        System.out.println("Status code to save:" + empStatus.getCode());
        preparedStatement.setInt(i,empStatus.getCode());
    }

    // Get database data
    @Override
    public EmpStatus getResult(ResultSet resultSet, String s) throws SQLException {
        //You need to return an enumeration object according to the enumeration status code obtained from the database
        int code = resultSet.getInt(s);
        System.out.println("Status code obtained from database:"+code);
        EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code);
        return empStatus;
    }

    @Override
    public EmpStatus getResult(ResultSet resultSet, int i) throws SQLException {
        int code = resultSet.getInt(i);
        System.out.println("Status code obtained from database:"+code);
        EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code);
        return empStatus;
    }

    @Override
    public EmpStatus getResult(CallableStatement callableStatement, int i) throws SQLException {
        int code = callableStatement.getInt(i);
        System.out.println("Status code obtained from database:"+code);
        EmpStatus empStatus = EmpStatus.getEmpStatusByCode(code);
        return empStatus;
    }
}

Keywords: Java

Added by wizhippo on Wed, 27 Oct 2021 10:23:54 +0300