This is the 15th day of my participation in the August More Text Challenge. For details, see:August is more challenging
【DB series 】Mybatis series tutorial CURD basic use posture
Mybatis, as the ORM framework of data, is still very considerable in the domestic application market. When I first started to work, I used Spring + Mybatis for development, and then I also used Hibernate, JDBCTemplate, JooQ. Mybatisplus and other frameworks,
In terms of personal use feeling, jOOQ’s use posture is similar to writing SQL, basically can write SQL without additional training, can immediately start;
Hibernate’s main feature is to map SQL statements with method names, which is very characteristic, but when the query conditions are more complex, it is not so friendly to small white;
Jdbctemplate, on the other hand, is nice and flexible to use in small, lightweight DB operations, but there are a few points that need to be taken care of. For example, queryForObject throws an exception instead of returning null when no data is found.
As for MyBatis and derivative myBatis – Plus, that is, the next protagonist, how its characteristics, why by a large number of domestic developers sought after, it as the db operation of the first ORM framework, let us see it after
I. Build the basic environment
The following project demonstration of Mybatis is mainly run in the SpringBoot environment, and the underlying database uses MySql. The corresponding version information is as follows
- Springboot: 2.2.0. RELEASE
- Mysql: 5.7.22
1. Configure the SpringBoot project
The project creation process for SpringBoot is omitted. Here are the core POM dependencies
<dependencies>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.2.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
</dependencies>
Copy the code
The core depends on MyBatis -spring-boot-starter. For version selection, go to the MVN repository and find the latest one
Another thing that is not available is the DB configuration information, appliaction.yml
spring:
datasource:
url: JDBC: mysql: / / 127.0.0.1:3306 / story? useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password:
Copy the code
2. Prepare the database
In the local database, a new table has been added as follows
CREATE TABLE `money` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(20) NOT NULL DEFAULT ' ' COMMENT 'Username',
`money` int(26) NOT NULL DEFAULT '0' COMMENT 'money',
`is_deleted` tinyint(1) NOT NULL DEFAULT '0',
`create_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT 'Creation time',
`update_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'Update time'.PRIMARY KEY (`id`),
KEY `name` (`name`)
) ENGINE=InnoDB AUTO_INCREMENT=551 DEFAULT CHARSET=utf8mb4;
Copy the code
The curDs that follow in this article are all for this table
II. MyBatis CURD
Next, we will implement the whole process of mysql operation based on MyBatis from 0 to 1
1. Basic objects
As any frequent user of Mybatis may know, operating a DB usually comes with several indispensable things
- Database entity classes: Can be understood as Java Bean objects to which database table locks are mapped
- Mapper Interface: Interface class, which defines db operations
- XML file: Corresponding to the above interface, the actual SQL is written in the XML file
Mybatis recommended gameplay is to write SQL using XML, but the official way to annotate is also provided, so XML file is not necessary; How annotations operate is described later; This article will focus on the traditional XML collocation posture
For this table, the first step is to define the entity class MoneyPo
@Data
@NoArgsConstructor
@AllArgsConstructor
public class MoneyPo {
private Integer id;
private String name;
private Long money;
private Integer isDeleted;
private Timestamp createAt;
private Timestamp updateAt;
}
Copy the code
- The above three annotations belong to lombok knowledge, there are unclear partners can search
Next up is the Mapper interface, which is MoneyMapper
// Note the @mapper annotation to indicate that the interface belongs to Mybatis's Mapper object
@Mapper
public interface MoneyMapper {}Copy the code
Then there is the XML file moneymapper.xml for the Mapper interface
Note that the XML file is placed under the resources file, and the directory structure of the XML file is exactly the same as the package path of the Mapper interface above. 【DB series 】SpringBoot Mybatis Mapper interface and Sql binding
<! DOCTYPEmapper PUBLIC "- / / mybatis.org//DTD Mapper / 3.0 / EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.git.hui.boot.mybatis.mapper.MoneyMapper">
</mapper>
Copy the code
2. Data insertion
In the first three steps, the entity class, interface object and XML file that we need are initialized. The next step is to enter our CURD link to realize the addition, deletion, change and check of the database. Here we mainly use the INSERT tag
For example, if we want to insert a piece of data, the first thing we need to do is define a method in the Mapper interface
int savePo(@Param("po") MoneyPo po);
Copy the code
Next comes the corresponding SQL in the XML file
<insert id="savePo" parameterType="com.git.hui.boot.mybatis.entity.MoneyPo" useGeneratedKeys="true"
keyProperty="po.id">
INSERT INTO `money` (`name`, `money`, `is_deleted`)
VALUES
(#{po.name}, #{po.money}, #{po.isDeleted});
</insert>
Copy the code
2.1 Description
Notice the XML file above
- ParameterType: specifies the parameterType
- UseGenerateKeys + keyProperty: indicates that the primary key ID that needs to be inserted into the DB will be written to the ID field of the entity class
- SQL statement parameters: such as
# {}
Enter the variable name in curly brackets, and the above ispo.name
This means that the name member of the Po object is used as the name field of the DB
Here are the important points:
- Pass parameters in addition to use
# {}
In addition, you can also useThe ${}
, the difference is that the first is a parameter placeholder, followed by a string replacement, so there is a risk of SQL injection
For example
select * from money where id=${id}
select * from money where id=#{id}
Copy the code
When id =1 or id =1, the corresponding SQL becomes
The first SQL will return all the data
select * from money where id = 1 or 1 =1
The following throws an SQL exception
select * from money where id = '1 or 1=1'
Copy the code
2.2 Batch Insert
In addition to the single insert above, batch inserts are also ok, similar to the previous position
int batchSave(@Param("list") List<MoneyPo> list);
Copy the code
The corresponding SQL is as follows
<insert id="batchSave" parameterType="com.git.hui.boot.mybatis.entity.MoneyPo" useGeneratedKeys="true" keyProperty="id">
insert ignore into `money` (`name`, `money`, `is_deleted`)
values
<foreach collection="list" item="item" index="index" separator=",">
(#{item.name}, #{item.money}, #{item.isDeleted})
</foreach>
</insert>
Copy the code
The foreach tag will be explained in a later blog post, but it can be simply interpreted as traversal
3. Data query
Query can be said to be the most common situation in our daily development, here first give a simple query demo, as for more complex query conditions (such as table, subquery, conditional query, etc.) in the following blog to introduce
For queries based on primary keys, the select label is used
MoneyPo findById(int id);
Copy the code
The corresponding SQL
<resultMap id="BaseResultMap" type="com.git.hui.boot.mybatis.entity.MoneyPo">
<id column="id" property="id" jdbcType="INTEGER"/>
<result column="name" property="name" jdbcType="VARCHAR"/>
<result column="money" property="money" jdbcType="INTEGER"/>
<result column="is_deleted" property="isDeleted" jdbcType="TINYINT"/>
<result column="create_at" property="createAt" jdbcType="TIMESTAMP"/>
<result column="update_at" property="updateAt" jdbcType="TIMESTAMP"/>
</resultMap>
<sql id="money_po">
id, name, money, is_deleted, create_at, update_at
</sql>
<select id="findById" parameterType="java.lang.Integer" resultMap="BaseResultMap">
select
<include refid="money_po"/>
from money where id=#{id}
</select>
Copy the code
Focusing on the above implementation, the content of the SELECT statement is relatively simple, but there are a few points to note
- SQL tag: internally defines the DB fields to be queried. The biggest feature is for the following query statements to pass
include
To achieve code snippet reuse - ResullMap: From the comparison between DB field and MoneyPo entity class, we can know that some field names are not exactly the same, for example, db uses underline, Java uses hump, then how to map DB field and Java member variables? Used here
result
Label to specify the mapping between the two, as well as the type
(I believe the above will always accompany you in your development career)
4. Data update
Updates are made with the update tag, which is less informative than the two above
int addMoney(@Param("id") int id, @Param("money") int money);
Copy the code
The corresponding SQL is as follows
<update id="addMoney" parameterType="java.util.Map">
update money set money=money+#{money} where id=#{id}
</update>
Copy the code
instructions
- The parameterType in the tag above is actually omitted here
@Param
Note: This is mainly used to specify parameter names. In XML, you can use internally defined names as parameter variables. Without this annotation, in XML, parameter variables are usedparam0
.param1
To replace the
5. Delete data
Delete using the delete tag
int delPo(@Param("id") int id);
Copy the code
The corresponding SQL is as follows
<delete id="delPo" parameterType="java.lang.Integer">
delete from money where id = #{id,jdbcType=INTEGER}
</delete>
Copy the code
6. Use a demo
The mapper interface defines the complete CURD. The next step is to use the Mapper interface to implement the interaction. In Spring, it is very simple to use the mapper interface
@Repository
public class MoneyRepository {
@Autowired
private MoneyMapper moneyMapper;
public void testBasic(a) {
MoneyPo po = new MoneyPo();
po.setName("mybatis user");
po.setMoney((long) random.nextInt(12343));
po.setIsDeleted(0);
moneyMapper.savePo(po);
System.out.println(po);
MoneyPo out = moneyMapper.findById(po.getId());
System.out.println("query:" + out);
moneyMapper.addMoney(po.getId(), 100);
System.out.println("after update:" + moneyMapper.findById(po.getId()));
moneyMapper.delPo(po.getId());
System.out.println("after del:"+ moneyMapper.findById(po.getId())); }}Copy the code
The following output is displayed
MoneyPo(id=552, name=mybatis user, money=7719, isDeleted=0, createAt=null, updateAt=null) query:MoneyPo(id=552, Name =mybatis user, money=7719, isDeleted=0, createAt=2021-08-01 11:47:23.0, UpdateAt =2021-08-01 11:47:23.0) after update:MoneyPo(id=552, name=mybatis user, money=7819, isDeleted=0, CreateAt =2021-08-01 11:47:23.0, updateAt=2021-08-01 11:47:23.0) after del:nullCopy the code
7. Summary
I believe you see here, build a CURD project of MyBatis database should be not a problem, the main knowledge points of this paper are as follows
- Mybatis project three suites: entity class + Mapper interface + XML file
- Database additions and deletions
Some of the knowledge points are more important, this article is just thrown out, interested partners can continue to pay attention to the follow-up updates
The following knowledge points will be explained in more detail later
- How do I get the primary key ID of the inserted data
- In batch scenarios
foreach
Label use - Mapping of database table structures to Java entity classes
resultMap
The label - How Mapper interfaces are associated with XML files
- How can the Mapper interface be scanned and be used by Spring Bean objects
- Mapper interface and XML parameter passing mode
@Param
annotations - Two ways to write SQL parameter substitution
# ${}, {}
- Pass the parameter type and return the value type definition
- Code reuse fragment
sql
The label
III. Can’t miss the source code and related knowledge
0. Project
- Project: github.com/liuyueyi/sp…
- Source: github.com/liuyueyi/sp…
1. Wechat official account: a gray Blog
The above content is not as good as the letter, purely the words of a family, due to the limited personal ability, there are inevitably omissions and mistakes, such as found bugs or better suggestions, welcome criticism and correction, not grudging gratitude
Below a gray personal blog, record all study and work in the blog, welcome everyone to visit
- A gray Blog personal Blog blog.hhui. Top
- A Gray Blog-Spring feature Blog Spring.hhui. Top