跟老杜从零入门MyBatis到架构思维(四)使用MyBatis完成CRUD-下

72 阅读3分钟

使用MyBatis完成CRUD

配合视频教程观看,更易学习理解,课程讲解从Mybatis的一些核心要点与实战中的运用,一直过渡到MyBaits源码,由表及里的代入架构思维。一步一案例,一码一实操。从简单到深入,从实战到源码,MyBatis重点、难点、考点一网打尽。

相关的学习资料给大家备好了

​点这里!​

delete(Delete)

需求:根据car_num进行删除。

SQL语句这样写:

<delete id="deleteByCarNum">
  delete from t_car where car_num = #{SuiBianXie}
</delete>

Java程序这样写:

@Test
public void testDeleteByCarNum(){
    // 获取SqlSession对象
    SqlSession sqlSession = SqlSessionUtil.openSession();
    // 执行SQL语句
    int count = sqlSession.delete("deleteByCarNum", "102");
    System.out.println("删除了几条记录:" + count);
}

运行结果:

编辑

注意:当占位符只有一个的时候,${} 里面的内容可以随便写。

3.3 update(Update)

需求:修改id=34的Car信息,car_num为102,brand为比亚迪汉,guide_price为30.23,produce_time为2018-09-10,car_type为电车

修改前:

编辑

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(34L);
        car.setCarNum("102");
        car.setBrand("比亚迪汉");
        car.setGuidePrice(30.23);
        car.setProduceTime("2018-09-10");
        car.setCarType("电车");
        // 获取SqlSession对象
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 执行SQL语句
        int count = sqlSession.update("updateCarByPOJO", car);
        System.out.println("更新了几条记录:" + count);
    }

运行结果:

编辑

编辑

当然了,如果使用map传数据也是可以的。

3.4 select(Retrieve)

select语句和其它语句不同的是:查询会有一个结果集。来看mybatis是怎么处理结果集的!!!

查询一条数据

需求:查询id为1的Car信息

SQL语句如下:

<select id="selectCarById">
  select * from t_car where id = #{id}
</select>

Java程序如下:

@Test
public void testSelectCarById(){
    // 获取SqlSession对象
    SqlSession sqlSession = SqlSessionUtil.openSession();
    // 执行SQL语句
    Object car = sqlSession.selectOne("selectCarById", 1);
    System.out.println(car);
}

运行结果如下:

### Error querying database.  Cause: org.apache.ibatis.executor.ExecutorException: 
    A query was run and no Result Maps were found for the Mapped Statement 'car.selectCarById'.  【翻译】:对于一个查询语句来说,没有找到查询的结果映射。
    It's likely that neither a Result Type nor a Result Map was specified.						 【翻译】:很可能既没有指定结果类型,也没有指定结果映射。

以上的异常大致的意思是:对于一个查询语句来说,你需要指定它的“结果类型”或者“结果映射”。

所以说,你想让mybatis查询之后返回一个Java对象的话,至少你要告诉mybatis返回一个什么类型的Java对象,可以在标签中添加resultType属性,用来指定查询要转换的类型: <select id="selectCarById" resultType="com.powernode.mybatis.pojo.Car"> select * from t_car where id = #{id} </select> 运行结果: ​ 编辑 运行后之前的异常不再出现了,这说明添加了resultType属性之后,解决了之前的异常,可以看出resultType是不能省略的。 仔细观察控制台的日志信息,不难看出,结果查询出了一条。并且每个字段都查询到值了:Row: 1, 100, 宝马520Li, 41.00, 2022-09-01, 燃油车 但是奇怪的是返回的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> 运行结果如下: ​ 编辑 通过测试得知,如果当查询结果的字段名和java类的属性名对应不上的话,可以采用as关键字起别名,当然还有其它解决方案,我们后面再看。 查询多条数据 需求:查询所有的Car信息。 SQL语句如下: <!--虽然结果是List集合,但是resultType属性需要指定的是List集合中元素的类型。--> <select id="selectCarAll" resultType="com.powernode.mybatis.pojo.Car"> <!--记得使用as起别名,让查询结果的字段名和java类的属性名对应上。--> 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 sqlSession = SqlSessionUtil.openSession(); // 执行SQL语句 List<Object> cars = sqlSession.selectList("selectCarAll"); // 输出结果 cars.forEach(car -> System.out.println(car)); } 运行结果如下: ​ 编辑 3.5 关于SQL Mapper的namespace 在SQL Mapper配置文件中标签的namespace属性可以翻译为命名空间,这个命名空间主要是为了防止sqlId冲突的。 创建CarMapper2.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="car2"> <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和CarMapper2.xml文件中都有 id="selectCarAll" 将CarMapper2.xml配置到mybatis-config.xml文件中。 <mappers> <mapper resource="CarMapper.xml"/> <mapper resource="CarMapper2.xml"/> </mappers> 编写Java代码如下: @Test public void testNamespace(){ // 获取SqlSession对象 SqlSession sqlSession = SqlSessionUtil.openSession(); // 执行SQL语句 List<Object> cars = sqlSession.selectList("selectCarAll"); // 输出结果 cars.forEach(car -> System.out.println(car)); } 运行结果如下: org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.IllegalArgumentException: selectCarAll is ambiguous in Mapped Statements collection (try using the full name including the namespace, or rename one of the entries) 【翻译】selectCarAll在Mapped Statements集合中不明确(请尝试使用包含名称空间的全名,或重命名其中一个条目) 【大致意思是】selectCarAll重名了,你要么在selectCarAll前添加一个名称空间,要有你改个其它名字。 Java代码修改如下: @Test public void testNamespace(){ // 获取SqlSession对象 SqlSession sqlSession = SqlSessionUtil.openSession(); // 执行SQL语句 //List<Object> cars = sqlSession.selectList("car.selectCarAll"); List<Object> cars = sqlSession.selectList("car2.selectCarAll"); // 输出结果 cars.forEach(car -> System.out.println(car)); } 运行结果如下: ​ 编辑 ​