Mybatis使用过程
导入mybatis、驱动包(略)
导入sqlmap-config.xml主配置文件 主要注意数据库连接那一块和加载sql语句定义文件那一块
<configuration>
<environments default="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver"
value="oracle.jdbc.OracleDriver" />
<property name="url"
value="jdbc:oracle:thin:@127.0.0.1:1521:MLDN"/>
<property name="username" value="scott" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/xdl/sql/DeptMapper.xml" />
</mappers>
</configuration>
定义实体类(略)
定义SQL语句
DeptMapper.xml
<!-- namespace指定和哪个Mapper映射器接口对应 -->
<mapper namespace="com.xdl.mapper.DeptMapper">
<select id="findAll" resultType="com.xdl.bean.Dept">
select * from dept
</select>
<insert id="sava" parameterType="com.xdl.bean.Dept">
insert into dept(deptno,dname,loc) values(#{deptno},#{dname},#{loc})
</insert>
</mapper>
定义Mapper接口或自定义Dao(此处是根据sal文件定义的Mapper接口的方式)
package com.xdl.mapper;
import java.util.List;
import com.xdl.bean.Dept;
public interface DeptMapper {
public List<Dept> findAll();
public int save(Dept dept);
}
获取SqlSession对象操作
public class DeptMapperTest {
public static void main(String[] args) throws Exception {
// 构建一个SqlSession 工厂的构建器
SqlSessionFactoryBuilder ssfb = new SqlSessionFactoryBuilder();
// 获取SqlSession 工厂对象
Reader reader = Resources.getResourceAsReader("sqlmap-config.xml");
/*或者通过流对象获取
* InputStream inputStream = DeptMapperTest.class.getClassLoader()
.getResourceAsStream("sqlmap-config.xml");*/
SqlSessionFactory build = ssfb.build(reader);
// 获取sqlSession 对象
SqlSession openSession = build.openSession();
//通过Mapper映射规则生成了接口的实现类
DeptMapper mapper = openSession.getMapper(DeptMapper.class);
List<Dept> list = mapper.findAll();
for (Dept dept : list) {
System.out.println(dept.getDeptno()+" "+dept.getDname());
}
}
}
Spring+MyBatis
Spring整合MyBatis技术:spring-orm工具/mybatis-spring.jar工具。提供了SqlSessionFactoryBean、MapperScanConfigurer、SqlSessionTemplate
1.使用Mapper映射器对象
使用SqlSessionFactoryBean和MapperScanConfigurer。
- 导入spring、mybatis、驱动包、连接池、mybatis-spring
- 添加sqlmap-config.xml、applicationContext.xml
- 根据表定义实体类(没有区别)
- 定义SQL语句文件(没有区别)
- 定义Mapper映射器接口(没有区别)
- 在Spring配置文件中配置DataSource、SqlSessionFactoryBean、MapperScanconfigurer
<!-- 配置数据流对象 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource">
<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
<property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:MLDN"></property>
<property name="username" value="scott"></property>
<property name="password" value="123456"></property>
</bean>
<!-- 加载 mybatis配置文件创建SqlSessionFactory-->
<bean id="factory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:sqlmap-config.xml"></property>
</bean>
<!-- 加载basePackage路径下的Mapper接口生成对象 -->
<bean id="mapperscan" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="sqlSessionFactory" ref="factory"></property>
<property name="basePackage" value="com.xdl.mapper"></property>
</bean>
获取SqlSession对象操作。变为Spring获取对象的方式。
public class mybatistest {
public static void main(String[] args) {
ApplicationContext app =
new ClassPathXmlApplicationContext("applicationContext.xml");
DeptMapper bean = app.getBean("deptMapper",DeptMapper.class);
List<Dept> findAll = bean.findAll();
for (Dept dept : findAll) {
System.out.println(dept.getDeptno()+" "+dept.getDname());
}
}
}
2.自定义Dao接口和实现组件
使用SqlSessionFactoryBean和SqlSessionTemplate。‘
导入spring、mybatis、驱动包、连接池、mybatis-spring
添加sqlmap-config.xml、applicationContext.xml
根据表定义实体类(没有区别)
定义SQL语句文件(没有区别)
自定义DeptDao接口和实现类,扫描注入SqlSessionTemplate
定义DeptDao接口
public interface DeptDao {
public List<Dept> findAll();
public int add(Dept dept);
}
接口的实现类,注入SqlSessionTemplate
@Repository("deptDao")
public class MyDeptDao implements DeptDao {
@Autowired
private SqlSessionTemplate template;
@Override
public List<Dept> findAll() {
List<Dept> list = template.selectList("dept.findAll");
return list;
}
@Override
public int add(Dept dept) {
return template.insert("dept.save", dept);
}
}
在Spring配置DataSource、SqlSessionFactoryBean、SqlSessionTemplate、DeptDao
<!-- 配置数据源DataSource-->
<bean id="dbcp"
class="org.apache.commons.dbcp.BasicDataSource">
<property name="username" value="SCOTT"></property>
<property name="password" value="TIGER"></property>
<property name="url" value="jdbc:oracle:thin:@localhost:1521:XE"></property>
<property name="driverClassName" value="oracle.jdbc.OracleDriver"></property>
</bean>
<!-- 加载mybatis配置文件创建SqlSessionFactory -->
<bean id="factory"
class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dbcp"></property>
<property name="configLocation" value="classpath:sqlmap-config.xml">
</property>
</bean>
<!-- 配置sqlSessionTemplate-->
<bean id="template"
class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="factory">
</constructor-arg>
</bean>
<context:component-scan base-package="cn.xdl.dao"/>
测试Dao接口中的方法
public class TestDeptMapper {
public static void main(String[] args) {
String conf = "applicationContext.xml";
ApplicationContext ac =
new ClassPathXmlApplicationContext(conf);
DeptDao deptDao = ac.getBean("deptDao",DeptDao.class);
List<Dept> list = deptDao.findAll();
for(Dept dept:list){
System.out.println(dept.getDeptno()+" "+dept.getDname());
}
}
}
MyBatis注解SQL
SQL定义可以使用XML文件,也可使用注解方式。
注解SQL是写在Mapper映射器接口中。
1.定义实体类Emp(没变化)
2.定义EmpMapper映射器
public interface EmpMapper {
@Select("select * from EMP")
public List<Emp> selectAll();
@Select("select * from EMP where EMPNO=#{no}")
public Emp selectById(int id);
@Insert("insert into EMP(EMPNO,ENAME,JOB,MGR,HIREDATE,SAL,COMM,DEPTNO) values (#{empno},#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})")
public int save(Emp emp);
@Update("update EMP set ENAME=#{name,jdbcType=VARCHAR} where EMPNO=#{no,jdbcType=NUMERIC}")
public int updateName(@Param("no")int id,@Param("name")String name);
}
3.在sqlmap-config.xml加载EmpMapper映射器
<mapper class="cn.xdl.mapper.EmpMapper"/>
这是Mybatis中Sql注解使用的方法,但是不用担心整合Spring之后修改的地方相同!
常见问题
1.无效列类型: 1111
产生原因:#{} SQL参数遇到了null值,MyBatis底层无法分辨导致的异常。
解决方法:追加jdbcType属性指定,例如#{name,jdbcType=VARCHAR}、#{id,jdbcType=NUMERIC}
2.Mybatis自带分页使用灵活性、性能都比较差。
session.selectList(SQL的ID,SQL的参数,分页器RowBounds对象)
- 在代码中使用Mybatis自带的分页
执行分页查询 RowBounds bounds = new RowBounds(3, 3);//从第一条开始抓取,取2个 List<Dept> list = session.selectList( "cn.xdl.mapper.DeptMapper.findAll",null,bounds); for(Dept dept:list){ System.out.println(dept.getDeptno()+" "+dept.getDname()); }
优化方法,使用pagehelper工具包
- 添加pagehelper、jsqlparse工具包
-
在sqlmap-config.xml配置pagehelper
<!-- 开启日志-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="oracle"/>
</plugin>
</plugins>
- 在代码中使用PageHelper.startPage()
//Mapper映射器
EmpMapper empDao = session.getMapper(EmpMapper.class);
//分页设置
Page page = PageHelper.startPage(2,3);//查询第一页,一页3条
List<Emp> list = empDao.selectAll();
for(Emp e:list){
System.out.println(e.getEmpno()+" "+e.getEname());
}
System.out.println("总记录数:"+page.getTotal()
+" 总页数:"+page.getPages()+" 当前页:"+page.getPageNum());