MyBatis注解开发相关习题
Posted a-oyi
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis注解开发相关习题相关的知识,希望对你有一定的参考价值。
文章目录
一、单选题
1、下列属性中,不属于@Results注解的是()。
A、column
B、property
C、size
D、one
正确答案:C
无解析
2、下列注解中,可以实现一对一关联查询的是()。
A、@Select
B、@Result
C、@One
D、@Many
正确答案:C
MyBatis中@Results注解可以用在三种关联查询方式中,其中@Result注解是@results的子元素;@One可以实现一对一关联查询;@Many可以实现一对多关联查询
3、在数据表employee中根据id删除员工信息,下列@Delete注解的写法正确的是()。
A、@Delete(“delete from employee where id = ?”)
B、@Delete(“delete from employee”)
C、@Delete(“delete from employee where id = #id”)
D、以上说法都不正确
正确答案:C
无解析
4、要求根据员工的id查找员工信息,下列使用@Select注解的代码书写正确的是()。
A、@Select(“select * from tb_worker where id = ?”)
B、@Select(“select * from tb_worker where id = #id”)
C、@Select(“select * from tb_worker where id = id”)
D、@Select(“select * from tb_worker where id = #id”)
正确答案:D
#是MyBatis提供的支持动态SQL的语法
5、下列选项中,使用@Select和@Param编写代码正确的是()。
A、@Select(“select * from tb_worker where id = #param01”)
Worker selectWorkerByIdAndName(@Param(“param01”) int id);
B、@Select(“select * from tb_worker where id = #param”)
Worker selectWorkerByIdAndName(@Param(“param01”) int id);
C、@Select(“select * from tb_worker where id = param01”)
Worker selectWorkerByIdAndName(@Param(“param01”) int id);
D、@Select(“select * from tb_worker where id = param01”)
Worker selectWorkerByIdAndName(@Param(“param01”) int id);
正确答案:A
无解析
6、关于@Insert注解的使用,下列代码书写正确的是()。
A、Insert(“insert into tb_worker(name,age,sex,worker_id)”
+“values(#name,#age,#sex,#worker_id)”)
int insertWorker(Worker worker);
B、@Insert(“insert into tb_worker(name,age,sex,worker_id)”
+“values(#name #age #sex #worker_id)”)
int insertWorker(Worker worker);
C、@Insert(“insert into tb_worker(name,age,sex,worker_id)”
+“values(#name,#age,#sex,#worker_id)”)
int insertWorker(Worker worker);
D、@Insert(“insert into tb_worker(name,age,sex,worker_id)”
+“values(name,age,sex,worker_id)”)
int insertWorker(Worker worker);
正确答案:C
无解析
二、多选题
7、下列关于@Results注解的属性说法正确的是()。
A、property属性用来指定关联属性
B、column属性用来指定关联的数据库表中的字段
C、one属性用来指定数据表之间属于哪种关联关系
D、以上说法都正确
正确答案:A,B,C,D
以上说法都正确
8、关于注解的说法,下列选项正确的是()。
A、@Select注解用于映射查询语句,其作用等同于XML配置文件中的<select>元素
B、@Insert注解用于映射插入语句,其作用等同于XML配置文件中的<insert>元素
C、@Update注解用于映射更新语句,其作用等同于XML配置文件中的<update>元素
D、@Delete注解用于映射删除语句,其作用等同于XML配置文件中的<delete>元素
正确答案:A,B,C,D
以上说法都正确
9、下列注解中,属于MyBatis常用注解的是()。
A、@Select注解
B、@Insert注解
C、@Update注解
D、@Delete注解
正确答案:A,B,C,D
以上说法都正确
三、判断题
10、在@Results注解中,只能包含一个@Result注解。
正确答案:错
可以包含多个的,@Result注解的作用是完成实体类中属性和数据表中字段的映射
11、在@Results注解中,可以包含多个@Result注解,一个@Result注解完成实体类中一个属性和数据表中一个字段的映射。
正确答案:对
无解析
12、在@Many注解中,select属性用于指定关联属性的值。
正确答案:对
无解析
13、MyBatis中,@Update注解的参数可以是一条插入语句,也可以是一条更新语句。
正确答案:错
@Update注解的参数是一条更新语句,参数是插入语句的注解为@Insert
14、MyBatis中,除了XML的映射方式,MyBatis还支持通过注解实现POJO对象和数据表之间的关系映射。
正确答案:对
无解析
15、MyBatis中使用注解进行删除时,一般将SQL语句直接写在接口上。
正确答案:对
无解析
16、MyBatis中,@Update注解用于映射更新语句,其作用等同于XML配置文件中的<update>元素。
正确答案:对
无解析
17、在数据库中,表与表之间的多对多关联关系通常使用一个中间表来维护。
正确答案:对
无解析
18、MyBatis中,核心配置文件中的内容的扫描方式是从上到下扫描。
正确答案:对
无解析
19、MyBatis的@Insert注解就是将SQL语句直接写在接口上,使得代码书写更加简单,减少了大量的XML文件的配置。
正确答案:对
无解析
20、MyBatis中,@Param注解的功能是指定SQL语句中的参数,通常用于SQL语句中参数比较多的情况。
正确答案:对
无解析
21、在@Insert注解中,value属性是可选的。
正确答案:错
value属性用于指定要执行的insert语句,是必须指定的
四、填空题
22、MyBatis中,@One注解的作用等同于XML配置文件中的_________元素。
<assocation>
23、MyBatis中,_________注解的作用是完成实体类中一个属性和数据表中一个字段的映射。
@Result
24、_________注解用于映射删除语句,其作用等同于XML配置文件中的<delete>元素。
@Delete
25、可以用于结果集映射的三大注解有@ResultMap、@Results和_________。
@Result
26、MyBatis中使用_________注解可以实现数据表的一对一关联查询。
@One
27、MyBatis使用_________注解实现数据表的一对多关联查询,它作用等同于XML配置文件中的<collection>元素。
@Many
28、MyBatis中,_________注解用于映射插入语句,其作用等同于XML配置文件中的<insert>元素。
@Insert
29、在@Many注解中,用于指定关联属性的值的属性是_________。
select
30、在@Result注解中,_________属性用来指定关联属性。
property
如有错误,欢迎指正!!!
Mybatis注解开发
一:引言
通过前面的几篇文章的学习,到这里已经学习了差不多了,离成功也很快了,但还有Mybatis的注解开发要学习,因为学习注解开发,你就会发现原来Mybatis是这么牛逼呀,可以说使用注解开发会对你的开发起到了很大的时间缩减,接下来就由我给大家带来mybatis注解开发的一系列操作吧!
准备工作【搭建简单注解框架】
二:Mybatis注解开发之单表CRUD操作
因为单表的CRUD操作比较简单,我就直接上代码了,再加上一点注释
1:查询一系列操作
①:查询全部
######StudentDao代码 //查询全部学生数据 @Select("select sid id,sname name,ssex sex,scredit credit,smoney " + "money,saddress address,senrol enrol, fid,tid from student") List<Student> findAll(); ######测试类 //查询全部学生 @Test public void findAllStudent() { StudentDao mapper = sqlSession.getMapper(StudentDao.class); List<Student> students = mapper.findAll(); for (Student student : students) { System.out.println(student); } } //可以看出这种使用别名的效果极差,如果字段多的话就会崩溃 //在这个例子中展现出我的sql语句都是使用别名,要不然和类属性名和数据库字段名对不上, //所以我先用别名来解决这个问题,但是它肯定有简单的解决方法,再第三节我将为大家介绍注解映射关系
②:根据主键查询单个学生
#####StudentDao接口代码 后面会介绍映射 //查询单个 根据主键id @Select("select * from student where sid=#{id}") @Results(value={ @Result(id=true,column = "sid",property = "id"), @Result(column = "sname",property = "name"), @Result(column = "ssex",property = "sex"), @Result(column = "sage",property = "age"), @Result(column = "scredit",property = "credit"), @Result(column = "smoney",property = "money"), @Result(column = "saddress",property = "address"), @Result(column = "senrol",property = "enrol"), @Result(column = "tid",property = "tid"), @Result(column = "fid",property = "fid") }) Student findById(Integer id); #####测试类 //查询单个学生 @Test public void findById(){ StudentDao mapper = sqlSession.getMapper(StudentDao.class); Student student = mapper.findById(5); System.out.println(student); }
③:模糊查询
#####StudentDao接口代码 //模糊查询 按照姓名 ResultMap是引用之前的映射 @Select("select * from student where sname like #{name}") @ResultMap(value="studentMapper") List<Student> findLikeName(String name); #####测试类 //模糊查询 按照学生姓名 @Test public void findLikeNameStudent(){ StudentDao mapper = sqlSession.getMapper(StudentDao.class); List<Student> students = mapper.findLikeName("%张%"); for (Student student : students) { System.out.println(student); } }
注:模糊查询和之前配置文件的写法一样,也是有3种不同的写法,而我在这使用了占位符的方式
④:查询总记录数
#####StudentDao接口代码 //查询total总数 @Select("select count(sid) from student") Integer total(); #####测试 //查询学生总数 @Test public void totalStudent(){ StudentDao mapper = sqlSession.getMapper(StudentDao.class); Integer total = mapper.total(); System.out.println("总共学生:"+total); }
2:添加操作
#####dao代码 //添加学生 @Insert("insert into student(sname,ssex,sage,scredit,smoney,saddress,senrol,fid,tid)" + " values (#{name},#{sex},#{age},#{credit},#{money},#{address},#{enrol},null,#{tid})") void add(Student student); //注:因为学生表中有一个一对一的字段外键fid指向家庭信息表,所以我之 //前在设计表的时候对学生表和家庭信息表的外键做了约束,删除制空,更改级联,所以我给家庭信息表设置了null ######测试 //添加学生 @Test public void insertStudent(){ Student student=new Student(0,"蚂蚁小哥","男",16,55,688.5,"安徽六安","2018-9-9",0,2); StudentDao mapper = sqlSession.getMapper(StudentDao.class); mapper.add(student); sqlSession.commit(); }
3:更改操作
#########dao接口 //更新学生姓名 地址 @Update("update student set sname=#{name},saddress=#{address} where sid=#{id}") void update(Student student); ######测试类 //更新学生 @Test public void updateStudent(){ Student student=new Student(); student.setName("小老虎"); student.setId(2); student.setAddress("北京顺义"); StudentDao mapper = sqlSession.getMapper(StudentDao.class); mapper.update(student); sqlSession.commit(); }
4:删除操作
#####dao方法 //删除学生 @Delete("delete from student where sid=#{id}") void delete(Integer id); ########测试类 //注:这里说明一下,删除的时候,因为我表设置一对一关系,所以删除的时候, //必须删除fid字段(连接家庭信息表)为空值的,就是后来添加的没用值 //删除学生 @Test public void deleteStudent(){ StudentDao mapper = sqlSession.getMapper(StudentDao.class); mapper.delete(66); sqlSession.commit(); }
三:Mybatis注解配置映射关系
众所周知,在Mybatis的xml编写中遇到数据库字段名和实体类属性名不一样怎么解决呢?最简单的方法就是写sql里面别名咯,这是最简单的,但是还有一种就是配置映射关系,使用resultMap标签来配置映射关系,好了,那注解开发怎么来配置呢?很简单,接下来就和我一起来看看吧!
#首先呢在xml里面是标签,而在注解里面是@xxx什么的,所以@Results注解诞生了 @Select("select * from student where sid=#{id}") @Results() Student findById(Integer id); #那里面可以放什么呢?怎么设置配置注解呢? 点进去@Results注解可以看到当前注解是接口里面有2个方法 //存放id的,用来标识唯一的配置信息,供其它的方法使用,不用来回配置了 String id() default ""; //存放映射关系的数组 Result[] value() default {}; #所以就改造成了这样,但是value里面怎么放呢? @Results(id="studentMapper",value={}) #继续改造 #Result就是配置每个关系的映射情况 点进去Result会发现好多接口方法 // 用来配置当前字段是不是表的主键 // boolean id() default false; // 配置数据库字段名称 // String column() default ""; // 配置实体类属性 // String property() default ""; // java类型 说明当前实体类的属性类型 // Class<?> javaType() default void.class; // jdbc类型就是,当前的数据库字段类型 // JdbcType jdbcType() default JdbcType.UNDEFINED; // 我们在前面讨论过默认的类型处理器。使用这个属性, // 你可以覆盖默认的类型处理器。这个属性值是类的完全 // 限定名或者是一个类型处理器的实现,或者是类型别名 // Class<? extends TypeHandler> typeHandler() default UnknownTypeHandler.class; // 配置一对一关系 // One one() default @One; // 配置一对多关系 // Many many() default @Many; @Results(id="studentMapper",value={ @Result(id=true,column = "sid",property = "id"), @Result(column = "sname",property = "name") }) # 最终改造 @Select("select * from student where sid=#{id}") @Results(id="studentMapper",value={ @Result(id=true,column = "sid",property = "id"), @Result(column = "sname",property = "name"), @Result(column = "ssex",property = "sex"), @Result(column = "sage",property = "age"), @Result(column = "scredit",property = "credit"), @Result(column = "smoney",property = "money"), @Result(column = "saddress",property = "address"), @Result(column = "senrol",property = "enrol"), @Result(column = "tid",property = "tid"), @Result(column = "fid",property = "fid") }) Student findById(Integer id); # 后期有要用这个注解的怎么办呢?
# 因为ResultMap注解里面就一个属性方法可以不写value
# @ResultMap{{"studentMapper"}}
# 因为就一个值 所以花括号也可以省
# @ResultMap{"studentMapper"} //模糊查询 按照姓名 @Select("select * from student where sname like #{name}") @ResultMap(value={"studentMapper"}) List<Student> findLikeName(String name);
四:Mybatis注解之一对一查询
Mybatis注解一对一查询就好像和使用xml的关联嵌套查询一样,都是调用别的方法直接查询,下面就带大家改造一下代码吧!
##### StudentDao接口 //因为Student里面不包含family对象,所以定义了POJO对象 //定义一个查询全部的方法,把数据封装到POJO对象里面 //这里进行一个学生对应一个家庭信息数据的一对一操作 //one代表一对一或者多对一操作使用的关联关系 //one里面的select代表引用别处的查询家庭信息根据id //one里面的fetchType代表加载时机 因为是一对一我就使用了立即加载 @Select("select * from student") @Results(id="studentMapper2",value={ @Result(id=true,column = "sid",property = "id"), @Result(column = "sname",property = "name"), @Result(column = "ssex",property = "sex"), @Result(column = "sage",property = "age"), @Result(column = "scredit",property = "credit"), @Result(column = "smoney",property = "money"), @Result(column = "saddress",property = "address"), @Result(column = "senrol",property = "enrol"), @Result(column = "fid" ,property = "family",one=@One(select = "cn.xw.dao.FamilyDao.findById",fetchType = FetchType.EAGER)) }) List<Stu_Tea_Fam> findAllToStu_Tea_Fam(); ##### FamilyDao接口 可以让上面的方法关联下面的查询方法 //查询单个家庭信息 @Select("select * from family where fid=#{id}") @Results(id = "familyMapper", value = { @Result(id = true, column = "fid", property = "id"), @Result(column = "fmember", property = "member"), @Result(column = "fguardian", property = "guardian"), @Result(column = "ftel", property = "tel"), @Result(column = "fdad", property = "dad"), @Result(column = "fmom", property = "mom"), @Result(column = "faddress", property = "address") }) Family findById(Integer id); #####测试类 //查询单个家庭信息 @Test public void findByIdFamily() { FamilyDao mapper = sqlSession.getMapper(FamilyDao.class); Family family = mapper.findById(5); System.out.println(family); } //查询全部学生封装到POJO对象 主要是这个方法测试一对一的存在 @Test public void findAllToStu_Tea_Fam() { StudentDao mapper = sqlSession.getMapper(StudentDao.class); List<Stu_Tea_Fam> students = mapper.findAllToStu_Tea_Fam(); for (Stu_Tea_Fam student : students) { System.out.println(student); } }
五:Mybatis注解之一对多查询
注解一对多查询和xml的的集合关联查询差不多,都是在主表中调用查询副表的查询单个方法来封装到POJO对象
##### TeacherDao接口 //查询全部辅导员,一对多 一个辅导员有多个学生 //所以在主表中直接查询辅导员全部信息, //然后去调用副表的查询,把数据查询后封装 //many是一对多 或者 多对多的查询 //select是调用student //Dao里面的根据tid外键查询多个 //fetchType 因为是一对多 推荐使用延迟加载 LAZY @Select("select * from teacher") @Results(id="studentMapper" , value={ @Result(id=true,column = "tid",property = "id"), @Result(column = "tname",property = "name"), @Result(column = "tsex",property = "sex"), @Result(column = "tage",property = "age"), @Result(column = "tsalary",property = "salary"), @Result(column = "taddress",property = "address"), @Result(column = "tid",property = "students",many = @Many(select = "cn.xw.dao.StudentDao.findByTid",fetchType = FetchType.LAZY)) }) List<Tea_Stu> findAllToTea_Stu(); ##### StudentDao接口 //查询单个 根据外键id ,这里使用了ResultMap 代表它引用别的映射关系 @Select("select * from student where tid=#{id}") @Results(id="studentMapper3",value={ @Result(id=true,column = "sid",property = "id"), @Result(column = "sname",property = "name"), @Result(column = "ssex",property = "sex"), @Result(column = "sage",property = "age"), @Result(column = "scredit",property = "credit"), @Result(column = "smoney",property = "money"), @Result(column = "saddress",property = "address"), @Result(column = "senrol",property = "enrol"), @Result(column = "tid",property = "tid"), @Result(column = "fid",property = "fid") }) List<Student> findByTid(Integer id); ##### 测试方法 //查询全部辅导员及学生 @Test public void findAllToTea_Stu(){ TeacherDao mapper = sqlSession.getMapper(TeacherDao.class); List<Tea_Stu> teachers = mapper.findAllToTea_Stu(); for(Tea_Stu teacher:teachers){ System.out.println(teacher); } }
六:Mybatis之缓存机制
1:一级缓存
在上一篇文章也说过,Mybatis的一级缓存存在于SqlSession域的,它模式是开启状态,争夺以上我来演示一下
######更改一下StudentDao接口的方法 设置映射关系 //查询单个 根据主键id 对映射关系我引用其它已经配置好的 @Select("select * from student where sid=#{id}") @ResultMap("studentMapper") Student findById(Integer id);
#####编写测试类 //查询单个学生 @Test public void findById() { //创建第一个SqlSession下的代理对象 StudentDao mapper1 = sqlSession.getMapper(StudentDao.class); Student student1 = mapper1.findById(5); System.out.println("打印Student1的hashCode:"+student1.hashCode()); //创建第二个SqlSession下的代理对象 StudentDao mapper2 = sqlSession.getMapper(StudentDao.class); Student student2 = mapper2.findById(5); System.out.println("打印Student2的hashCode:"+student2.hashCode()); System.out.println("看看2个对象是否一样"); System.out.println(student1==student2); }
但是要怎么要清除缓存呢?其实和之前的一篇文章一样,遇到增删改、commit、clearCache、close等都会使缓存消失
//查询单个学生 @Test public void findById() { //创建第一个SqlSession下的代理对象 StudentDao mapper1 = sqlSession.getMapper(StudentDao.class); Student student1 = mapper1.findById(5); System.out.println("打印Student1的hashCode:"+student1.hashCode()); //加上清除缓存方法 sqlSession.clearCache(); //创建第二个SqlSession下的代理对象 StudentDao mapper2 = sqlSession.getMapper(StudentDao.class); Student student2 = mapper2.findById(5); System.out.println("打印Student2的hashCode:"+student2.hashCode()); System.out.println("看看2个对象是否一样"); System.out.println(student1==student2); }
2:二级缓存
二级缓存其实默认为关闭的,要我们手动开启,这一点和xml配置做法一样,都要去SqlMapConfig.xml里面设置settings标签,唯一区别就是xml文件里配置cache标签,而注解要配置@CacheNamespace(blockint=true),接下来我就和大家来解释一下吧!
#####第一步大家先配置一下SqlMapConfig.xml里面的settings标签 <!--配置settings 记住一定要在Properties标签下面--> <settings> <setting name="cacheEnabled" value="true"/> </settings> #####第二步在实体类要实现序列化 public class Student implements Serializable { .......... } #####第三步在要实现二级缓存的接口上开启二级缓存的注解 @CacheNamespace(blocking = true) public interface StudentDao { .......... }
###StudentDao接口方法 //查询单个 根据主键id @Select("select * from student where sid=#{id}") @ResultMap("studentMapper") Student findById(Integer id); #####测试类 //查询单个学生 @Test public void findById() { //因为测试方法结束后要关闭sqlSession对象,因为没有我创建一个 sqlSession=factory.openSession(); //创建第一个SqlSession对象 SqlSession sqlSessionA = factory.openSession(); StudentDao mapperA = sqlSessionA.getMapper(StudentDao.class); Student studentA = mapperA.findById(5); System.out.println("打印studentA的hashCode:"+studentA.hashCode()); sqlSessionA.close(); //创建第二个SqlSession对象 SqlSession sqlSessionB = factory.openSession(); StudentDao mapperB = sqlSessionB.getMapper(StudentDao.class); Student studentB = mapperB.findById(5); System.out.println("打印studentB的hashCode:"+studentB.hashCode()); sqlSessionA.close(); System.out.println("打印2者是否一样"); System.out.println(studentA==studentB);
//false是因为SqlSessionFactory域对象存储的是散装数据,具体前面一篇文章有详细介绍 }
七:总结
我在这几天中对Mybatis进行了一番讲解,从简单的入门到配置文件xml开发的CRUD操作以及单表多表的操作,但是这只是对Mybatis的基本操作;后面我又介绍了关于Mybatis的连接池技术以及源码的分析、加载机制和缓存机制,这才算的上对mybatis的一点点认识,但是今天我讲到了Mybatis的注解开发,其实呢注解开发固然好用,但是发现了吗?如果CRUD的方法特别多,都写注解sql,会发现它们的耦合关系太大,也难以看懂,所以具体看项目要求,我一般是单表操作的话注解开发可以推荐,但是呢,如果方法多,逻辑特别多,而且涉及到3表操作4表操作....我还是建议用xml开发
说到这也结束了,后期我会慢慢的给大家带来mybatis的源码分析文章,谢谢大家,而且我能力有限,也是个小白,所以就没有讲的太深入,请大家理解
以上是关于MyBatis注解开发相关习题的主要内容,如果未能解决你的问题,请参考以下文章