第十节:MyBatis之常用注解、注解的多表操作、构建SQL

一. 常用注解

1. 简介

 Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。常用注解如下:

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

@Results:可以与@Result 一起使用,封装多个结果集

@One:实现一对一结果集封装

@Many:实现一对多结果集封装

2. 实战

(1). 核心配置文件(已经没有映射配置文件了)

<?xml version="1.0" encoding="UTF-8" ?>
<!--MyBatis的DTD约束-->
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">

<!--configuration 核心根标签-->
<configuration>

    <!--引入数据库连接的配置文件-->
    <properties resource="jdbc.properties"/>

    <!--配置LOG4J-->
    <settings>
        <setting name="logImpl" value="log4j"/>
    </settings>

    <!--起别名-->
    <typeAliases>
        <!--<typeAlias type="com.ypf.bean.Student" alias="student"/>-->
        <!-- 全局别名通用配置 -->
        <package name="com.ypf.bean"/>
    </typeAliases>


    <!--environments配置数据库环境,环境可以有多个。default属性指定使用的是哪个-->
    <environments default="mysql">
        <!--environment配置数据库环境  id属性唯一标识-->
        <environment id="mysql">
            <!-- transactionManager事务管理。  type属性,采用JDBC默认的事务-->
            <transactionManager type="JDBC"></transactionManager>
            <!-- dataSource数据源信息   type属性 连接池-->
            <dataSource type="POOLED">
                <!-- property获取数据库连接的配置信息 -->
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- mappers引入映射配置文件 -->
    <mappers>
        <!--扫描使用注解的类-->
         <!--  <mapper class="com.ypf.dao.StudentDao"></mapper>-->

        <!-- 或 扫描使用注解的类所在的包-->
          <package name="com.ypf.dao"></package>

    </mappers>

</configuration>
View Code

(2). 代理接口

public interface StudentDao {
    //查询全部
    @Select("SELECT * FROM student")
    public abstract List<Student> selectAll();

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

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

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

}

(3). 测试代码

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

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

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

        //4.获取StudentDao实现类对象,并调用相关方法
        StudentDao sDao=sqlSession.getMapper(StudentDao.class);
        List<Student> list=sDao.selectAll();

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

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



    /*
       删除功能
    */
    @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();
        //SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取StudentDao实现类对象,并调用相关方法
        StudentDao sDao=sqlSession.getMapper(StudentDao.class);
        int result=sDao.delete(5);

        //5.提交事务
        sqlSession.commit();

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

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

    /*
        修改功能
     */
    @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();
        //SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取StudentDao实现类对象,并调用相关方法
        Student stu = new Student(5,"周七",37);
        StudentDao sDao=sqlSession.getMapper(StudentDao.class);
        int result=sDao.update(stu);

        //5.提交事务
        sqlSession.commit();

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

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

    /*
        新增功能
     */
    @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();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);   //设为true,表示自动提交事务,后面则不需要sqlSession.commit了

        //4.获取StudentDao实现类对象,并调用相关方法
        Student stu = new Student(5,"周七",27);
        StudentDao sDao=sqlSession.getMapper(StudentDao.class);
        int result = sDao.insert( stu);

        //5.提交事务
        //sqlSession.commit();

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

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

二. 注解的多表操作

1. 整体说明

 实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置。

2. 实战

(1). 代理接口

public interface DynamicMapper {

    //查询全部(1对1  )
    @Select("SELECT * FROM card")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "number",property = "number"),
            @Result(
                    property = "p",             // 被包含对象的变量名
                    javaType = Person.class,    // 被包含对象的实际数据类型(关联类)
                    column = "pid",             // 根据查询出的card表中的pid字段来查询person表
                    /*
                        one、@One 一对一固定写法
                        select属性:指定调用哪个接口中的哪个方法
                     */
                    one = @One(select = "com.ypf.dao.DynamicMapper.selectById")
            )
    })
    public abstract List<Card> selectAll();

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



    //1个班级对应多个学生(1对多)
    @Select("SELECT * FROM classes")
    @Results({
            @Result(column = "id",property = "id"),
            @Result(column = "name",property = "name"),
            @Result(
                    property = "students",  // 被包含对象的变量名
                    javaType = List.class,  // 被包含对象的实际数据类型
                    column = "id",          // 根据查询出的classes表的id字段来查询student表
                    /*
                        many、@Many 一对多查询的固定写法
                        select属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.ypf.dao.DynamicMapper.selectByCid")
            )
    })
    public abstract List<Classes> selectAll2();


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



    //查询全部(多对多  课程和学生是多对多的关系)
    @Select("SELECT DISTINCT s.id,s.name,s.age FROM student s,stu_cr sc WHERE sc.sid=s.id")
    @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属性:指定调用哪个接口中的哪个查询方法
                     */
                    many = @Many(select = "com.ypf.dao.DynamicMapper.selectBySid")
            )
    })
    public abstract List<Student> selectAll3();


    //根据学生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> selectBySid(Integer id);

}
View Code

