MyBatis接口代理方式实现Dao层
规则:
1.映射配置文件中的 名称空间 必须和Dao层接口的全类名相同
2.映射配置文件中的 增删改查标签的id属性 必须和Dao层接口的方法名相同
3.映射配置文件中的 增删改查标签的parameterType属性 必须和Dao层接口方法的参数相同
4.映射配置文件中的 增删改查标签的resultType属性 必须和Dao层接口方法的返回值相同
具体实现
直接把mapperImpl删掉,MyBatis会帮我们搞
1.删除mapper层接口的实现类
2.修改映射配置文件
3.修改service层接口的实现类,采用接口代理方式实现功能
StudentMapper持久层、不再需要他的Impl实现类了
StudentMapper.xml
满足规则1 1.映射配置文件中的 名称空间 必须和Dao层接口的全类名相同
StudentServiceImpl业务层:持久层对象Impl已经没有了,所以删除,里面的实现逻辑也要删除改进。变成接口代理的相关功能
改进后的selectAll方法:
public List<Student> selectAll(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取StudentMapper接口的实现类对象
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
该语句等价于-->StudentMapper mapper = new StudentMapperImpl();
只不过这个实现类不是我们自己写的,而是MyBatis帮我们生成
//调用实现类对象中的方法来完成操作,返回拿到的集合对象
List<Student> = mapper.selectAll();
//释放资源
sqlSession.close();
//返回结果
return list;
}
selectById
insert
update
delete
控制层测试持久层能否成功
执行结果:
@Param注解
想查询年龄是24或者名字是张三 的信息
业务层实现类对象
持久层
使用@Params
映射配置文件(为多个参数设置类型)、这里就不用再设置parameterType了,因为我们已经通过@Params来设置了
通过映射文件 实现 动态SQL
sql条件有很多,如果我们要一条一条的实现也太累了,我们通过动态SQL来实现
StudentMapper.xml映射配置文件
StudentMapper.java持久层实现对DB的操作
测试类Test01.java
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml")
如果我在这里将setName注释掉,程序是会报错的,因为这三个参数我必须都要传,才可以成功。如果是这样的话,就相当于限定死了每一条sql语句,那么如何解决呢?
if标签
StudentMapper.xml
<select id = "selectCondition" resultType = "student" parameterType = "student">
//只需要写前面的select
SELECT * FROM student
//where语句被下放的where标签代替了,可以删除了
//WHERE id = #{id} AND name = #{name} AND age = #{age}
//使用where标签代替where关键字
<where>
查询条件,根据id来查询,但是name和age可以作为备选条件查询
<if test = "id!=null">
id = #{id}
</if>
<if test = "name!=null">
AND name = #{name}
</if>
<if test = "age!=null">
AND age = #{age}
</if>
</where>
</select>
Test01.java测试类测试
就算对其中一个备选数据进行注释,我也依然可以根据已知的条件查询出对应的数据。
foreach标签
多个参数 或者的关系 :多个id查询出多个数据
StudentMapper.xml
//多个参数存在集合里
<select id = "selectByIds" resultType="student" parameterType="list">
//查询id是1、2、3的数据
//SELECT * FROM student WHERE id IN(1,2,3)
//使用foreach标签优化 将where后面的语句删除
<where>
开始:从where后,结束:小括号
<foreach collection="list"
open="id IN("
close=")"
item="id"
separator=",">
//获取数据
#{id}
</foreach>
</where>
</select>
接口中的语句:
public abstract List<Studnet>selectByIds(List<Integer> ids)
测试方法:
sql片段抽取
对重复性的SQL语句进行抽取,达到复用的效果。
比如说对:SELECT * FROM student
MyBatis核心配置文件-分页插件
分页就是Sql中的limit限制显示的条数,效果是一样的
分页插件实现步骤
1.导入jar包
2.在核心配置文件中集成分页助手插件
在MyBatisConfig.xml核心配置文件
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
</plugin>
</plugins>
3.在测试类中使用分页助手相关API实现分页功能
public void selectPaging() throws Exception{
InputStream is = Resources.getResourceAsStream("MyBatisConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
//把8条数据分成3页来实现,通过分页助手实现
PageHelper.startPage(1,3); //第1页-显示3条
PageHelper.startPage(2,3); //第2页-显示3条
List<Student> list = mapper.selectAll();
for(Student student : list){
System.out.println(student)
}
----------------------在这里获取分页参数------------------
sqlSession.close();
is.close();
分页插件相关参数的了解
PageInfo:封装分页相关参数的功能类
//获取分页参数,位置在上面的地方
PageInfo<Student> info = new PageInfo<>(list);
总条数:info.getTotal();
总页数:info.getPages();
当前页:info.getPageNum();
每页显示条数:info.getPageSize();
上一页:info.getPrePage();
下一页:info.getNextPage();
是否是第一页:info.isIsFirstPage();
是否是最后一页:info.isIsLastPage();
总结:
多表操作
一对一的多表操作
1.新建数据库表:Card和Person.class,里面初始化
2.在核心配置文件中:导入映射配置文件
3.书写映射配置文件的接口OneToOneMapper.java
public interface OneToOneMapper{
public abstract List<Card> selectAll();
}
4.设置他们俩的映射配置文件OneToOneMapper.xml
<mapper namespace="接口所在的全路径">
//用来配置字段和实体对象属性的映射关系,给实体对象card配置映射关系
<resultMap id = "oneToone" type="card">
//column:给表中哪个字段进行封装?
//property:给card实例类中的id赋值
主键用id标签
<id column="cid" property="id"/>
其他字段用result标签
<result column="number" property="number"/>
//配置给被包含对象的映射关系(就是person表的字段)
//property被包含对象的变量名Person p
//javaType被包含对象的数据类型
<association property="p" javaType="person">
<id column="pid" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
</association>
</resultMap>
<select id = "selectAll" resultMap="oneToone">
//显示card表中的id 并且 取别名叫 cid,来自card表 取别名后的c表
SELECT c.id cid,number,pid,name,age from card c,person p where c.pid = p.id
</select>
</mapper>
5.测试类
结果:
小结:
一对多
实体类
Student
classes
映射配置文件OneToManyMapper.xml
<mapper namespace = "接口全类名">
//唯一标识,给哪一个实体对象进行映射关系
<resultMap id = "oneToMany" type = "classes">
//表中的主键名,classes.id赋值
<id colum = "cid" property = "id" />
//字段名,classes.name赋值
<result column = "cname" property = "name"/>
//学生表中的数据要单独写,collection是一对多的标签
//被包含对象的变量名,ofType:实际类型
<collection property="students" ofType="student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<result column="sage" property="age"/>
</collection>
</resultMap>
//唯一标识,要和上方的resultMap名对应
<select id ="selectAll" resultMap="oneToMany">
SELECT c.id cid,c.name cname,s.id sid,s.name sname
s.age sage FROM classes c,student s where
c.id=s.id
</mapper>
核心配置文件MyBatisConfig.xml(引入映射配置文件)
接口
测试类Test
结果: