一、配置文件头部声明
部分异常是因为头部声明版本低等原因引起的,需要收集相关信息
-
Web.xml头部声明
<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0">
-
Spring相关部分头部声明
<!--spring配置头部声明--> <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mvc="http://www.springframework.org/schema/mvc" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd"> </beans>
-
Mybatis映射文件约束头
<?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">
-
MyBatis核心配置文件约束头
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
二、MyBatis开发步骤
-
添加MyBatis坐标 :mybatis + mysql
-
创建数据表和POJO(Plain Ordinary Java Object)
-
Mapper映射文件配置
映射文件位置一般与dao层Java文件位置保持一致,配置SqlSessionFactoryBean时可以不用指定该属性的值。创建时创建到resources目录下,其他层级与dao层目录相同,每层目录间用 "/" 而不是 ".",- 代理开发方式实现Dao层(第二种为手动方式)
Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同Dao接口实现类方法,Mapper 接口开发需要遵循以下规范:
- Mapper.xml文件中的namespace与mapper接口的全限定名相同
- Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
- Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同
- Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
- 基本配置
<mapper namespace="userMapper"> <select id="findAll" resultType="POJO fully-qualified name"> select * from User </select> </mapper>
标签详解:- mapper 根标签
namespace - 定义命名空间,与类似select标签的id一起组成查询标识 - insert、delete、update、select 标签中定义sql语句
resultType - 结果对应的实体类型
paramType - 参数对应的实体类型
- mapper 根标签
- 动态SQL语句
- 多条件组合查询动态SQL之 if 标签
<select id="findByCondition" parameterType="user" resultType="user"> select * from User <where> <if test="id!=0"> and id=#{id} </if> <if test="username!=null"> and username=#{username} </if> </where> </select>
- 循环执行sql的拼接动态SQL之 foreach,例如:SELECT * FROM USER WHERE id IN (1,2,5)
<select id="findByIds" parameterType="list" resultType="user"> select * from User <where> <foreach collection="array" open="id in(" close=")" item="id" separator=","> #{id} </foreach> </where> </select> <!--
属性: collection:代表要遍历的集合元素,注意编写时不要写#{} open:代表语句的开始部分 close:代表结束部分 item:代表遍历集合的每个元素,生成的变量名 sperator:代表分隔符 --> - SQL片段抽取,使用时用 include 引用即可
<!--抽取sql片段简化编写--> <sql id="selectUser" select * from User</sql> <select id="findById" parameterType="int" resultType="user"> <include refid="selectUser"></include> where id=#{id} </select> <select id="findByIds" parameterType="list" resultType="user"> <include refid="selectUser"></include> <where> <foreach collection="array" open="id in(" close=")" item="id" separator=","> #{id} </foreach> </where> </select>
- 多条件组合查询动态SQL之 if 标签
- 多表查询
- 代理开发方式实现Dao层(第二种为手动方式)
-
MyBatis核心配置文件 SqlMapConfig
核心配置文件中的标签和子标签:
- environments 标签
<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>
- 事务管理器(transactionManager)类型有两种
JDBC:这个配置就是直接使用了JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
MANAGED:不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接,然而一些容器并不希望这样,因此需要将 closeConnection 属性设置为 false 来阻止它默认的关闭行为。 - 数据源(dataSource)类型有三种:
UNPOOLED:这个数据源的实现只是每次被请求时打开和关闭连接。
POOLED:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来。
JNDI:这个数据源的实现是为了能在如 EJB 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
- 事务管理器(transactionManager)类型有两种
- mapper 标签,加载映射有以下四种方式:
-
使用相对于类路径的资源引用,例如:
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
-
使用完全限定资源定位符(URL),例如:
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
-
使用映射器接口实现类的完全限定类名,例如:
<mapper class="org.mybatis.builder.AuthorMapper"/>
-
将包内的映射器接口实现全部注册为映射器,例如:
<package name="org.mybatis.builder"/>
-
- properties 标签,加载其他如 jdbc.properties 配置文件
<properties resource="jdbc.properties" />
- typeAliases 标签,设置别名
<typeAliases> <!--后续调用resultType等时可调用该alias别名--> <typeAlias type="POJO fully-qualified name“ alias="user"></typeAlias> <!--还可以使用扫描包的方式 <package name="domain fully-qualified name" /> --> </typeAliases>
- typeHandlers 标签,注册类型转换器,下方为日期转换器
public class MyDateTypeHandler extends BaseTypeHandler<Date> { public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType type) { preparedStatement.setString(i,date.getTime()+""); } public Date getNullableResult(ResultSet resultSet, String s) throws SQLException { return new Date(resultSet.getLong(s)); } public Date getNullableResult(ResultSet resultSet, int i) throws SQLException { return new Date(resultSet.getLong(i)); } public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException { return callableStatement.getDate(i); } }
<!--注册类型自定义转换器--> <typeHandlers> <typeHandler handler="com.itheima.typeHandlers.MyDateTypeHandler"></typeHandler> </typeHandlers>
- plugins 标签,添加第三方插件,如分页插件等
分页插件的使用:
- 导入pagehelper依赖
- Spring中配置pagehelper插件
<property name="plugins"> <array> <!-- 传入插件的对象 --> <bean class="com.github.pagehelper.PageInterceptor"> <property name="properties"> <props> <prop key="helperDialect">oracle</prop> <prop key="reasonable">true</prop> </props> </property> </bean> </array> </property>
- PageHelper.startPage 静态方法调用(重点),另有RowBounds方式
//service层 //获取第1页,10条内容,默认查询总数count PageHelper.startPage(1, 10); //紧跟着的第一个select方法会被分页 List<Country> list = countryMapper.selectIf(1); //controller层 @RequestMapping("/findAll") public ModelAndView findAll(@RequestParam(name = "page",required = true,defaultValue = "1")Integer page,@RequestParam(name = "pageSize",required = true,defaultValue = "4")Integer pageSize) throws Exception{ ModelAndView mv = new ModelAndView(); List<Order> orders = orderService.findAll(page,pageSize); //创建pageInfo对象,对查询的数据包括page相关信息进行封装,构造函数参数为查询的集合 PageInfo pageInfo = new PageInfo(orders); mv.addObject("pageInfo",pageInfo); mv.setViewName("orders-list"); return mv; }
- environments 标签
-
获取SqlSession执行SQL语句(初期手动创建SqlSession时用)
//加载核心配置文件,Resources 工具类在 org.apache.ibatis.io 包中 InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml"); //获得sqlSession工厂对象 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); //获得sqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession(); //执行sql语句
List<User> userList = sqlSession.selectList("userMapper.findAll"); //打印结果
System.out.println(userList); //释放资源
sqlSession.close();SqlSessionFactory 有多个方法创建 SqlSession 实例。常用的有如下两个:
- openSession():会默认开启一个事务,但事务不会自动提交,也就意味着需要手动提交该事务,更新操作数据才会持久化到数据库中
- openSession(boolean autoCommit):参数为是否自动提交,如果设置为true,那么不需要手动提交事务
三、注解开发
四、MyBatis和Spring、SpringMVC的整合
- 将Session工厂交给Spring容器管理,从容器中获得执行操作的Mapper实例即可
<!--加载jdbc.properties--> <context:property-placeholder location="classpath:jdbc.properties"/><!--配置数据源--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}"/> <property name="jdbcUrl" value="${jdbc.url}"/> <property name="user" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </bean> <!--配置MyBatis的SqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/>
<!--不再创建MyBatis核心配置文件,全部交由Spring配置文件管理--><!--property name="configLocation" value="classpath:sqlMapConfig.xml"/--> <!--扫描POJO包,给包下所有pojo对象起别名--> <property name="typeAliasesPackage" value="domain fully-qualified name" />
<!--mapperLocations:它表示我们的Mapper文件存放的位置,当我们的Mapper文件跟对应的Mapper接口处于同一位置的时候可以不用指定该属性的值
-->
</bean>
<!--配置Mapper扫描,生成包下所有接口的代理对象并放入Spring容器中-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.itheima.mapper"/>
</bean> - 将事务的控制交给Spring容器进行声明式事务控制
<!--配置声明式事务控制(配置文件方式)--> <bean id="transacionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:advice id="txAdvice" transaction-manager="transacionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" /> <tx:method name="find*" read-only="true" /> <tx:method name="*" propagation="REQUIRED" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="txPointcut" expression="execution(* GroupId.ArtifactId.service.impl.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/> </aop:config>
<!--配置声明式事务控制(注解方式)-->