(2). 测试类 

public class AnnotationRelationTest {

    @Test
    public void selectOneToOne() 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.获取DynamicMapper接口的实现类对象
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Card> list = mapper.selectAll();

        //6.处理结果
        for (Card card : list) {
            System.out.println(card);
        }

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

    @Test
    public void selectOneToMany() 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.获取DynamicMapper接口的实现类对象
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Classes> list = mapper.selectAll2();

        //6.处理结果
        for (Classes cls : list) {
            System.out.println(cls.getId() + "," + cls.getName());
            List<Student> students = cls.getStudents();
            for (Student student : students) {
                System.out.println("	" + student);
            }
        }

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


    @Test
    public void selectManyToMany() 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.获取DynamicMapper接口的实现类对象
        DynamicMapper mapper = sqlSession.getMapper(DynamicMapper.class);

        //5.调用实现类对象中的方法,接收结果
        List<Student> list = mapper.selectAll3();

        //6.处理结果
        for (Student student : list) {
            System.out.println(student.getId() + "," + student.getName() + "," + student.getAge());
            List<Course> courses = student.getCourses();
            for (Course cours : courses) {
                System.out.println("	" + cours);
            }
        }

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




}
View Code

三. 构建SQL

1. 说明

 上述通过注解开发时,相关 SQL 语句都是自己直接拼写的。一些关键字写起来比较麻烦、而且容易出错。  MyBatis 给我们提供了 org.apache.ibatis.jdbc.SQL 功能类,专门用于构建 SQL 语句。

2. 实战测试

(1). SQL构建类

public class ReturnSql {

    //定义方法,返回查询的sql语句
    public String getSelectAll() {
        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();
    }

    //定义方法,返回修改的sql语句
    public String getUpdate(Student stu) {
        return new SQL() {
            {
                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();
    }
}
View Code

(2). 代理接口

public interface DynamicMapper {

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

    //新增功能
    @InsertProvider(type = ReturnSql.class , method = "getInsert")
    public abstract Integer insert(Student stu);

    //修改功能
    @UpdateProvider(type = ReturnSql.class , method = "getUpdate")
    public abstract Integer update(Student stu);

    //删除功能
    @DeleteProvider(type = ReturnSql.class , method = "getDelete")
    public abstract Integer delete(Integer id);

}

(3). 测试类

public class DynamicSQLTest {

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

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

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

        //4.获取DynamicMapper实现类对象,并调用相关方法
        DynamicMapper sDao=sqlSession.getMapper(DynamicMapper.class);
        List<Student> list=sDao.selectAll();

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

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



    /*
       删除功能
    */
    @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();
        //SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取DynamicMapper实现类对象,并调用相关方法
        DynamicMapper sDao=sqlSession.getMapper(DynamicMapper.class);
        int result=sDao.delete(5);

        //5.提交事务
        sqlSession.commit();

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

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

    /*
        修改功能
     */
    @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();
        //SqlSession sqlSession = sqlSessionFactory.openSession(true);

        //4.获取DynamicMapper实现类对象,并调用相关方法
        Student stu = new Student(5,"周七",37);
        DynamicMapper sDao=sqlSession.getMapper(DynamicMapper.class);
        int result=sDao.update(stu);

        //5.提交事务
        sqlSession.commit();

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

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

    /*
        新增功能
     */
    @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();
        SqlSession sqlSession = sqlSessionFactory.openSession(true);   //设为true,表示自动提交事务,后面则不需要sqlSession.commit了

        //4.获取DynamicMapper实现类对象,并调用相关方法
        Student stu = new Student(5,"周七",27);
        DynamicMapper sDao=sqlSession.getMapper(DynamicMapper.class);
        int result = sDao.insert( stu);

        //5.提交事务
        //sqlSession.commit();

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

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

!

  • 作       者 : Yaopengfei(姚鹏飞)
  • 博客地址 : http://www.cnblogs.com/yaopengfei/
  • 声     明1 : 如有错误,欢迎讨论,请勿谩骂^_^。
  • 声     明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,否则保留追究法律责任的权利。
 
原文地址:https://www.cnblogs.com/yaopengfei/p/15016061.html