官方文档:MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
简单地说,MyBatis
是可以快速完成程序和数据库交互的工具,是 *** 作和读取数据库的非常好用的工具。
既然要 *** 作数据库,就需要准备一个数据库。
这不是必须的步骤,如果已经有了数据库可以跳过这个步骤。
如果没有可以 *** 作的数据库,可以复制下面的样例到MySql客户端,复制粘贴+enter键即可。
-- 创建数据库
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8;
-- 使用数据数据
use mycnblog;
-- 创建表[用户表]
drop table if exists userinfo;
create table userinfo(
id int primary key auto_increment,
username varchar(100) not null,
password varchar(32) not null,
photo varchar(500) default '',
createtime datetime default now(),
updatetime datetime default now(),
`state` int default 1
);
-- 创建文章表
drop table if exists articleinfo;
create table articleinfo(
id int primary key auto_increment,
title varchar(100) not null,
content text not null,
createtime datetime default now(),
updatetime datetime default now(),
uid int not null,
rcount int not null default 1,
`state` int default 1
);
-- 创建视频表
drop table if exists videoinfo;
create table videoinfo(
vid int primary key,
`title` varchar(250),
`url` varchar(1000),
createtime datetime default now(),
updatetime datetime default now(),
uid int
);
-- 添加一个用户信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1);
-- 文章添加测试数据
insert into articleinfo(title,content,uid)
values('Java','Java正文',1);
insert into articleinfo(title,content,uid) values('Spring','Spring正文',1);
-- 添加视频
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://www.baidu.com',1);
-- 日志表
create table userlog(
id int primary key auto_increment,
`desc` varchar(250),
createtime datetime default now(),
updatetime datetime default now()
);
基础使用:
MyBatis在使用时需要配置xml文件,并在xml中写入具体 *** 作数据库的SQL语句,下面是最简单的查询为例的xml模板:
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.UserMapper">
<select id="getAll" resultType="com.example.demo.model.User">
select * from userinfo
select>
mapper>
namespace
属性中写入xml实现接口的完整路径,即定义了各种接口的类在哪。id必须和我们自定义的接口类中的方法名称相同resultType
:返回的数据类型。
CRUD *** 作
增加:insert语句
在Controller层创建add方法,这个add方法返回的是表中插入数据后受影响的行数:
//添加用户,并返回受影响的行数
@RequestMapping("/add")
public int add(UserInfo userInfo){
//参数校验-> 调用业务逻辑层
if(userInfo==null || userInfo.getName()==null
|| userInfo.getPassword()==null
|| userInfo.getName().equals("")
|| userInfo.getPassword().equals("") ){
//非法参数 返回0
return 0;
}
return userService.add(userInfo);
}
在mapper层声明一个接口方法:
int add(UserInfo userInfo);
在Mapper.xml,MyBatis的配置文件中实现这个接口方法,也就是在配置文件中使用insert语句,insert语句在使用时不需要设置返回类型,会自动默认返回一个int数值。
在向其中传入UserInfo对象的时候,设置相关属性时,语法格式为#{属性名称},#{属性名称}…
<insert id="add">
insert into userinfo(username,password)
value(#{name},#{password})
insert>
运行结果:
在Mysql中查看,可以看到成功插入一条数据:
在实际场景中我们经常需要获取插入数据的主键来进行一些后续的 *** 作,数据库中主键一般使用自增或者UUID()的方式自动生成。
使用Java中的UUID来获得主键是一种比较方便的方式,但是使用数据库生成的主键就需要将插入的数据再查询出来得到主键,在某些情况下还可能会查询到多条结果,这并非理想的情况。
为了解决这个问题,我们在添加这条数据的时候就让其自动返回主键。
像上面的添加 *** 作一样,在Controller层创建一个添加方法:
//向数据库中添加数据,并返回用户的自增id
@RequestMapping("/addCre")
public int addCre(UserInfo userInfo){
//参数校验-> 调用业务逻辑层
if(userInfo==null || userInfo.getName()==null
|| userInfo.getPassword()==null
|| userInfo.getName().equals("")
|| userInfo.getPassword().equals("") ){
//非法参数 返回0
return 0;
}
//调用数据库的添加 *** 作,执行完添加 *** 作后会将自增id设置到userinfo的id属性
userService.addCre(userInfo);
//这里直接获得id
return userInfo.getId();
}
在Mapper层声明接口方法:
int addCre(UserInfo userInfo);
在Mapper对应的xml配置文件中实现这个方法:
<insert id="addCre" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into userinfo(username,password)
value(#{name},#{password})
insert>
这里的insert语句使用了以下三个属性:
useGeneratedKeys属性:对于支持自动生成记录主键的数据库,如MySQL、SQL Servler,如果设置useGeneratedKeys为true,在添加数据后就可以获得数据库自动生成的主键id。keyColumn属性:设置生成键值在表中的列名,即对应的字段名。keyProperty属性:指定唯一能识别对象的属性,即在实体类中对应的某个属性。在单元测试中查看是否返回自增id:
@Test
void addCre() {
UserInfo userInfo=new UserInfo();
userInfo.setName("Spring Boot");
userInfo.setPassword("SpringBoot");
//调用需要进行测试的方法
int autoId=userController.addCre(userInfo);
System.out.println("自增id:"+autoId);
}
成功返回自增id:
过程同上,在Controller层定义方法:
@RequestMapping("/del")
public int del(int id){
if(id<=0) return 0;
return userService.del(id);
}
然后在mapper中声明,在xml配置中使用了delete语句:
<delete id="del">
delete from userinfo where id=#{id}
delete>
最后测试删除id为ma的数据,删除成功:
方法流程和上面的基础 *** 作相同,只是在xml配置时用到了select语句,这里不在赘述,需要注意的是select语句在查询数据时有两种返回方式:
1.resultType(返回类型)
<select id="getAll" resultType="com.example.demo.model.UserInfo">
select * from userinfo
select>
2.resultMap(返回映射/返回字典)
<resultMap id="BaseMap" type="com.example.demo.model.UserInfo">
<id column="id" property="id">id>
<result column="username" property="name">result>
<result column="password" property="password">result>
<result column="photo" property="photo">result>
<result column="createtime" property="createtime">result>
<result column="updatetime" property="updatetime">result>
resultMap>
<select id="getAll" resultMap="BaseMap">
select * from userinfo
select>
总结ResultType 与 ResultMap的异同:
相同:功能相同,作用都是用来指定查询返回结果类型不同:
resultType使用简单,缺点是如果实体类中的属性名和表中的字段不一致时,将查询不出任何结果。
resultMap用法稍微复杂,需要建立多个列的映射,优点是如果实体类中的属性名和表中字段不一致时,依然可以正常映射,返回查询结果。 修改:update语句
举例:修改数据库中某条记录的密码
在Controller层中创建方法:
//修改 *** 作,修改数据库中某个用户的密码
@RequestMapping("/update")
public int updatePassword(int id,String password){
//参数检验
if(id<=0 || password==null || password.equals("")){
//非法数据
return 0;
}
return userService.updatePassword(id,password);
}
在mapper层声明这个接口方法,并在其配置xml文件中实现这个方法:
int updatePassword(int id, String password); //声明
<update id="updatePassword">
update userinfo set password=#{password}
where id=#{id}
update>
在测试中尝试将记录ma的密码修改为password:
@Test
void updatePassword() {
int result=userController.updatePassword(5,"password");
Assertions.assertEquals(result,1);
}
在数据库中可以看到,修改成功:
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)