• MyBatis Dao层的编写


    传统的dao层编写

    以前编写dao层,先新建一个包com.chy.dao,再写接口StudentDao:

    public interface StudentDao {
        public void insertStudent(Student student);
    
        public void updateStudent(Student student, Integer id);
    
        public Student selectStudent(Integer id);
    }

    接着写实现类StudentDaoImpl:

    public class StudentDaoImpl implements StudentDao {
        @Override
        public void insertStudent(Student student) {
    
        }
    
        @Override
        public void updateStudent(Student student, Integer id) {
    
        }
    
        @Override
        public Student selectStudent(Integer id) {
            return null;
        }
    }

    MyBatis的dao层编写

    MyBatis不这样编写dao。MyBatis的dao由2部分组成:映射文件、映射文件对应的接口。

    新建一个包com.chy.mapper,包下新建接口StudentMapper:

    public interface StudentMapper {
        public void insertStudent(Student student);
    
        public Student selectStudent(Integer id);
    }

    包下新建此接口对应的映射文件StudentMapper.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="com.chy.mapper.StudentMapper">
        <insert id="insertStudent" parameterType="com.chy.pojo.Student">
            INSERT INTO student_tb(name,age,score)VALUES (#{name},#{age},#{score})
        </insert>
    
        <select id="queryById" parameterType="Integer" resultType="Student">
            SELECT * FROM student_tb WHERE id=#{id}
        </select>
    </mapper>
    • 映射文件的文件名、namespace要与接口名相同,面向接口编程。
    • id要与接口中的方法名相同
    • 参数类型、返回值类型要与接口中的一致
    • 接口中的方法最多只能有一个参数,因为映射文件的参数类型最多只能有一个

    mapper包相当于传统方式的dao包,映射文件相当于接口的实现类。


    MyBatis dao层的使用

    在mybatis全局配置文件中引入映射文件。

         InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession=sqlSessionFactory.openSession();
    
            //通过mapper来调用接口中的方法,操作数据库
            //参数是mapper接口类的class对象
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            //插入
            Student student1 = new Student();
            student1.setName("chy");
            mapper.insertStudent(student1);
    
            //查询
            Student student2 = mapper.queryById(1);
            System.out.println(student2);
    
            sqlSession.commit();
            sqlSession.close();

    说明

    Mapper接口不是必需的。

    如果不写Mapper接口,那只能通过sqlSession.selectOne()之类的方式操作数据库;

    编写了Mapper接口,才可以通过Mapper接口来操作数据库,sqlSession.getMapper(),实质是动态代理。


    传入包装类型的参数

    有时候我们需要传入多个参数,比如

    • 查询age>20、score>90的学生,需要传入2个Integer型的参数
    • 查询某本书在这一周的销量,需要传入一个pojo类:Book,还需要传入一个参数表示这一周以内。
    • 要查询某用户购买某辆汽车的订单信息,需要传入2个pojo类:User、Car

    这种传入多个参数的情况在复杂的条件查询中比较常见,尤其是多表查询。

    mybatis最多只能传入一个参数,怎么办?

    可以把要传入的参数包装一下,放在一个包装类中,传入包装类即可

    新建包com.chy.vo,包下新建包装类UserQueryVO,将要传入的参数写为成员变量,并提供getter、setter方法:

    public class UserQueryVO {
        private User user;
        private Car car;
    
        public User getUser() {
            return user;
        }
    
        public void setUser(User user) {
            this.user = user;
        }
    
        public Car getCar() {
            return car;
        }
    
        public void setCar(Car car) {
            this.car = car;
        }
    }

    vo:value object  值对象

    po:persist object   持久化对象,与数据表对应。

    pojo:plain ordinary java object  简单的Java对象

    在com.chy.mapper包下新建UserMapper接口,编写对应的映射文件实现数据库操作。

    public interface UserMapper {
        public Order queryOrder(UserQueryVO vo);
    }
    <mapper namespace="com.chy.mapper.UserMapper">
        <select id="queryOrder" parameterType="com.chy.vo.UserQueryVO" resultType="com.chy.pojo.Order">
            SELECT * FROM order_tb WHERE order_tb.user_id=#{user.id} AND order_tb.car_name=#{car.name}
        </select>
    </mapper>

    #{}中的user、car是vo的属性,这2个属性本身也是对象,可通过.来访问user、car的属性。

    使用:

         InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession=sqlSessionFactory.openSession();
    
            Car car = new Car();
            car.setName("宝马X6");
    
            User user = new User();
            user.setId(1);
    
            //要传入的包装类
            UserQueryVO vo = new UserQueryVO();
            vo.setCar(car);
            vo.setUser(user);
    
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            //传入包装类进行查询
            Order order = mapper.queryOrder(vo);
            System.out.println(order);

    使用Map传入多个参数

    除了可以使用包装类传入多个参数,也可以使用Map传入多个参数。

    Mapper接口:

    public interface UserMapper {
        public Order queryOrder(Map<String,Object> map);
    }

    这个是Mapper接口,所以参数通常写接口,不写具体的实现类,让耦合是接口层次的。

    要传入的参数的数据类型不同,写成Object。

    映射文件:

    <mapper namespace="com.chy.mapper.UserMapper">
        <select id="queryOrder" parameterType="HashMap" resultType="com.chy.pojo.Order">
            SELECT * FROM order_tb WHERE order_tb.user_id=#{user.id} AND order_tb.car_name=#{car.name}
        </select>
    </mapper>

    #{}中的user、car是map的key,得到对应的value(对象),再通过.获取属性值。

    使用:

         InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession sqlSession=sqlSessionFactory.openSession();
    
            Car car = new Car();
            car.setName("宝马X6");
    
            User user = new User();
            user.setId(1);
    
            //要传入的map
            HashMap<String,Object> map = new HashMap<>();
            map.put("car", car);
            map.put("user", user);
    
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            //传入map进行查询
            Order order = mapper.queryOrder(map);
            System.out.println(order);

    与使用包装类传入多个参数相比,使用map不需要创建vo类,更加简单。


    使用List传入多个参数

        <update id="updateMoney" parameterType="list">
            <!--传入map,直接通过key来引用-->
            update user_tb set money=#{list[1]} where id=#{list[0]}
        </update>

    默认以list代表列表名。

      


    使用@Param直接传入多个参数

    不使用@Param,则只能有一个参数;使用@Param,可以有多个参数。

    mapper接口:

    public interface UserMapper {
        public double queryMoneyById(int id);
        public void updateMoney(@Param("id") int id, @Param("money") double money);
    }

    映射文件:

        <update id="updateMoney">
            <!--传入map,直接通过key来引用-->
            update user_tb set money=#{money} where id=#{id}
        </update>

    不设置参数类型,@Param("value")、#{value}这2个value要相同,通过这个值来绑定参数。

  • 相关阅读:
    (转)ubuntu 对拍和基本操作
    一个在线翻译LateX的网站
    51nod 1376: 最长递增子序列的数量(二维偏序+cdq分治)
    BZOJ1087: [SCOI2005]互不侵犯King(状态压缩动态规划)
    ZOJ Problem Set
    bzoj2301:[HAOI2011]Problem b(容斥+莫比乌斯反演+分块)
    BZOJ 4318 OSU!期望DP
    CodeForces 235B Let's Play Osu!(概率)
    博客界面美化
    A+B Problem
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12152695.html
Copyright © 2020-2023  润新知