Mybatis高级

1. 注解开发(理解)

对于简单的SQL,建议使用注解;对于复杂SQL,建议使用xml配置映射配置文件。

1.1 常用注解

  • @Insert:实现新增 相当于标签

    @Update:实现更新 相当于标签

    @Delete:实现删除 相当于标签

    @Select:实现查询 相当于标签

1.3查询-单表

interface StudentMapper{
    // 标注在方法是,可以通过注解获取到方法的返回值类型、参数类型、该方法属于哪个类
    @Select("select * from student")
    List<Student> findAll();
}

测试代码

@Test
public void insert() throws Exception{
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    //3.通过工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    //4.获取StudentMapper接口的实现类对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //5.调用实现类对象中的方法,接收结果
    Student stu = new Student(4,"赵六",26);
    Integer result = mapper.insert(stu);

    //6.处理结果
    System.out.println(result);
    for(Student stu : list){
        System.out.println(stu);
    }

    //7.释放资源
    sqlSession.close();
    is.close();
}

1.4 新增-单表

StudentMapper接口

interface StudentMapper{
    //新增操作
    @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
    Integer insert(Student stu);
}

测试代码

@Test
public void insert() throws Exception{
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    //3.通过工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    //4.获取StudentMapper接口的实现类对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //5.调用实现类对象中的方法,接收结果
    Student stu = new Student(4,"赵六",26);
    Integer result = mapper.insert(stu);

    //6.处理结果
    System.out.println(result);

    //7.释放资源
    sqlSession.close();
    is.close();
}
1.4.1 新增并返回自增的主键

StudentMapper接口

interface StudentMapper{
    //新增操作
    @Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
    @Option(useGeneratedKeys=true, keyColumns="id",keyProperty="id")
    Integer insert(Student stu);
}

新增之前,封装了一个Student对象,该对象的id没有赋值;当调用完新增方法之后,会把当前学生的信息保存进数据库并返回主键id,而且会把该id设置进之前是Student对象。

1.5 修改-单表

StudentMapper接口

interface StudentMapper{
    //修改操作
    @Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
    public abstract Integer update(Student stu);
}

测试代码

@Test
public void update() throws Exception{
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    //3.通过工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    //4.获取StudentMapper接口的实现类对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //5.调用实现类对象中的方法,接收结果
    Student stu = new Student(4,"赵六",36);
    Integer result = mapper.update(stu);

    //6.处理结果
    System.out.println(result);

    //7.释放资源
    sqlSession.close();
    is.close();
}

1.6 删除-单表

StudentMapper接口

interface StudentMapper{
    //删除操作
    @Delete("DELETE FROM student WHERE id=#{idx}")
    public abstract Integer delete(@Param("idx")Integer id);
}

测试代码

@Test
public void delete() throws Exception{
    //1.加载核心配置文件
    InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");

    //2.获取SqlSession工厂对象
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

    //3.通过工厂对象获取SqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession(true);

    //4.获取StudentMapper接口的实现类对象
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);

    //5.调用实现类对象中的方法,接收结果
    Integer result = mapper.delete(4);

    //6.处理结果
    System.out.println(result);

    //7.释放资源
    sqlSession.close();
    is.close();
}

1.7 一对一查询

CardMapper.java

public interface CardMapper {
    //查询全部
    @Select("SELECT * FROM card")  //@Select 相当于Select标签
    @Results({                      //@Results 相当于 ResultMap标签
            @Result(column = "id",property = "id",id = true), // @Result + id=true相当于id标签
            @Result(column = "number",property = "number"),  @Result + id=fasle相当于result标签
            @Result(                                            //@Result 相当于association
                    property = "p",             // 被关联对象的变量名
                    javaType = Person.class,    // 被关联对象的实际数据类型
                    column = "pid",             // 根据查询出的card表中的pid字段来查询person表
                    /*
                        one = @One(select="") 一对一分步查询,延迟加载的固定写法
                        select属性:指定查询关联对象时,调用哪个接口中的哪个方法
                     */
                    one = @One(select = "com.itheima.one_to_one.PersonMapper.selectById")
            )
    })
    public abstract List<Card> selectAll();
}

PersonMapper.java

public interface PersonMapper {
    //根据id查询
    @Select("SELECT * FROM person WHERE id=#{id}")
    public abstract Person selectById(Integer id);
}

1.8 一对多查询

ClassesMapper.java

public interface ClassesMapper {
    //查询全部
    @Select("SELECT * FROM classes")
    @Results({
            @Result(column = "id",property = "id",id=true),
            @Result(column = "name",property = "name"),
            @Result(
                    property = "students",  // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出的classes表的id字段来查询student表
                    /*
                        many = @Many(select="") 一对多分步查询,延迟加载的固定写法
                        select属性:指定查询关联对象时,调用哪个接口中的哪个方法
                     */
                    many = @Many(select = "com.itheima.one_to_many.StudentMapper.selectByCid")
            )
    })
    public abstract List<Classes> selectAll();
}

StudentMapper.java

public interface StudentMapper {
    //根据cid查询student表
    @Select("SELECT * FROM student WHERE cid=#{cid}")
    public abstract List<Student> selectByCid(Integer cid);
}

1.9 多对多

多对多的本质就是多个一对多,可以使用一对多映射多对多。

