2018/4/23 17:20 Monday
Mybatis通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。
今天记录一下原始的Dao开发方法
1.1 SqlSession使用范围
是一个面向程序员的接口.
SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回多个对象)..
SqlSession是线程不安全的.在Sqlsession实现类中除了有接口的方法(操作数据库的方法)还有数据域属性.
SqlSession的最佳应用场合市在方法体内.在多个线程去访问这一个对象,每个线程对于同一个方法,都在不同的内存区域内运行,所以把SqlSession定义为局部变量使用
1.2 SqlSessionFactoryBuilder
将SqlSessionFactory当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder.
在需要创建SqlSessionFactory的时候.SqlSessionFactory只需要new一次.
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
1.3 SqlSessionFactory
通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例)
以后和spring整合后,就使用的市单例模式管理的SqlSessionFactory
2.思路:
程序员需要写DAO接口和DAO实现类
需要向DAO实现类中注入SqlSessionFactory,并在方法体内创建SqlSession
2.1 创建CategoryDao.java接口
package com.kh.DaoImp;
import com.kh.pojo.Category;
/*
* Title:CategoryDao
* Description:DAO接口
* Date:2018-4-23 17:41
*/
public interface CategoryDao {
//根据id查询
public Category FindById(int id) throws Exception;
//添加
public Category InsertCategory(Category cg) throws Exception;
//根据id删除
public void DeleteById(int id) throws Exception;
}
2.2创建了CategoryDao.java接口然后就是创建它的实现类: CategoryImp.java
package com.kh.DaoImp;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.kh.pojo.Category;
/*
* Title:CategoryDao
* Description:DAO接口实现类
* Date:2018-4-23 17:41
*/
public class CategoryImp implements CategoryDao{
//需要想DAO实现类中注入SqlSessionFactory
//通过构造方法来注入
private SqlSessionFactory sqlSessionFactory;
public CategoryImp(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory=sqlSessionFactory;
}
//----------------------分隔符----------------------------------------
@Override
public Category FindById(int id) throws Exception {
//创建SqlSession对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//查询操作
Category cg=sqlSession.selectOne("FindById", id);
//释放资源
sqlSession.close();
return cg;
}
//----------------------分隔符----------------------------------------
@Override
public Category InsertCategory(Category cg) throws Exception {
//创建SqlSession对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//执行插入
sqlSession.insert("InsertCategory", cg);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
return cg;
}
//----------------------分隔符----------------------------------------
@Override
public void DeleteById(int id) throws Exception {
//创建SqlSession对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//执行删除
sqlSession.delete("DeleteById", id);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
3. 测试这些接口
package com.kh.DaoImpTest;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import com.kh.DaoImp.CategoryDao;
import com.kh.DaoImp.CategoryImp;
import com.kh.pojo.Category;
public class CategoryImpTest {
private SqlSessionFactory sqlSessionFactory;
public void setUp() throws Exception {//这个方法是为了获得SqlSessionFactory(会话工厂)
//创建SqlSessionFactory
//mybatis配置文件
String resource="mybatis-config.xml";
//得到配置文件流
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
//------------------------分隔符------------------------------------------
public void testFindById() throws Exception {
//创建一个CategoryDao对象
CategoryDao cgdao=new CategoryImp(sqlSessionFactory);
//Category对象调用CategoryDao方法
Category cg=cgdao.FindById(1);
System.out.println(cg);
}
public static void main(String[] args) throws Exception {
CategoryImpTest test=new CategoryImpTest();
test.setUp();//获得SqlSessionFactory(会话工厂)
test.testFindById();
}
}
这里只测试了一个查询操作.
4.这里总结一下这种开发的问题:
1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。
2、调用sqlsession方法时将statement的id硬编码了
3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。
比如这段代码:
public void DeleteById(int id) throws Exception {
//创建SqlSession对象
SqlSession sqlSession=sqlSessionFactory.openSession();
//执行删除
sqlSession.delete("DeleteById", id);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
sqlSession.detele("DeteleById",id);写成
sqlSession.detele("DeteleById",new Date());但是编译器不会报错
因为它第二个参数是泛型.