创建Mybatis项目
MyBatis的写法
1.注解
2.XML
1.引入Mybatis依赖,引入对应数据库的依赖,比如mysql.
2.配置数据库相关信息
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: 1234
driver-class-name: com.mysql.cj.jdbc.Driver
3.定义Java对象
package com.example.demo;
import java.util.Date;
public class UserInfo {
private Integer id ;
private String username;
private String password ;
private Integer age;
private Integer gender;
private String phono;
private Integer delete_flag;
private Date createTime ;
}
4.写实现
实现这里的@select注解是sql语句,其下面是对应方法声明。@Mapper注解, mybatis就会告诉Spring,把对象交给Spring管理。
package com.example.demo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.springframework.web.bind.annotation.Mapping;
import java.util.List;
@Mapper
public interface UserInfoMapper {
@Select("select * from userinfo")
List<UserInfo> selectAll();
}
在数据库中使用删除时分为:逻辑删除和物理删除
逻辑删除:指从逻辑上进行数据删除。物理删除:从硬盘上进行数据删除delete。二者的区分就是是否保存数据,现在数据非常宝贵,可以通过日常数据得知每个人的偏好和各种信息,所以现在一般都是采用逻辑删除来进行保存信息。
写测试类
右键生成中有测试直接选中
将这些都选中就会出现如下
@Slf4j//日志框架
@SpringBootTest//必需写上将Spring容器中的数据注入其中
class UserInfoMapperTest {
@Autowired
private UserInfoMapper userInfoMapper;
@BeforeEach//结果出现前打印
void setUp() {
log.info("setUP");
}
@AfterEach//结果出现后打印
void tearDown() {
log.info("setUP");
}
@Test
void selectAll(){
List<UserInfo> list =userInfoMapper.selectAll();
log.info(list.toString()) ;
}
}
在运行时,报这个错误时是有可能org.springframework.beans.factory.UnsatisfiedDependencyException
在启动类上面注解的后面加了(exclude = {DataSourceAutoConfiguration.class}),其意思是Spring Boot将不会自动配置数据源和JPA存储库相关的bean。
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
去掉之后正常运行
Mybaties的日志打印
mybatis:
configuration: #配置打印MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
将会详细打印出数据库查询的运行轨迹
根据参数来进行查询结果
虽然如果只有一个参数,SQL的名称可以为任意的,但是还是将名称改为与其对应的,代码可读性高,以后也比较好进行修改。
@Select("select * from userinfo where id =#{id}")
UserInfo selectOne(Integer id);
//test
@Test
void selectOne() {
UserInfo userInfo = userInfoMapper.selectOne(1);
log.info(userInfo.toString());
}
查询结果
同时也可以将参数进行重命名来进行使用
@Select("select * from userinfo where id =#{userId}")
UserInfo selectOne2(@Param("userId") Integer id);
将参数进行重命名的目的是
- 语义化命名: 参数名
userId
更直观地表示了参数的含义,明确了该参数表示的是用户的 ID。 - 避免歧义: 当方法参数较多时,可能存在多个
id
参数,此时通过重命名可以避免歧义,明确是哪个参数代表用户的 ID。 - 可维护性: 如果后续需要修改参数名,只需要修改
@Param
注解中的值,而不需要修改 SQL 查询语句中的参数名,降低了修改的风险
插入数据
@Insert("insert into userinfo (username,password,age,gender,phone)"+
"values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);
//test
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("sadada");
userInfo.setPassword("32324");
userInfo.setAge(2);
userInfo.setGender(1);
userInfo.setPhone("213123123");
Integer result = userInfoMapper.insert(userInfo);
log.info("insert",result);
}
结果
查询数据库中自增的数据
这个Op注解设置为true就是将自增数据的读取权限给打开,然后你就可以进行读取
sql语句太长换行加上”+“连进行连接
@Options(useGeneratedKeys = true,keyProperty = "id")
@Insert("insert into userinfo (username,password,age,gender,phone)"+
"values (#{username},#{password},#{age},#{gender},#{phone})")
Integer insert(UserInfo userInfo);
//test
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("ewqrwe");
userInfo.setPassword("ewrwe");
userInfo.setAge(1);
userInfo.setGender(1);
userInfo.setPhone("213123123");
Integer result = userInfoMapper.insert(userInfo);
log.info("insert,结果:{} ,自增ID:{}",result,userInfo.getId());//必修要使用{}才能捕获输出的值
}
不设置就会产生下面
参数为对象时,对参数进行重命名
并且重命名时,必修在参数前加上重命名的名称加上.否则不能进行识别,会报错
@Insert("insert into userinfo (username,password,age,gender,phone)"+
"values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender},#{userInfo.phone})")
Integer insert(@Param("userInfo") UserInfo userInfo);
删除数据
@Delete("delete from userinfo where id =#{id}")
Integer delete(Integer id);
@Test
void delete() {
UserInfo userInfo = new UserInfo();
Integer result = userInfoMapper.delete(16);
log.info("delete,{}",result);
}
更改数据
@Insert("insert into userinfo (username,password,age,gender,phone)"+
"values (#{userInfo.username},#{userInfo.password},#{userInfo.age},#{userInfo.gender},#{userInfo.phone})")
Integer insert(@Param("userInfo") UserInfo userInfo);
//test
@Test
void update() {
UserInfo userInfo = new UserInfo();
userInfo.setAge(55);
userInfo.setId(10);
Integer result = userInfoMapper.update(userInfo);
log.info("update {}",result);
}
通过结果映射进行查询
结果映射
Mybatis 会自动的根据数据库的字段名和Java对象的属性名,进行映射如果名称一样.就讲行赋值
相同就进行了赋值,不同就置为空。
1.直接使用配置来进行自动转化
将createTime转化为create_time类型
mybatis:
configuration: #配置打印MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
map-underscore-to-camel-case: true #配置驼峰自动转换
2.使用@Results注解
左边是数据库,右边是java对象的属性。并且其还能进行复用,在想复用的的方法上加上
@ResultMap(value = "BaseMap")
@Results(id= "BaseMap",value = {
@Result(column = "delete_flag",property = "deleteFlag")
})
@Select("select * from userinfo")
List<UserInfo> selectAll2();
//复用
@ResultMap(value ="BaseMap")
@Select("select * from userinfo;")
List<UserInfo> selectAll();
XML方式
1.先配置数据库
2.指明xml的路径
mybatis:
# configuration: #配置打印MyBatis日志
# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
# map-underscore-to-camel-case: true #配置驼峰自动转换
mapper-locations:
classpath:mapper/**Mapper.xml
classpath后面对应的是Mapper.xml放在哪里并且Mapper.xml这个文件前面是什么无所谓,只要后面这几个是Mapper.xml就可以。
3.写XML的实现
namespace后面写的要实现哪个接口以及要写接口的全限定类名。id写的是实现的方法名,resultType则是返回的类型,返回的是对象,或者list, 此处定义的都是返回的数据的类型
<?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.example.demo.mapper.UserInfoXMLMapper">
<select id="selectALL" resultType="com.example.demo.UserInfo">
select * from userinfo
</select>
</mapper>
//所在的类的方法
@Mapper
public interface UserInfoXMLMapper {
List<UserInfo> selectALL();
}
如果下面报错
Invalid bound statement (not found):com.bite.demo.mapper.UserInfoXNLNapper.selectAll
可能原因
1.xml和接口定义的方法名称不一致 2.mapper的路径配置和xml的路径不一样 3.xml namespace写错了
曾删改和注解类似
Integer insert(UserInfo userInfo);
//XML
<insert id="insert">
insert into userinfo (username,password,age,gender,phone)
values(#{username},#{password},#{age},#{gender},#{phone})
</insert>
//test
@Test
void insert() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("ewqrwe");
userInfo.setPassword("ewrwe");
userInfo.setAge(1);
userInfo.setGender(1);
userInfo.setPhone("213123123");
Integer result = userInfoXMLMapper.insert(userInfo);
log.info("result ,{}",result);
}
Integer insert2(@Param("userInfo") UserInfo userInfo);
//XML
<insert id="insert2" useGeneratedKeys="true" keyProperty="id">
iinsert into userinfo (username,password,age,gender,phone)
values(#{userInfo.username},#{userInfo.password}
,#{userInfo.age},#{userInfo.gender},#{userInfo.phone})
</insert>
//test
@Test
void insert2() {
UserInfo userInfo = new UserInfo();
userInfo.setUsername("ewqrwe");
userInfo.setPassword("ewrwe");
userInfo.setAge(1);
userInfo.setGender(1);
userInfo.setPhone("213123123");
Integer result = userInfoXMLMapper.insert(userInfo);
log.info("result ,{}",result);
}
Integer delete(Integer id);
//XML
<delete id="delete">
delete from userinfo where id =#{id}
</delete>
//test
@Test
void delete() {
UserInfo userInfo = new UserInfo();
Integer result = userInfoXMLMapper.delete(11);
log.info("delete,{}",result);
}
Integer update(UserInfo userInfo);
//Xml
<update id="update">
update userinfo set gender =#{gender}
where id =#{id}
</update>
//test
@Test
void update() {
UserInfo userInfo = new UserInfo();
userInfo.setGender(2);
userInfo.setId(2);
Integer result = userInfoXMLMapper.update(userInfo);
log.info("update,{}",result);
}