前言
在Mybatis的使用中,对于数据库的操作,我们针对每一张表创建一个对应的接口和sql映射文件。
注意到上述两篇中并没有在代码中直接使用我们的dao接口,下面将会介绍dao接口的两种用法。
提示:以下是本篇文章正文内容,下面案例可供参考
一、传统的dao使用
1、回顾一下接口
在java编程语言中,接口是一个抽象类型,是所有抽象方法的一个集合。接口不能被继承,只能被实现,而实现它的这个类必须实现它里面的所有方法,否则该类必须声明为抽象类。
2、创建一个接口
public Interface Animal{
//抽象方法
public void eat();
public void travel();
}
3、实现接口并使用
public class Cat implements Animal{
public void eat(){
System.out.println("Mammal eats");
}
public void travel(){
System.out.println("Mammal travels");
}
}
public class TestInterface{
public static void main(String args[]){
MammalInt m = new MammalInt();
m.eat();
m.travel();
}
}
二、Mybatis中传统dao的使用
1.创建dao的实现类
代码如下(示例)
/**
* studentDao的实现类
* */
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> selectStudent() {
//1、获取SqlSession
SqlSession sqlSession = Myutils.getSqlSession();
//2、创建sql
String sqlId = "com.bjnode.dao.StudentDao"+"."+"selectStudent";
//3、执行sql
List<Student> students =sqlSession.selectList(sqlId);
//4、关闭
sqlSession.close();
//5、返回结果
return students;
}
@Override
public int insertStudent(Student student) {
//1、获取SqlSession
SqlSession sqlSession = Myutils.getSqlSession();
//2、创建sql
String sqlId = "com.bjnode.dao.StudentDao"+"."+"insertStudent";
//3、执行sql
int num =sqlSession.insert(sqlId,student);
//4、手动提交事务
sqlSession.commit();
//5、关闭
sqlSession.close();
//6、返回结果
return num;
}
}
2.Junit单元测试:直接创建Dao实现类调用数据库操作方法
代码如下(示例):
public class MybatisTest01 {
@Test
public void testSelectStudent() {
//1、创建实现类
StudentDao so = new StudentDaoImpl();
//2、调用子类查询方法
List<Student> students =so.selectStudent();
//3、输出结果
for (Student student:students){
System.out.println(student);
}
}
@Test
public void testInsertStudent(){
//1、创建实现类
StudentDao so = new StudentDaoImpl();
//2、插入
Student student = new Student();
student.setAge(21);
student.setId(2006);
student.setName("hye");
student.setEmail("hye@163.com");
int num = so.insertStudent(student);
//3、结果
System.out.println(((num)!=-1)?"添加成功":"添加失败");
}
}
三、Mybatis中动态代理dao
1、既然说到了代理,那么这里介绍一下动态代理这种设计模式
1)代理模式能够解决什么问题?
在面向对象系统中,有些对象由于某些原因(比如对象创建开销很大,某些操作需要安全控制,需要进程外的访问),直接访问会给使用者或者系统结构带来很多麻烦,我们可以在访问此对象时加上一个对此对象的访问层。
举个例子:当你漂亮的女朋友想和奶茶的时候,现在我们需要的对象就是奶茶,那么怎么获得呢?一、自己准备制作奶茶的各种材料,自己制作;二,奶茶店卖,价格美丽,东西美丽。在这个过程中,我们其实真正关心的只有最好拿到这杯奶茶,但是第一种方法相比于第二种方法显然非常复杂很麻烦,于是我们找到代理的对象也就是奶茶店,最后获得一杯满意的奶茶。
2、代理模式示例
1)创建代理对象与被代理对象的共同接口(Image),使他们具有相同的行为
public interface Image {
void display();
}
2) 创建实现接口的被代理对象(RealImage)
public class RealImage implements Image {
//属性私有化
private String fileName;
//重载构造方法
public RealImage(String fileName){
this.fileName = fileName;
loadFromDisk(fileName);
}
//被代理的行为
@Override
public void display() {
System.out.println("Displaying " + fileName);
}
//方法私有化
private void loadFromDisk(String fileName){
System.out.println("Loading " + fileName);
}
}
3)创建实现接口的代理对象类(ProxyImage)
public class ProxyImage implements Image{
// 属性私有化
private RealImage realImage;
private String fileName;
public ProxyImage(String fileName){
this.fileName = fileName;
}
@Override
public void display() {
//被代理对象为空,新建
if(realImage == null){
realImage = new RealImage(fileName);
}
//不空,直接调用
realImage.display();
}
}
4)当被请求时,使用 ProxyImage 来获取 RealImage 类的对象
public class ProxyPatternDemo {
public static void main(String[] args) {
Image image = new ProxyImage("test_10mb.jpg");
// 图像将从磁盘加载
image.display();
System.out.println("");
// 图像不需要从磁盘加载
image.display();
}
}
3、Mybatis中使用代理模式的条件分析
在传统的dao的使用方法中,dao的实现类中两个不同方法代码块中重复代码比较多,而不一样的的地方集中在sql语句:
// 查询方法
String sqlId = "com.bjnode.dao.StudentDao"+"."+"selectStudent";
// 插入方法
String sqlId = "com.bjnode.dao.StudentDao"+"."+"insertStudent";
观察发现,一样的部分就是sql映射文件中namespace和id:
<mapper namespace="com.bjnode.dao.StudentDao">
<select id="selectStudent" resultType="com.bjnode.domain.Student">
select * from Student
</select>
<insert id="insertStudent" >
insert into Student values(#{id},#{name},#{email},#{age})
</insert>
</mapper>
于是,mybatis就利用动态代理的思想,根据获取的字符串就可以创建dao的实现类,完成sqlSession创建以及数据库的访问。
4、Mybatis中动态代理的使用
动态代理的核心就是sqlSession的getMapper()方法,此时不需要我们手动创建实现类,代码如下:
@Test
public void testSelectStudent() {
//1、获取sqlSession
SqlSession sqlSession = Myutils.getSqlSession();
//2、调用getMapper创建子类
StudentDao dao = sqlSession.getMapper(StudentDao.class);
//3、调用接口的查询方法
List<Student> students =dao.selectStudent();
//3、输出结果
for (Student student:students){
System.out.println(student);
}
}
总结
本文为学习过程中记录,如有表述不当或者错误之处请在评论区指出,共同讨论!