MyBatis入门
MyBatis是一个ORM的数据库持久化框架。相比于Hibernate,Mybatis的性能更佳,因为由开发者直接操作sql语句。但是开发效率会相对较差一些。
核心对象
SqlSessionFactoryBuilder:该对象用于SqlSessionFactory的创建,一旦创建了SqlSessionFactory,这个类就不需要再使用了 。
SqlSessionFactory:一个重量级对象,一般情况下 ,一个项目只需要一个SqlSessionFactory对象。由于是重量级对象所以该对象是线程安全的,不能轻易创建和销毁。
SqlSession:轻量级对象,每个线程都应该有它自己的 SqlSession 实例。 SqlSession 的实例不能被共享,也是线程不安全的。因此最佳的范围是请求或方法范围。每次使用完该对象都应该进行关闭(在finally代码块中执行)。
入门配置
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
//数据库的配置
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--mappers 元素是包含所有mapper (映射器)的列表,这些 mapper的XML文件包含SQL代码和映射定义信息-->
<mappers>
<mapper resource="cn/itsource/mybatis/domain/ProductMapper.xml"/>
<mapper resource="cn/itsource/mybatis/domain/UserMapper.xml"/>
</mappers>
配置文件通过mappers属性中的mapper映射到想要pojos到数据表的mapping。
<?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">
<!--namespace:命名空间;要求:一个项目中命名空间必须唯一;一般:domain的路径来唯一
domain的全路径Mapper-->
<mapper namespace="cn.itsource.mybatis.domain.ProductMapper">
<select id="queryOne" parameterType="Long" resultType="Product">
select * from product where id = #{id}
</select>
需要传入的参数用#{}表示占位,与jdbc使用preparedStatement的最终向数据库发送的sql是一摸一样的。
配置好mybatis和想要进行crud的xml文件后。就可以进行crud操作
@org.junit.Test
public void testQuery()throws Exception{
//通过读取配置文件,进行SqlSessionFactory的创建
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
//获得sqlSession,该对象根据namespace+要执行的操作的id(默认为方法名)找到sql语句,并执行
SqlSession sqlSession = sqlSessionFactory.openSession();
Product one = (Product)sqlSession.selectOne("cn.itsource.mybatis.domain.ProductMapper.queryOne", 1L);
System.out.println(one);
//关闭
sqlSession.close();
}
#{}和${}的区别
前者使用占位符进行占位,后者是拼接sql语句,可能会发送sql语句注入的情况 ,如以下demo
根据User配置的mapper
<mapper namespace="cn.itsource.mybatis.domain.UserMapper">
<select id="queryOne" parameterType="User" resultType="User">
select * from user where name=${name} and pwd=${pwd}
</select>
</mapper>
dao层的impl类
public class IUserDaoImpl implements IUserDao {
@Override
public User queryOne(User user) throws Exception {
SqlSession sqlSession = null;
try {
//该工具类用于拿到sqlSession对象
sqlSession = MyBatisUtil.getSqlSession();
return sqlSession.selectOne("cn.itsource.mybatis.domain.UserMapper.queryOne", user);
} finally {
sqlSession.close();
}
}
}
测试代码
@org.junit.Test
public void test$()throws Exception{
User user = new User();
user.setName("\"admin\" or \"1=1\"");
user.setPwd("\"admin\"");
IUserDao userDao = new IUserDaoImpl();
userDao.queryOne(user);
}
}
执行结果如下: