【SpringBoot】| ORM operation MySQL (integrated MyBatis)

Table of contents

One: ORM operates MySQL 

1. Create a Spring Boot project

2. @MapperScan

3. The mapper file and java code are managed separately

4. Transaction support


One: ORM operates MySQL 

Use the MyBatis framework to operate data, integrate MyBatis in the SpringBoot framework, and use the steps:

(1) mybatis start-up dependency: complete the automatic configuration of mybatis objects, and put the objects in the container

(2) pom.xml specifies to include the xml file in the src/main/java directory into the classpath

(3) Create an entity class Student

(4) Create a Dao interface StudentDao and create a method to query students

(5) Create the Mapper file corresponding to the Dao interface, the xml file, and write the sql statement

(6) Create a Service layer object, create a StudentService interface and its implementation class. The method of removing the dao object to complete the operation of the database

(7) Create a Controller object and access the Service.

(8) Write the application.properties file to configure the connection information of the database.

1. Create a Spring Boot project

(1) Prepare the database table

fields and their types

 insert data

 (2) Create a SpringBoot project

Select Spring Web dependency

MybatisFramework dependency, MySQL Driver dependency

(3) Generated pom.xml configuration and manually added resource plug-in configuration

Note: The resource plug-in configuration means that the *.xml configuration files under src/java/main or subpackages are finally loaded into the target/classes directory.

