Tip: Write code carefully
Article directory
foreword
The most important thing about MyBatis code is to simplify the dao layer code, and simplify the complex and large amount of JDBC code in dao into interfaces and mapping files
ORM idea
O: po class
R: relationship, database
M: mapper, mapping
Preparation
Step 1: Create a new project Maven project
In the next step, check the first option to create a simple project, and finally fill in the relevant information to complete
If there is a configuration file that needs to be imported:
the advantage of this is that it is fine even if the original configuration file is deleted
Step 2: Improve the pom.xml file
After the project is completed, import relevant codes in the pom.xml file, such as:
add what is missing
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.1</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 使用log4j输出更多的日志信息 -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<!--表示需要编译的源文件路径-->
<directory>src/main/java</directory>
<includes>
<!--表示以.properties和*.xml结尾的文件将进行编译-->
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<!--表示需要编译的源文件路径-->
<directory>src/main/resources</directory>
<includes>
<!--表示以.properties和*.xml和.yml结尾的文件将进行编译-->
<include>**/*.properties</include>
<include>**/*.xml</include>
<include>**/*.yml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>
Step 3: Configure the main/resources folder
mybatis-config.xml
configuration file
<?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>
<typeAliases>
<package name=""/>
</typeAliases>
<!-- 配置数据源相关属性 -->
<environments default="development">
<!-- 可以配置多个数据源环境,默认使用default中的值 -->
<environment id="development">
<!-- 使用jdbc的事务管理 -->
<transactionManager type="MANAGED" />
<!-- 配置数据源,并使用自带数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8&serverTimezone=Asia/Shanghai" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 配置映射文件,可配置多个 -->
<mappers>
<!-- 指定映射文件路径,复制一下 -->
<mapper resource="" />
<mapper resource="" />
</mappers>
</configuration>
log4j.properties
Configuration file, can display log output
### direct log messages to stdout ###
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{
yyyy-MM-dd HH:mm:ss} %m%n
log4j.rootLogger=debug,stdout
- Create a new mapping file
XyzMapper.xml
<?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="">
</mapper>
Step 4: Create a test test class under the test/java folder
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
public class AppTest {
private SqlSession session=null;
@Before
public void before() throws Exception {
// 与main/resources文件夹中的 mybatis-config.xml 配置文件名字对应
InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(input);
session= ssf.openSession();
}
@After
public void after() {
session.close();
}
@Test
public void test() {
}
}
提示:以下是本篇文章正文内容,下面案例可供参考
MyBatis CRUD operation process
MySQL table creation statement:
drop table if exists emp;
create table EMP
(
EMPNO int primary key,
ENAME varchar(20),
JOB varchar(9),
MGR int,
HIREDATE date,
SAL double,
COMM double,
DEPTNO int,
foreign key (DEPTNO) references DEPT (DEPTNO)
);
add feature
Create a new po package and class in the main/java folder
public class Emp {
private Integer empno;
private String ename;
private String job;
private Integer mgr;
private Date hiredate;
private Double sal;
private Double comm;
private Integer Deptno;
// 自动生成 Getter、Setter、toString()、有参无参方法
}
Create a new mapping file mapper.xml in the main.resources folder
What is written here is the SQL statement
The parameters in parameterType are: double-click the name of the class in the po class, right-click to copy the qualified name, and the
specific data in the SQL statement should be written as #{}
a placeholder
The attribute names in curly brackets should be consistent with the names in the po class (note case), and the names in the po class should be consistent with the names in the database
<mapper namespace="emp">
<!-- 方法名, 参数 返回值(只有查询有) -->
<insert id="insertEmp" parameterType="com.mybatis.po.Emp">
insert into emp
values(#{empno},#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{Deptno})
</insert>
</mapper>
Next, add the configuration file to the config.xml file
<!-- 配置映射文件,可配置多个 -->
<mappers>
<!-- 指定映射文件路径,复制一下 -->
<mapper resource="EmpMapper.xml" />
</mappers>
Then you can test, test code:
@Test
// insertEmp()起个名
public void insertEmp() {
Emp emp = new Emp(8988, "张三", "Java", 7790, new Date(2023, 10, 23), 10000.0, 99.0, 20);
// "emp.insertEmp" → "namespace的值.insertEmp方法名是映射文件中的id"
int i = session.insert("emp.insertEmp", emp);
System.out.println(i);
}
Next, right-click the test class test , click Run Mode → JUnit Test
He will run the previous @Test
method
delete function
#{}
The name in the placeholder If the parameter is of type po, then the name must be an attribute name, if the parameter is a basic type or String, then the parameter name is custom
Mapping file code:
<delete id="deleteEmp" parameterType="int">
delete from emp
where empno = #{
随便起名}
</delete>
Test class code:
@Test
public void deleteEmp() {
int i = session.delete("emp.deleteEmp",8966);
System.out.println(i);
}
modify function
Mapping file code:
<update id="updateEmp" parameterType="com.mybatis.po.Emp">
update emp
set ename=#{
ename},job=#{
job},mgr=#{
mgr},hiredate=#{
hiredate},sal=#{
sal},comm=#{
comm},Deptno=#{
Deptno}
where empno = #{
empno}
</update>
Test class code:
@Test
public void updateEmp() {
Emp emp = new Emp(8988,"enen","java全栈",7790,new Date(2003, 10, 13), 11000.0, 999.0, 20);
int i = session.update("emp.updateEmp",emp);
System.out.println(i);
}
query function
#{} Placeholder
Mapping file code:
<select id="queryEmps" parameterType="String" resultType="com.mybatis.po.Emp">
select * from emp
where ename like concat('%',#{名字模糊查询},'%')
</select>
Test class code:
@Test
public void queryEmp() {
List<Emp> list = session.selectList("emp.queryEmps","T");
for (Emp emp : list) {
System.out.println(emp);
}
}
In addition to #{}
other placeholders, there is a placeholder called ${}
, which is less used now
${} placeholder
Mapping file code:
<select id="queryEmps" parameterType="String" resultType="com.mybatis.po.Emp">
select * from emp
where ename like concat('%','${value}','%')
</select>
Test class code:
@Test
public void queryEmps() {
// 查询部门名字中带 O 的
List<Emp> list = session.selectList("emp.queryEmps","O");
for (Emp emp : list) {
System.out.println(emp);
}
}
The difference between the two placeholders❗
${}
The common Statement statement is used to run, the operation efficiency is low, and the SQL statement splicing method is used, which may cause SQL injection security problems
#{}
The PreparedStatement precompiled statement is used, which has high operating efficiency, can prevent SQL injection, and has high security
Mapping file summary❗
- The mapping file can be understood as a dao class, which contains SQL statements
- The tag in the mapping file
insert update delete select
is understood as a method in the dao class id
Attributes are understood as method names ,parameterType
attributes are understood as parameters , andresultType
attributes are understood as method return values (addition, deletion, and modification do not require configuration, because they can only be of type int)- The specific data in the SQL statement should be written as
#{}
a placeholder.#{属性名1},#{属性名2}
#{}
The name in the placeholder If the parameter is of type po, then the name must be an attribute name, if the parameter is a basic type or a string, then the parameter name can be customizedalt + /
is a reminder
The mapper proxy method realizes CRUD
mapper agent development specification
1. Create a new interface and a mapping file with the same name in the same package
2. The namespace of the mapping file must be the qualified name of the interface
3. The statement id in the mapping file must be consistent with the method name in the interface
4. The statement parameterType in the mapping file Must be consistent with the method parameters in the interface
5. The statement resultType in the mapping file must be consistent with the method return value type in the interface
A mapper.xml corresponds to a mapper.java interface, and the implementation class of the interface is automatically generated by MyBatis
Create a new customer table in the database
drop table if exists cust;
CREATE TABLE cust (
id INT PRIMARY KEY auto_increment, # id自增
name VARCHAR(50) NOT NULL, # 姓名
phone VARCHAR(20), # 电话
birthday DATE, # 出生日期
balance DOUBLE # 余额
);
INSERT INTO cust (id, name, phone, birthday, balance) VALUES (1, '张三', '13611111111', '1990-01-01', 1000.00);
INSERT INTO cust (id, name, phone, birthday, balance) VALUES (2, '李四', '13722222222', '1995-02-02', 2000.00);
INSERT INTO cust (id, name, phone, birthday, balance) VALUES (3, '王五', '13833333333', '1985-03-03', 3000.00);
Create a new po package and its Java class in main/java
public class Cust {
private Integer id;
private String name;
private String phone;
private Date birthday;
private double balance;
// 自动生成 Getter、Setter、toString()、有参无参方法
}
.xml
Then create a Cust interface and file in main/java
In the CustMapper.xml file, namespace
it is the qualified name of the interface
<mapper namespace="com.mybatis.mapper.CustMapper">
Configuration in the mybatis-config.xml file:
<!-- 1.package name是po包的限定名 -->
<typeAliases>
<package name="com.mybatis.po"/>
</typeAliases>
<!-- 中间代码省略 -->
<!-- 2.配置映射文件,可配置多个 -->
<mappers>
<!-- 指定映射文件包(mapper包) 的限定名,复制一下 -->
<package name="com.mybatis.mapper"/>
</mappers>
add feature
First define the method in the interface:
int insertCust(Cust cust);
Customers.xml file code:
<insert id="insertCust" parameterType="Cust">
insert into cust(id,name,phone,birthday,balance)
values (#{id},#{name},#{phone},#{birthday},#{balance})
</insert>
Test code:
@Test
public void insertCust() {
// 得到mapper接口实现类对象
CustMapper mapper = session.getMapper(CustMapper.class);
// 主键是自增的,所以id可以为空
Cust cust = new Cust(null,"张三", "15794612345", new Date(2003-8-03),20.5);
// 调用接口中定义的方法
int i = mapper.insertCust(cust);
System.out.println(i);
}
How to get the primary key after adding it?
In the mapping file: add the query primary key value
<insert id="insertCust" parameterType="Cust">
<!-- 获得自动递增的主键值 -->
<selectKey keyProperty="id" resultType="int" order="AFTER">
<!--
查一个虚表,最后一次插入的值
先执行增加的sql语句,再执行查询,获取插入的主键值,然后赋值给keyProperty的id
-->
select last_insert_id() from dual
</selectKey>
insert into cust(id,name,phone,birthday,balance)
values (#{
id},#{
name},#{
phone},#{
birthday},#{
balance})
</insert>
Test code plus:
System.out.println("增加的主键值是:"+cust.getId());
delete function
First define the method in the interface:
int deleteCust(int id);
In the mapping file CustMapper.xml:
<delete id="deleteCust" parameterType="int">
delete from cust
where id = #{
int类型随便起名}
</delete>
Test code:
@Test
public void deleteCustomers() {
CustMapper mapper = session.getMapper(CustMapper.class);
int i = mapper.deleteCust(3);
System.out.println(i);
}
modify function
First define the method in the interface:
int updateCust(Cust cust);
In the mapping file CustMapper.xml:
<update id="updateCust" parameterType="Cust">
update cust
set name = #{name}, phone = #{phone}, birthday = #{birthday}, balance = #{balance}
where id = #{id}
</update>
Test code:
@Test
public void updateCust() {
CustMapper mapper = session.getMapper(CustMapper.class);
Cust cust = new Cust(5,"李四", "15846012345", new Date(2013-8-03),1320.5);
int i = mapper.updateCust(cust);
System.out.println(i);
}
query function
First define the method in the interface:
// id查询
Cust queryCustById(int id);
// 名字和电话的模糊查询
List<Cust> queryCusts(Cust cust);
In the mapping file CustMapper.xml:
<select id="queryCustById" parameterType="int" resultType="Cust">
select * from cust
where id = #{
随便起名}
</select>
<select id="queryCusts" parameterType="Cust" resultType="Cust">
select * from cust
where name like concat('%',#{
name},'%')
and phone like concat('%',#{
phone},'%')
</select>
Test code:
@Test
public void query() {
CustMapper mapper = session.getMapper(CustMapper.class);
mapper.queryCustById(6);
Cust cust = new Cust(null,"四", "2345", null,130020.5);
mapper.queryCusts(cust);
}
Focus on whether the console output statement is correct