【MyBatis】带你快速掌握 —— CRUD
文章目录
- insert(Create)
- Map集合
- pojo传参
- delete(Delete)
- update(Update)
- select(Retrieve)
- 查询一条数据
- 查询多条数据
- 关于SQL Mapper的namespace
insert(Create)
Map集合
在Java程序中,将数据放到Map集合中
在sql语句中使用 #{map集合的key} 来完成传值,#{} 等同于JDBC中的 ? ,#{}就是占位符
Java程序如下:
public class CarMapperTest {
@Test
public void testInsertCar(){
// 准备数据
Map<String, Object> map = new HashMap<>();
// 让key的可读性增强
map.put("carNum", "103");
map.put("brand", "奔驰E300L");
map.put("guidePrice", 50.3);
map.put("produceTime", "2020-10-01");
map.put("carType", "燃油车");
// 获取SqlSession对象
SqlSession sqlSession = SqlSessionUtil.openSession();
// 执行SQL语句(使用map集合给sql语句传递数据)
int count = sqlSession.insert("insertCar", map);
System.out.println("插入了几条记录:" + count);
sqlSession.commit();
sqlSession.close();
}
}
SQL语句如下【#{} 的里面必须填写map集合的key】:
<?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="car">
<insert id="insertCar">
insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>
</mapper>
pojo传参
第一步:定义一个pojo类Car,提供相关属性。
public class Car {
private Long id;
private String carNum;
private String brand;
private Double guidePrice;
private String produceTime;
private String carType;
@Override
public String toString() {
return "Car{" +
"id=" + id +
", carNum='" + carNum + '\'' +
", brand='" + brand + '\'' +
", guidePrice=" + guidePrice +
", produceTime='" + produceTime + '\'' +
", carType='" + carType + '\'' +
'}';
}
public Car() {
}
public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {
this.id = id;
this.carNum = carNum;
this.brand = brand;
this.guidePrice = guidePrice;
this.produceTime = produceTime;
this.carType = carType;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getCarNum() {
return carNum;
}
public void setCarNum(String carNum) {
this.carNum = carNum;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public Double getGuidePrice() {
return guidePrice;
}
public void setGuidePrice(Double guidePrice) {
this.guidePrice = guidePrice;
}
public String getProduceTime() {
return produceTime;
}
public void setProduceTime(String produceTime) {
this.produceTime = produceTime;
}
public String getCarType() {
return carType;
}
public void setCarType(String carType) {
this.carType = carType;
}
}
第二步:Java程序
@Test
public void testInsertCarByPOJO(){
// 创建POJO,封装数据
Car car = new Car();
car.setCarNum("103");
car.setBrand("奔驰C200");
car.setGuidePrice(33.23);
car.setProduceTime("2020-10-11");
car.setCarType("燃油车");
// 获取SqlSession对象
SqlSession sqlSession = SqlSessionUtil.openSession();
// 执行SQL,传数据
int count = sqlSession.insert("insertCarByPOJO", car);
System.out.println("插入了几条记录" + count);
sqlSession.commit();
sqlSession.close();
}
第三步:SQL语句
<insert id="insertCarByPOJO">
<!--#{} 里写的是POJO的属性名-->
insert into t_car(car_num,brand,guide_price,produce_time,car_type) values(#{carNum},#{brand},#{guidePrice},#{produceTime},#{carType})
</insert>
#{} 里写的是POJO的属性名,如果写成其他的会有问题吗?
注意:
- 采用map集合传参,#{} 里写的是map集合的key,如果key不存在不会报错,数据库表中会插入NULL。
- 采用POJO传参,#{}里写的是get方法的方法名去掉get之后将剩下的单词首字母变小写。
例如:getUsername() --> #{username},getEmail() --> #{email},如果这样的get方法不存在会报错。
mybatis在底层给?传值的时候,先要调用了pojo对象的get方法。例如:car.getCarNum()
delete(Delete)
假设:根据 car_num 进行删除。
SQL语句如下:
<delete id="deleteByCarNum">
delete from t_car where car_num = #{carnum}
</delete>
Java程序如下:
@Test
public void testDeleteByCarNum(){
SqlSession sqlSession = SqlSessionUtil.openSession();
int count = sqlSession.delete("deleteByCarNum", "102");
System.out.println("删除了几条记录:" + count);
sqlSession.commit();
sqlSession.close();
}
运行结果:
注意:
当占位符只有一个的时候,#{} 里面的内容可以随便写。(但最好见名知意)
update(Update)
假设我们现在来修改第二条汽车的信息
SQL语句如下:
<update id="updateCarByPOJO">
update t_car set
car_num = #{carNum},
brand = #{brand},
guide_price = #{guidePrice},
produce_time = #{produceTime},
car_type = #{carType}
where id = #{id}
</update>
Java代码如下:
@Test
public void testUpdateCarByPOJO(){
Car car = new Car();
car.setId(2L);
car.setCarNum("99");
car.setBrand("比亚迪");
car.setGuidePrice(66.66);
car.setProduceTime("2018-09-10");
car.setCarType("电车");
SqlSession sqlSession = SqlSessionUtil.openSession();
int count = sqlSession.update("updateCarByPOJO", car);
System.out.println("更新了几条记录:" + count);
sqlSession.commit();
sqlSession.close();
}
运行结果:
select(Retrieve)
注意:select语句查询会有一个结果集。
查询一条数据
假设:查询id为1的Car信息
对于一个查询语句来说,你需要指定“结果类型”或者“结果映射”。
我们可以在标签中添加 resultType属性,这个属性用来告诉mybatis,查询结果集封装成什么类型的java对象。
resultType通常写的是:全限定类名
SQL语句如下:
<select id="selectCarById" resultType="com.powernode.mybatis.pojo.Car">
select * from t_car where id = #{id}
</select>
Java程序如下:
@Test
public void testSelectCarById(){
SqlSession sqlSession = SqlSessionUtil.openSession();
Object car = sqlSession.selectOne("selectCarById", 1);
System.out.println(car);
sqlSession.commit();
sqlSession.close();
}
运行结果:
仔细观察控制台的日志信息,可以发现返回的Car对象,只有id和brand两个属性有值,其它属性的值都是null,这是因为查询结果列名和Car类的属性名不是一 一对应的:
查询结果集的列名:id, car_num, brand, guide_price, produce_time, car_type
Car类的属性名:id, carNum, brand, guidePrice, produceTime, carType
很显然只有id和brand是一致的,其他字段名和属性名对应不上,这导致其它属性的值都是null。
为了解决这个问题,可以在sql语句中使用as关键字来给查询结果列名起别名试试:
<select id="selectCarById" resultType="com.powernode.mybatis.pojo.Car">
select
id,
car_num as carNum,
brand,
guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
from t_car
where id = #{id}
</select>
运行结果如下:
查询多条数据
假设:查询所有的Car信息。
SQL语句如下:
// resultType要指定封装的结果集的类型。
// 不是指定List类型,是指定List集合中元素的类型。
<select id="selectCarAll" resultType="com.powernode.mybatis.pojo.Car">
select
id,
car_num as carNum,
brand, guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
from t_car
</select>
Java代码如下:
@Test
public void testSelectCarAll() {
SqlSession sqlSession = SqlSessionUtil.openSession();
List<Object> cars = sqlSession.selectList("selectCarAll");
// selectList方法:会自动返回一个List集合。
cars.forEach(car -> System.out.println(car));
sqlSession.commit();
sqlSession.close();
}
运行结果如下:
关于SQL Mapper的namespace
在SQL Mapper配置文件中标签的namespace属性可以翻译为命名空间,这个命名空间主要是为了防止sqlId冲突的。
创建UserMapper.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="lm">
<select id="selectCarAll" resultType="com.powernode.mybatis.pojo.Car">
select
id,
car_num as carNum,
brand, guide_price as guidePrice,
produce_time as produceTime,
car_type as carType
from t_car
</select>
</mapper>
不难看出,CarMapper.xml和UserMapper.xml文件中都有 id=“selectCarAll”
将UserMapper.xm配置到mybatis-config.xml文件中。
<mappers>
<mapper resource="CarMapper.xml"/>
<mapper resource="UserMapper.xml"/>
</mappers>
此时sqlId的完整写法: namespace.id
需要执行哪个命名空间的,就写哪个命名空间的namespace。
Java代码如下:
@Test
public void testNamespace(){
SqlSession sqlSession = SqlSessionUtil.openSession();
List<Object> cars = sqlSession.selectList("lm.selectCarAll");
cars.forEach(car -> System.out.println(car));
sqlSession.commit();
sqlSession.close();
}
运行结果如下: