MyBatis操作数据库-XML实现
目录
1.MyBatis的简单介绍
2.MyBatis操作数据库的步骤
2.1 添加依赖
2.2 配置文件
2.3 写持久层代码
2.4 方法测试
3.MyBatis操作数据库(增删查改)
3.1 CRUD标签
3.2 参数传递
3.3 Insert-新增
3.4 Delete-删除
3.5 Update-修改
3.6 Select-查询(映射问题)
1.MyBatis的简单介绍
MyBatis是一款持久层框架(持久层指持久化操作的层,通常指数据访问层dao),简单来说,使用MyBatis能够更简单地完成程序和数据库之间的交互
2.MyBatis操作数据库的步骤
2.1 添加依赖
首先需要导入MyBatis依赖和MySQL驱动依赖(添加到pom.xml文件中)
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
2.2 配置文件
我们需要配置Mysql数据库信息,MyBatis日志打印和MyBatis XML的文件路径,数据库信息用于和指定数据库进行连接,MyBatis日志用于查看SQL语句的执行,传递的参数以及执行结果(MyBatis日志打印的配置不是必须的,如果不需要,在配置文件中删除相关配置信息即可),MyBatis XML文件路径(以下面的配置内容为例)用于声明在resources/mapper下创建所有的XML文件
如果是application.yml文件,配置以下内容
# 配置Mysql数据库信息
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
# url中的mybatis_test替换为自己的数据库名
username: root #数据库用户名
password: root #数据库密码(如果没设置密码,默认为root,如果有的话需要修改,例如'123456')
driver-class-name: com.mysql.cj.jdbc.Driver
# 配置打印 MyBatis⽇志
mybatis:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# 配置MyBatis XML文件路径
mapper-locations: classpath:mapper/**Mapper.xml
如果是application.properties文件,配置以下内容
# 配置Mysql数据库信息
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
# 上面url中的mybatis_test替换为自己的数据库名
spring.datasource.username=root #数据库用户名
spring.datasource.password=root #数据库密码(如果没设置密码,默认为root,如果有的话需要修改,例如'123456')
# 配置MyBatis日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 配置MyBatis XML文件路径
mybatis.mapper-locations=classpath:mapper/**Mapper.xml
2.3 写持久层代码
持久层代码分为两个部分,分别是方法定义(接口interface)和方法实现(**.xml)
(1)方法定义(UserInfoXMLMapper接口)
- @Mapper:表示MyBatis中的Mapper接口,程序运行时会自动生成接口的代理对象,并交给Spring的IoC容器管理
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
List<UserInfo> queryUserInfos();
}
(2)方法实现(UserInfoXMLMapper.xml,根据MyBatis XML文件路径,创建路径为resources/mapper/UserInfoXMLMapper.xml)
- <mapper>标签:表示命名空间,需要指定namespace属性,值为Mapper接口的全限定名(全包名.类名)
<?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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<!-- sql语句的具体实现-->
</mapper>
2.4 方法测试
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest //在Spring的运行环境下进行测试
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void queryUserInfos() {
//具体测试代码
}
}
3.MyBatis操作数据库(增删查改)
3.1 CRUD标签
CRUD标签即<insert>,<delete>,<select>,<update>四个标签,用于在方法实现的<mapper>标签中实现具体的SQL语句,以<select>为例
- <select>:执行数据库的查询操作
- id:与接口中的定义的方法名称相同,表示对接口的具体实现方法
- resultType:返回的数据类型,值为该类型的全限定名
<?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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
select * from userinfo
</select>
</mapper>
3.2 参数传递
当我们执行条件查询时等SQL语句时,需要在SQL语句中对表指定属性赋值,这时可以使用#{ }的方式来获取方法中的参数,拼接到SQL语句中从而得到完整的SQL语句,括号中的参数名称与方法中的参数名称最好相同(当然也可以不相同,下面会说到)
//UserInfoXMLMapper.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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
select * from userinfo where id=#{id} and age=#{age}
--获取id和age参数,分别赋值->最终执行SQL语句为select * from userinfo where id=1 and age=18
</select>
</mapper>
//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
List<UserInfo> queryUserInfos(UserInfo userInfo);
}
//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void queryUserInfos() {
UserInfo userInfo=new UserInfo();
userInfo.setId(1);
userInfo.setAge(18);
userInfoXMLMapper.queryUserInfos(userInfo).forEach(System.out::println);
}
}
如果需要使括号中的参数名称与方法中的参数名称不相同,可以通过@Param设置参数的别名,同时使用#{ }获取参数时括号中的参数名称要与别名相同
//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.example.mybatisdemo.model.UserInfo;
import java.util.List;
@Mapper
public interface UserInfoXMLMapper {
List<UserInfo> queryUserInfos(@Param("userid") Integer id);
}
//UserInfoXMLMapper.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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
select * from userinfo where id=#{userid}
</select>
</mapper>
3.3 Insert-新增
//UserInfoXMLMapper.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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<insert id="insertUserInfo">
insert into userinfo (username,password,age) values (#{userName},#{password},#{age})
</insert>
</mapper>
//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
@Mapper
public interface UserInfoXMLMapper {
Integer insertUserInfo(UserInfo userInfo);
}
//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void insertUserInfo() {
UserInfo userInfo = new UserInfo();
userInfo.setUserName("wangliu");
userInfo.setPassword("123456");
userInfo.setAge(18);
userInfoXMLMapper.insertUserInfo(userInfo);
}
}
接口定义不变时,在XML文件设置useGeneratedKeys和keyProperty属性可以返回自增的表属性
<?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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<insert id="insertUserInfo" useGeneratedKeys="true" keyProperty="id">--返回自增的id属性
insert into userinfo (username,password,age) values (#{userName},#{password},#{age})
</insert>
</mapper>
3.4 Delete-删除
//UserInfoXMLMapper.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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<delete id="deleteUserInfo">
delete from userinfo where id=#{id}
</delete>
</mapper>
//UserInfoXMLMapper接口
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserInfoXMLMapper {
Integer deleteUserInfo(Integer id);
}
//方法测试代码
package org.example.mybatisdemo.mapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void deleteUserInfo() {
userInfoXMLMapper.deleteUserInfo(10);
}
}
3.5 Update-修改
//UserInfoXMLMapper.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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<update id="updateUserInfo">
update userinfo set username=#{userName} where id=#{id}
</update>
</mapper>
//UserInfoXMLMapper类
package org.example.mybatisdemo.mapper;
import org.apache.ibatis.annotations.Mapper;
import org.example.mybatisdemo.model.UserInfo;
@Mapper
public interface UserInfoXMLMapper {
Integer updateUserInfo(UserInfo userInfo);
}
//方法测试代码
package org.example.mybatisdemo.mapper;
import org.example.mybatisdemo.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
@SpringBootTest
class UserInfoXMLMapperTest {
@Autowired
private UserInfoXMLMapper userInfoXMLMapper;
@Test
void updateUserInfo() {
UserInfo userInfo = new UserInfo();
userInfo.setUserName("zhangliu");
userInfo.setId(9);
userInfoXMLMapper.updateUserInfo(userInfo);
}
}
3.6 Select-查询(映射问题)
在参数传递(3.2节)已经举了一个关于查询操作的例子,这里便不再举例,虽然在这个例子中,代码能够正常运行,但是当我们仔细观察运行结果,会发现一些问题。以下是该例子运行结果的截图(与参数传递中的截图一致)
我们会发现有几个属性没有赋值(表中该条数据不存在为null的属性),这是因为自动映射查询结果时,MyBatis会获取结果中返回的列名属性并在Java类中查找相同名称的属性(忽略大小写),而delete_flag,create_time等列名属性与Java类(这里指UserInfo类)中的deleteFlag,createTime等属性名称不同,所以会返回null。这时只需要参照列名属性修改一下Java类中的属性名称,就可以得到正确结果,当然,如果不想修改属性名称,有三种方式可以解决这个问题,分别是起别名,结果映射和开启驼峰别名
(1)起别名
在SQL语句中,给列名起别名(as),使别名和Java类中属性名称保持相同,接口和方法测试代码与例子中一致
<?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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<select id="queryUserInfos" resultType="org.example.mybatisdemo.model.UserInfo">
select id,username,password,age,gender,phone,
delete_flag as deleteFlag,
create_time as createTime,
update_time as updateTime
from userinfo where id=#{id} and age=#{age}
</select>
</mapper>
<!--接口和方法测试代码与例子中一致-->
(2)结果映射
- id(<resultMap>标签):resultMap别名
- type:映射的实体类
- <id>标签:表示主键
- column(<result>标签):数据库列名属性
- property(<result>标签):Java类属性名
<?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="org.example.mybatisdemo.mapper.UserInfoXMLMapper">
<resultMap id="XMLBaseMap" type="org.example.mybatisdemo.model.UserInfo">
<id column="id" property="id"></id>
<result column="delete_flag" property="deleteFlag"></result>
<result column="create_time" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
</resultMap>
<select id="queryUserInfos" resultMap="XMLBaseMap">
select * from userinfo where id=#{id} and age=#{age}
</select>
</mapper>
<!--接口和方法测试代码与例子中一致-->
(3)开启驼峰命名
数据库列名一般使用蛇形命名法进行命名(下划线分割各个单词),而Java属性一般遵循驼峰命名法约定,要在这两种命名方式之间启用自动映射(delete_flag→deleteFlag),需要配置一下配置文件
如果是application.yml文件,配置以下内容
mybatis:
configuration:
map-underscore-to-camel-case: true #配置驼峰⾃动转换
如果是application.properties文件,配置以下内容
#配置驼峰自动转换
mybatis.configuration.map-underscore-to-camel-case: true