<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.7.9</version>
        <relativePath/>
    </parent>
    <groupId>com.zl</groupId>
    <artifactId>study-springboot-mysql</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!--web的起步依赖-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!--mybatis的起步依赖-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.3.0</version>
        </dependency>
        <!--mysql驱动依赖-->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>
        <!--测试-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <!--手动添加resources插件-->
        <resources>
            <resource>
                <!--指定目录-->
                <directory>src/main/java</directory>
                <!--指定目录下的文件-->
                <includes>
                    <include>**/*.xml</include>
                </includes>
            </resource>
        </resources>

        <!--plugins插件-->
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

(4) Entity class

Prepare an entity class whose attribute names are consistent with the field names in the database.

package com.zl.pojo;

public class Student {
    private Integer id;
    private String name;
    private Integer age;

    public Student() {
    }

    public Student(Integer id, String name, Integer age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Student{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

(5) Create a Dao interface

You need to add @Mapper annotation to the class : tell MyBatis that this is a dao interface, and create a proxy object for this interface.

package com.zl.dao;

import com.zl.pojo.Student;
import org.apache.ibatis.annotations.Mapper;

@Mapper //用来创建代理对象的
public interface StudentDao {
    // 根据id进行查询
    Student selectById(@Param("stuId") Integer id);
}

(6) Create a StudentDao.xml file with the same name under the Dao interface

Note: The resource configuration we configured earlier is for this StudentDao.xml configuration service!

<?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.zl.dao.StudentDao">
    <!--编写sql语句,id是这条sql语句的唯一表示-->
    <select id="selectById" resultType="com.zl.pojo.Student">
        select id,name,age from t_student where id = #{stuId}
    </select>
</mapper>

(7) Write the Service interface and the corresponding implementation class

StudentService interface

package com.zl.service;

import com.zl.pojo.Student;

public interface StudentService {
    // 方法调用
   Student queryStudent(Integer id);

}

StudentService interface implementation class, write business logic

package com.zl.service.impl;

import com.zl.dao.StudentDao;
import com.zl.pojo.Student;
import com.zl.service.StudentService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

@Service // 交给Spring容器管理
public class StudentServiceImpl implements StudentService {

    // 调用Dao
    @Resource // 给属性赋值
    private StudentDao studentDao;

    @Override
    public Student queryStudent(Integer id) {
        Student student = studentDao.selectById(id);
        return student;
    }
}

(8) Create a controller to call the service

package com.zl.controller;

import com.zl.pojo.Student;
import com.zl.service.StudentService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

@Controller 
public class StudentController {
    @Resource
    public StudentService studentService;
    
    @RequestMapping("/student/query")
    @ResponseBody
    public String queryStudent(Integer id){
        Student student = studentService.queryStudent(id);
        return student.toString();
    }
}

(9) To connect to the database, application.properties configuration is required

useUnicode uses unicode encoding, characterEncoding character set is utf-8, serverTimezone time zone.

server.port=9090
server.servlet.context-path=/orm
#连接数据库的配置
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123

(10) Execution result

2. @MapperScan

If there are multiple Dao interfaces, you need to add the @Mapper annotation to each Dao interface, which is troublesome!

StudentDao interface

package com.zl.dao;

import com.zl.pojo.Student;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface StudentDao {
    // 根据id进行查询
    Student selectById(Integer id);
}

UserDao interface

package com.zl.dao;

import com.zl.pojo.User;
import org.apache.ibatis.annotations.Mapper;

@Mapper
public interface UserDao {
    // 根据id进行查询
    SUser selectById(Integer id);
}

You can also add annotation package scan @MapperScan("com.zl.dao") on the main class (on the startup class)

Note: basePackages is a String array, and multiple packages to be scanned can be written.

package com.zl;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
@MapperScan(basePackages = "com.zl.dao")
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

detail:

If we import a project, IDEA cannot recognize resources, and the icon is as follows:

Right-click the mouse ----"Mark Directory as-----"Resources Root

The icon at this time is as follows: 

3. The mapper file and java code are managed separately

The current xml file and java code are managed under the same package!

 It can also be stored separately, and put the xml file in the resources directory! Create a mapper directory under resources and put all *.xml in it; but it can't be found at this time, we need to configure and specify.

 At this time, you need to specify in the application.properties file:

#指定mapper文件的位置
mybatis.mapper-locations=classpath:mapper/*.xml

Note: At this time, the lower version of Springboot may have the application.properties file not compiled into the target/classes directory. At this time, you need to modify the resources plug-in configuration:

<resources>
     <resource>
       <directory>src/main/resources</directory>
       <includes>
          <include>**/*.properties</include>
          <include>**/*.xml</include>  
       </includes>
     </resource>
</resources>

To see the information of the SQL statement, you need to add the log framework in application.properties

#指定mybatis的日志,使用StdOutImpl输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

At this point, you can see the log information of the SQL statement

4. Transaction support

Transactions in the Spring framework:

(1) Use objects that manage transactions: transaction managers (interfaces, interfaces have many implementation classes)

Example: use Jdbc or mybatis to access the database, the transaction manager used: DataSourceTransactionManager

(2) Declarative transaction: Describe the content of transaction control in the xml configuration file or use annotations

Control transactions: isolation level, propagation behavior, timeout, etc.

(3) Transaction processing method:

① @Transactional in the Spring framework;

② The aspectj framework can declare the content of transaction control in the xml configuration file;

It is very simple to use transactions in SpringBoot, and the bottom layer still uses the transaction management provided by Spring itself

① Add @Transactional above the business method , and after adding the annotation, the method has a transaction function.

②Add @EnableTransactionManager above the main startup class to enable transaction support.

Note: Only adding @Transactional can also complete the transaction function, and it is also recommended to add @EnableTransactionManager.

Step 1: Create a SpringBoot project and introduce: Spring Web, MybatisFramework, MySQL Driver

Step 2: Use the mybatis reverse engineering plug-in to generate a pojo class and a dao interface

①Add Mybatis reverse engineering plug-in

Note: This plug-in requires MySQL driver dependencies. If there is no MySQL driver dependency introduced here, then the <classPathEntry> tag is required in the generatorConfig.xml configuration below to specify the location of the JDBC driver package that connects to the database and specify it on your local machine. The full path, for example: <classPathEntry location="E:\mysql-connector-java-5.1.38.jar"/>.

<!--mybatis逆向⼯程插件-->
<plugin>
     <!--插件的GAV坐标-->
     <groupId>org.mybatis.generator</groupId>
     <artifactId>mybatis-generator-maven-plugin</artifactId>
     <version>1.4.1</version>
    
     <configuration>
            <!--配置文件的位置,放在项目根目录下必须指定一下-->
	       <!--<configurationFile>GeneratorMapper.xml</configurationFile>-->
            <!--允许覆盖-->
           <overwrite>true</overwrite>
     </configuration>
     <!--插件的依赖-->
     <dependencies>
         <!--mysql驱动依赖-->
         <dependency>
               <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>5.1.23</version>
         </dependency>
      </dependencies>
</plugin>

② Write generatorConfig.xml configuration file

Note: If the following generatorConfig.xml configuration file is placed in the resources directory of src, then the name of the configuration file must be generatorConfig.xml (case-insensitive), and the above <configurationFile> tag is not required to specify.

Note: If we put the generatorConfig.xml configuration file directly in the root directory of the project (same level directory as src), then the name of the generatorConfig.xml configuration file is arbitrary at this time, but you must use the above <configurationFile> tag to specify it (Both can be consistent).

Note: Of course, you can not directly put it in the root directory of the project, for example: put it in the src/main directory, then you need to specify src/main/generatorConfig.xml for the <configurationFile> tag (both must be consistent)

Note: For the higher version of the MySQL driver, the time zone must follow the URL, but & cannot be recognized in xml, so you need to use & to replace it, for example:

connectionURL="jdbc:mysql://localhost:3306/springdb?useUnicode=true&amp;characterEncoding=UTF-8&amp;serverTimezone=GMT%2B8"

Finally, the *.xml configuration will be generated. If you want it to be compiled and put into target/classes, you need to configure the processing resource directory

<!--处理资源目录-->
<resources>
    <resource>
       <directory>src/main/java</directory>
       <includes>
             <include>**/*.xml</include>
             <include>**/*.properties</include>
       </includes>
    </resource>
    <resource>
       <directory>src/main/resources</directory>
       <includes>
             <include>**/*.xml</include>
             <include>**/*.properties</include>
       </includes>
    </resource>
</resources>

 generatorConfig.xml configuration

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>


    <!-- 指定连接数据库的JDBC驱动包所在位置,如果前面插件中指定了,这里就不要指定了 -->
    <!--<classPathEntry location="E:\mysql-connector-java-5.1.38.jar"/>-->

    <!--
        targetRuntime有两个值:
            MyBatis3Simple:生成的是基础版,只有基本的增删改查。
            MyBatis3:生成的是增强版,除了基本的增删改查之外还有复杂的增删改查。
    -->
    <context id="DB2Tables" targetRuntime="MyBatis3Simple">
        <!--防止生成重复代码-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin"/>

        <commentGenerator>
            <!--是否去掉生成日期-->
            <property name="suppressDate" value="true"/>
            <!--是否去除注释-->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>

        <!--连接数据库信息-->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
                        connectionURL="jdbc:mysql://localhost:3306/springboot"
                        userId="root"
                        password="123">
        </jdbcConnection>

        <!-- 生成pojo包名和位置 -->
        <javaModelGenerator targetPackage="com.zl.pojo" targetProject="src/main/java">
            <!--是否开启子包-->
            <property name="enableSubPackages" value="true"/>
            <!--是否去除字段名的前后空白-->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!-- 生成SQL映射文件的包名和位置 -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <!--是否开启子包-->
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成Mapper接口的包名和位置 -->
        <javaClientGenerator
                type="xmlMapper"
                targetPackage="com.zl.mapper"
                targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 表名和对应的实体类名-->
        <table tableName="t_Student" domainObjectName="Student"/>

    </context>
</generatorConfiguration>

Double-click the plug-in, the execution result is as follows:

Step 3: Write application.properties configuration

Note: If the StudentMapper.xml directory is consistent with the StudentMapper directory, the following configuration mybatis.mapper-locations=classpath:mapper/*.xml is not required; here we define the mapper directory and put the mapper.xml file in it , so we need to specify its location!

#设置端口
server.port=8082
#配置项目根路径context-path
server.servlet.context-path=/myboot
#配置数据库
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/springboot?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT%2B8
spring.datasource.username=root
spring.datasource.password=123
#配置mybatis
mybatis.mapper-locations=classpath:mapper/*.xml
#配置日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

Step 4: Write service interface and implementation class

StudentService interface

package com.zl.service;

import com.zl.pojo.Student;

public interface StudentService {
    int addStudent(Student student);
}

The implementation class StudentServiceImpl of the StudentService interface

package com.zl.service.impl;

import com.zl.mapper.StudentMapper;
import com.zl.pojo.Student;
import com.zl.service.StudentService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;

@Service // 交给Spring容器管理
public class StudentServiceImpl implements StudentService {

    @Resource // 属性赋值
    private StudentMapper studentDao;

    @Transactional // 事务控制
    @Override
    public int addStudent(Student student) {
        System.out.println("准备执行sql语句");
        int count = studentDao.insert(student);
        System.out.println("已完成sql语句的执行");
        // 模拟异常,回滚事务
        int sum = 10 / 0;

        return count;
    }
}

Step 5: Write the controller class to call the service

package com.zl.controller;

import com.zl.pojo.Student;
import com.zl.service.StudentService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.annotation.Resource;

@Controller
public class StudentController {

    @Resource
    private StudentService studentService;


    @RequestMapping("/addStudent")
    @ResponseBody
    public String addStudent(String name,Integer age){
        Student s = new Student();
        s.setName(name);
        s.setAge(age);
        int count = studentService.addStudent(s);
        return "添加的Student个数是:"+count;
    }
}

Step 6: Add package scanning annotations and startup transaction manager annotations to the startup class

package com.zl;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@MapperScan(basePackages = "com.zl.mapper") // 添加包扫描
@EnableTransactionManagement // 启动事务管理器
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }

}

Step Seven: Run the Test

An exception occurs, the transaction will be rolled back, and data cannot be inserted

 No abnormality occurs, insert data normally

Guess you like

Origin blog.csdn.net/m0_61933976/article/details/129344765