首先,我们应该先了解一下接口与类:
接口与类
SqlSessionFactoryBuilder类,用来创建SqlSessionFactory接口的类,其中在这个SqlSessionFactoryBuilder类中,重载 了许多的builder方法。他会根据我们传入的流创建一个XMLConfigBuilder类,然后会调用parse()方法,返回一个Configuration对象,最后我们通过DefaultSqlSessionFactory(config),将我们的Configuration进行解析,返回我们最终需要的SqlSessionFactory。【点进去源码进行观察】。
通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。
SqlSessionFactory接口:SqlSessionFactory是一个接口,其具体实现类是DefaultSqlSessionFactory,通过类名我们可以看到SqlSessionFactory是一个SqlSession工厂,用来生产SqlSession对象,SqlSession中有我们进行数据库操作的增删改查接口。通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。
SqlSession接口:SqlSession是一个接口其具体实现类为DefaultSqlSession,SqlSession接口主要定义了一些增删改查方法,DefaultSQLSession是对SqlSession接口的具体实现,SqlSession是一个面向用户(程序员)的接口。SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。
SqlSession最佳应用场合在方法体内,定义成局部变量使用。
MyBatis 原始开发DAO步骤:
1、编写DAO接口
2、编写DAO实现
// 1、编写DAO接口
public interface UserDao {
public User seleteById(int id);
public List<User> selectByName(String name);
public void insertUser(User user);
public void deleteUserById(int id);
public void updateuserwithid(User user);
}
// 2、编写DAO实现
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlsessionfactory;
public UserDaoImpl(SqlSessionFactory sqlsessionfactory) {
this.sqlsessionfactory = sqlsessionfactory;
}
@Override
public User seleteById(int id) {
SqlSession session = sqlsessionfactory.openSession();
User user = session.selectOne("user.selectById", id);
session.close();
return user;
}
@Override
public List<User> selectByName(String name) {
SqlSession session = sqlsessionfactory.openSession();
List<User> users = session.selectList("user.selectByName", name);
session.close();
return users;
}
}
3、单元测试
public class UserTest {
private SqlSessionFactory sqlsessionfactory;
private UserDao userdao;
@Before
public void testbefore(){
try {
InputStream input = Resources.getResourceAsStream("mybatis.xml");
sqlsessionfactory = new SqlSessionFactoryBuilder().build(input);
userdao = new UserDaoImpl(sqlsessionfactory);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void testSeleteById() {
User user = userdao.seleteById(1);
System.out.println(user.getUsername());
}
@Test
public void testSelectByName() {
List<User> users = userdao.selectByName("张三");
for(User user: users){
System.out.println(user.getUsername());
}
}
说明:
1、此时我们的配置文件的mapper中的namespace仍然没有规则,是我们随意命名的。
2、对于接口中的方法名,此时也是和我们的配置文件中的id名称没有一一对应,没有规则的。
3、对于接口的实现类中,我们要设置属性 SqlSessionFactory ,这是因为SqlSessionFactory 是可以共用的,而且,在于我们的Spring整合之后,其可以设计问单例模式。
4、对于SqlSession 则是声明定义在我们的方法中。
5、在利用单元测试时,我们理由注解@Before 进行我们的加载配置文件,生成sqlsessionfactory ,然后在初始化我们的DAO接口实现时,将我们的sqlsessionfactory 参数传递到方法中。
MyBatis Mapper代理开发DAO步骤:
利用Mapper代理开发DAO,就是通过一些规范,将我们的DAO接口和我们的Mapper配置文件通过一定的关联建立起联系。
利用Mapper代理开发DAO,可以省去我们写DAO实现的代码,但是在省力的同时,我们也必须遵循MyBatis给我们提供的Mapper代理开发规范,这样的话,我们的MyBatis就可以自动生成mapper接口实现类代理对象:
1、 在mapper.xml中namespace等于mapper接口地址,这里我们的namespace就有了严格的定义:必须为我们的接口的类的全路径。
2、在我们的 mapper.java接口中的方法名和mapper.xml中statement的id必须严格保持一致。
3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
注意:
1、接口参数只能是一个,因为在配置文件中只能存在一个parameterType。
2、对于select返回单个对象或者是List集合时,是根据接口的返回值进行调用selectOne和selectList方法的。
步骤:
1、编写DAO接口
2、编写mapper.xml配置文件
// mapper接口 编写
public interface UserDaoMapper {
public User selectById(int id);
public List<User> selectByName(String name);
public void insertUser(User user);
public void deleteUserWithID(int id);
public void updateUserWithID(User user);
}
// 配置文件 编写
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wf.dao.UserDaoMapper">
<select id="selectById" parameterType="int" resultType="com.wf.model.User">
select * from User where id = #{id}
</select>
<select id="selectByName" parameterType="java.lang.String" resultType="com.wf.model.User">
select * from User where username like '%${value}%'
</select>
<delete id="deleteUserWithID" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
</mapper>
// 测试代码
public class UserDaoMapperTest {
private SqlSessionFactory sqlsessionfactory;
@Before
public void testBefore() {
InputStream inputStream;
try {
inputStream = Resources.getResourceAsStream("mybatis.xml");
sqlsessionfactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
@Test
public void test() {
SqlSession session = sqlsessionfactory.openSession();
UserDaoMapper userDaoMapper = session.getMapper(UserDaoMapper.class);
User user = userDaoMapper.selectById(1);
System.out.println(user.getUsername());
}
}
说明:
1、 namespace按照规范进行设定为接口类的全路径
2、id属性一定要和方法名保持一致,
3、由于我们利用了代理模式,所以在获取数据库操作时是利用Session的getMapper方法,得到我们的代理对象,然后再利用代理对象去调用接口中的方法,而不是,Session的相关selectOne或者selectList方法。,注意上面的测试代码中的相关方式。
4、mapper接口方法参数只能有一个,所以对于多参传递较为复杂的语句,我们使用的是包装对象进行开发的。