public interface StudentMapper {
    // 查询有选课信息的全部学生,加上中间表联查目的是为了去除没有选课的学生
    @Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
    // 查询所有学生
    // @Select("SELECT * FROM student ")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(column = "age",property = "age"),
            @Result(
                    property = "courses",   // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出student表的id来作为关联条件,去查询中间表和课程表
                    /*
                        many = @Many(select="") 一对多分步查询,延迟加载的固定写法
                        select属性:指定查询关联对象时,调用哪个接口中的哪个方法
                     */
                    many = @Many(select = "com.itheima.many_to_many.CourseMapper.selectCourseByStudentid")
            )
    })
    public abstract List<Student> selectAll();
}

CourseMapper.java

public interface CourseMapper {
    //根据学生id查询所选课程
    @Select("SELECT c.id,c.name FROM stu_cr sc,course c WHERE sc.cid=c.id AND sc.sid=#{id}")
    public abstract List<Course> selectCourseByStudentid(Integer studentId);
}

3. SQL构建(了解)

SQL写在注解中不美观且手动写SQL容易出错,可以通过mybatis提供的构建自动生成SQL语句

作用:

  1. 不用手写SQL
  2. 可以实现动态SQL拼接

select * from student

SQL.select("**").from(“student”) .toString = select * from student

3.1 注解

@SelectProvider

@InsertProvider

@UpdateProvider

@DeleteProvider

3.2 使用

标注在dao层接口的方法上,获取用户构建好的SQL语句

  • type属性:指定构建SQL语句的类的类型 Xxx.class

  • method属性:指定构建SQL语句的类中的方法名(字符串形式,无括号),"getAll"

    如果说SQL语句需要传递参数,在构造SQL的方法形参位置定义与dao层接口对应方法相同类型的参数即可。

3.3 代码

构建SQL语句的ReturnSql.java

public class ReturnSql {
    //定义方法,返回查询的sql语句
    public String getSelectAll() {
        /*return new SQL() {
            {
                SELECT("*");
                FROM("student");
            }
        }.toString();*/
        return new SQL().SELECT("*").FROM("student").toString();
    }

    //定义方法,返回新增的sql语句
    public String getInsert(Student stu) {
        /*return new SQL() {
            {
                INSERT_INTO("student");
                INTO_VALUES("#{id},#{name},#{age}");
            }
        }.toString();*/
        return "INSERT INTO student VALUES (#{id},#{name},#{age})";
    }

    //定义方法,返回修改的sql语句
    public String getUpdate(Student stu) {
        return new SQL() {
            {
                /*UPDATE("student");
                SET("name=#{name}", "age=#{age}");
                WHERE("id=#{id}");*/
                UPDATE("student").SET("name=#{name}", "age=#{age}").WHERE("id=#{id}");
            }
        }.toString();
    }

    //定义方法,返回删除的sql语句
    public String getDelete(Integer id) {
        return new SQL() {
            {
                DELETE_FROM("student");
                WHERE("id=#{id}");
            }
        }.toString();
    }
}

数据持久层接口类StudentMapper.java

public interface StudentMapper {
    //查询全部
    //@Select("SELECT * FROM student")
    /*
        type:生成SQL语句的类
        method:生成SQL语句的类的方法名称
    * */

    @SelectProvider(type = ReturnSql.class , method = "getSelectAll")
    public abstract List<Student> selectAll();


    //新增功能
    //@Insert("INSERT INTO student VALUES (#{id},#{name},#{age})")
        /*
        type:生成SQL语句的类
        method:生成SQL语句的类的方法名称
    * */
    @InsertProvider(type = ReturnSql.class , method = "getInsert")
    public abstract Integer insert(Student stu);

    //修改功能
    //@Update("UPDATE student SET name=#{name},age=#{age} WHERE id=#{id}")
    @UpdateProvider(type = ReturnSql.class , method = "getUpdate")
    public abstract Integer update(Student stu);

    //删除功能
    //@Delete("DELETE FROM student WHERE id=#{id}")
    @DeleteProvider(type = ReturnSql.class , method = "getDelete")
    public abstract Integer delete(Integer id);
}

3. 学生管理系统

整合

  1. 导包 mybatis log4j

  2. 编写配置文件核心配置使用xml

  3. 在接口中为每个方法编写SQL语句(映射配置使用注解)

  4. Service中要要修改获取dao层接口实现类对象的方式

    从原来自己new一个,改成找MybatisSQLSession获取

MybatisUtils.java

public class MybatisUtils<T> {

    private static SqlSession sqlSession = null;
    private static InputStream is = null;

    private MybatisUtils() {
    }


    // 提供获取Dao层接口代理对象的方法
    public static SqlSession getSqlSession() {
        try {
            //1.加载核心配置文件
            is = Resources.getResourceAsStream("MyBatisConfig.xml");

            //2.获取SqlSession工厂对象
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);

            //3.通过工厂对象获取SqlSession对象
            sqlSession = sqlSessionFactory.openSession(true);


        } catch (Exception e) {
			e.printStackTrace();
        }
       return sqlSession;
    }


    // 释放资源
    public static void realse(){
        sqlSession.close();
        try {
            is.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

逆向工程

逆向工程:

原来步骤:自己domain、dao、dao.xml,对应数据库中的表

逆向工程:根据数据库库中的表,自动生成domain、dao接口、daoxml

Mybatis官方提供了逆向工程实现的基础jar包:mybatis-generator-core-1.3.6.jar

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值