3. 使用Mybatis完成CRUD

前置工作准备

  • 创建Maven项目 , 引入依赖(mybatis依赖 ,mysql 驱动依赖 ,junit依赖 ,logback 依赖)
  • 将xml文件放到类的根路径下
  • 提供com.north.mybatis.utils.SqlSessionUtil工具类
  • 创建测试用例:com.north.mybatis.CarMapperTest


补充知识:什么是CRUD
C: Create增
R: Retrieve查(检索)
U: Update改
D: Delete删

1. insert(Create

先说理论知识 : 在sql语句中使用 #{map集合的key}来完成传值 等同于JDBC中的 ? ,#{}就是占位符

<insert id="insertCar">
        insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
        values(null,'1003','丰田霸道',30.0,'2000-10-11','燃油车');
    </insert>

上述代码的问题是:

  • 值 显然是写死到配置文件中的。
  • 这个在实际开发中是不存在的。一定是前端的form表单提交过来数据。然后将值传给sql语句。

例如:JDBC的代码是怎么写的?String sql = "insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)";

在JDBC当中占位符采用的是?,在mybatis当中是什么呢?
和?等效的写法是:#{}
在mybatis当中不能使用?占位符,必须使用 #{} 来代替JDBC当中的 ?

{} 和 JDBC当中的 ? 是等效的。


insert的细节之处
java程序中使用POJO类给SQL语句的占位符传值:

  • 注意:占位符#{},大括号里面写:pojo类的属性名 , 但是这样说也并不是很严谨

严格意义上来说:如果使用POJO对象传递值的话,#{}这个大括号中到底写什么?

  • 写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。
  • 例如:getUsername() --> #

也就是说mybatis在底层给 ? 传值的时候,先要获取值,怎么获取的 ?

  • 调用了pojo对象的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()

如果采用map集合传参,#{} 里写的是map集合的key,如果key不存在不会报错,数据库表中会插入NULL。
代码演示 ,这里我自己吸取之前的教训 ,把基本完整的给写出来 ,防止以后再来看的话 , 不知道都代表着是什么意思😊😊😊
工具类代码:

public class SqlSessionUtil {

    // 工具类的构造方法一般都是私有化的。
    // 工具类中所有的方法都是静态的,直接采用类名即可调用。不需要new对象。
    // 为了防止new对象,构造方法私有化。
    private SqlSessionUtil(){}

    private static SqlSessionFactory sqlSessionFactory;

    // 类加载时执行
    // SqlSessionUtil工具类在进行第一次加载的时候,解析mybatis-config.xml文件。创建SqlSessionFactory对象。
    static {
        try {
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /*public static SqlSession openSession(){
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        // SqlSessionFactory对象:一个SqlSessionFactory对应一个environment,一个environment通常是一个数据库。
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream("mybatis-config.xml"));
        SqlSession sqlSession = sqlSessionFactory.openSession();
        return sqlSession;
    }*/

    /**
     * 获取会话对象。
     * @return 会话对象
     */
    public static SqlSession openSession(){
        return sqlSessionFactory.openSession();
    }
}

测试类:

@Test
    public void testInsertCarByPOJO() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        // 封装数据
        Car car = new Car(null , "1005" , "比亚迪汉" , 30.0 , "2020-11-11" , "新能源");
        int rows = sqlSession.insert("insertCar" ,  car);
        System.out.println("插入成功的行数:" + rows);
        sqlSession.commit();
        sqlSession.close();
    }

CarMapper.xml文件中的insert标签:

<insert id="insertCar">
        insert into t_car(id , car_num , brand , guide_price , produce_time , car_type)
        values (null , #{carNum} , #{brand} , #{guidePrice} , #{produceTime} , #{carType})
    </insert>

2. delete (Delete)

注意:如果占位符只有一个,那么#{}的大括号里可以随意。但是最好见名知意。
需求:根据id进行删除数据
CarMapper.xml文件中的delete标签:

<delete id="deleteCar">
        delete from t_car where id = #{id}
    </delete>

测试类:

@Test
    public void testDeleteById() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        int rows = sqlSession.delete("deleteCar", 16);
        System.out.println("删除的行数:" + rows);
        sqlSession.commit();
        sqlSession.close();
    }

3. update(Update)

根据id修改某条数据的代码演示
CarMapper.xml文件中的update标签:

<update id="updateCar">
        update t_car
        set
            car_num = #{carNum} ,
            brand = #{brand} ,
            guide_price = #{guidePrice} ,
            produce_time = #{produceTime} ,
            car_type = #{carType}
        where
            id = #{id}
    </update>

测试类:

@Test
    public void testUpdateById() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        Car car = new Car(4L , "3333" , "梅特赛斯" , 146.8 , "2018-11-11" , "燃油车");
        int rows = sqlSession.update("updateCar", car);
        System.out.println("受影响的行数:" + rows);
        sqlSession.commit();
        sqlSession.close();
    }

4. select(Retrieve)

select语句和其它语句不同的是:查询会有一个结果集

4.1 查询一条数据

其中 ,查一个,根据主键查询的话,返回的结果一定是一个。
需求:根据id进行查询
需要特别注意的是:
select标签中resultType属性,这个属性用来告诉mybatis,查询结果集封装成什么类型的java对象。你需要告诉mybatis。
resultType通常写的是:全限定类名。
注意:select语句查询的时候,查询结果集的列名是可以使用as关键字起别名的。
查询的时候需要在select标签中进行封装结果接映射 ,也就是写上resultType属性 , 不然会进行报错

CarMapper.xml文件中的select标签:

<select id="selectById" resultType="com.north.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>

测试类:

@Test
    public void testSelectById() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        Object selectOne = sqlSession.selectOne("selectById", 1);
        System.out.println(selectOne);
        sqlSession.close();
    }

查询结果展示:

4.2 查询多条数据

需求:查询所有数据
需要注意的是:
resultType还是指定要封装的结果集的类型。不是指定List类型,是指定List集合中元素的类型。
selectList方法:mybatis通过这个方法就可以得知你需要一个List集合。它会自动给你返回一个List集合。
CarMapper.xml文件中的select标签:

<select id="selectAll" resultType="com.north.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>

测试类:

@Test
    public void testSelectAll() {
        SqlSession sqlSession = SqlSessionUtil.openSession();
        List<Object> selectAll = sqlSession.selectList("selectAll");
        selectAll.forEach(car -> System.out.println(car));
        sqlSession.close();
    }

运行结果展示:

5. 关于SQL Mapper的namespace

namespace的作用
在sql mapper.xml文件当中有一个namespace,这个属性是用来指定命名空间的。用来防止id重复。
实际上,本质上,mybatis中的sqlId的完整写法:namespace.id

posted @ 2024-06-11 07:50  捞月亮的小北  阅读(8)  评论(0编辑  收藏  举报