动态SQL内置参数

前面的例子中,配置映射关系的xml文件里,所有的参数都是来自接口方法的传值,但是Mybatis内部,其实还有两个很有作用的内置参数的,他们是:
①_databaseId: 在全局变量中配置了多数据库支持的databaseIdProvider属性的前提下,这个内置参数的值就是databaseIdProvider配置的数据库的别名。
②_parameter: 这个内置参数是接口方法传过来的参数的整体的应用,两种情况,一是如果接口方法传来的是单个参数,_parameter就是这个单参数的值,另一种情况是接口方法传来了多个参数的时候会被封装为一个map对象,_parameter就是这个map对象的引用变量。
举例来说明一下
前面的例子中,我们有两种数据库,这里可用_databaseId,来作判断,它的值由系统自动设置,这样我可以不用分开写方法。

_parameter参数:

实际上,以前写的就是省略了_parameter。
动态SQL的绑定和公共sql语句片段
前面把Mybatis的大部分动态标签都讲完了,最后还有三个标签,分别是bind,sql和include:
①bind:这个标签作用就是将OGNL标签里的值,进行二次加工,在绑定到另一个变量里,供其他标签使用,举个例子:

调用getUsers方法的时候,我们可不可以只传入“a”呢,不传%百分号?bind标签就可以帮我们实现:

bind绑定共享语句。 模糊查询中,不用输入百分了。不建议这样用,因为它不拼接null,会出现空指针异常。
②sql和include:这两个标签是配合一起使用的,作用就是将一些重复的slq片段,像提公因式样,单独抽出来可以重复调用,这个很好用。看例子:
在查询,插入,修改中,真正项目中不可能用’*'这个通配符,而又当字段多的时候,又很烦锁也容易出错,所以我们可以把这些字段代码,提出来,当作一个变量用。

1.sql和include配合使用,sql标签里和其他增删改查标签一样支持动态slq标签 2.include标签可以通过property子标签给sql标签里传值,sql标签里用${name}获取
讲到这里,就单纯的Mybatis的基本使用的知识点,基本讲完了,也就是说凭着前面讲过的知识点,你就可以将Mybatis用起来了,但是实际上想要真正在项目开发上用好Mybatis需要的知识点还有很多,比如它的第三方插件通用Mapper,增强工具插件mybatis-plus,分页插件Mybatis_PageHelper,调用存储过程,和spring框架的整合,根据特殊的项目需要编写自己的插件,还有官方提供的自动生成xml和pojo类的Mybatis Generator工具等等,这些知识点,这门Mybatis基础课程会讲一部分,剩下的后面再开专题课程讲!下一次课我们就看看Mybatis Generator工具的使用!
Generator(MBG)
MyBatis Generator(MBG),这是官方帮我们提供的一个自动生成代码的工具,前面的课程中,我们都是脑袋里想好,pojo有哪些属性,属性的类型是什么,对应的数据表中的字段名字是什么,匹配的类型是什么…然后还要写接口xxxDao,以及它的实现配置文件xxxDao.xml等等都是手动自己操作,以前我们学习Hibernate的时候,感觉方便就是写好pojo启动服务器Hibernate会自动帮助我们生成对应的数据表,MyBatis也有类似的工具,MBG就是官方给我提供的这样的工具,但它和Hibernate有点不一样就是,Hibernate帮我们生成表,MBG帮我们根据表生成接口、pojo类和xml这些文件!方向是反的。
使用MBG
要使用MBG首先要导jar包和建立一个XML配置文件
导包
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
以下元素就是MBG的最小配置
<jdbcConnection> 元素指定如何连接数据库
<javaModelGenerator>元素指定生成Model的目标package与目标project
<sqlMapGenerator>元素指定生成Mapping XML文件的目标package与目标project
(Optionally)<javaClientGenerator>元素指定生成Mapper(即DAO)文件的目标package与目标project, 如果不指定这个元素就不会生成Mapper文件
至少一个<table>元素
resources/mbgConfig.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!-- 数据库的驱动, JAR/ZIP文件的全路径,maven工程,驱动已经依赖了,没用-->
<!-- <classPathEntry location="/Program Files/IBM/SQLLIB/java/db2java.zip"/> -->
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 去除自动生成的注释 -->
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--基础的数据库连接-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://124.220.60.104:3306/mybatisdemo2?allowMultiQueries=true"
userId="root"
password="xiong">
</jdbcConnection>
<!--Java类型解析器, 目前也就只有forceBigDecimals可以给你玩-->
<javaTypeResolver>
<!--当数据类型为DECIMAL或者NUMERIC的时候, 如果是true的话则总是使用java.math.BigDecimal-->
<!--以下是false, 即默认值的情况-->
<!--如果有小数或者decimal长度大于18, Java类型为BigDecimal-->
<!--如果没有小数, 以及decimal长度为10至18, Java类型为Long-->
<!--如果没有小数, 以及decimal长度为5至9, Java类型为Integer-->
<!--如果没有小数, 以及decimal长度少于5, Java类型为Short-->
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--Domain生成器,生成modle类-->
<javaModelGenerator targetPackage="cn.ybzy.mybatisdemo.model" targetProject=".\src\main\java">
<!--据说可以自动添加schema名, 可是我没用到过-->
<property name="enableSubPackages" value="true"/>
<!--生成全属性构造器, 没什么用, 如果有指定immutable元素的话这个会被忽略-->
<property name="constructorBased" value="true"/>
<!--生成不可变的domain, 这个我也很少用-->
<property name="immutable" value="true"/>
<!--每个Domain都继承这个bean-->
<property name="rootClass" value="com.github.prontera.domain.base.BasicEntity"/>
<!--当遇到String的时候setter是否会先trim()-->
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--Mapping生成器-->
<sqlMapGenerator targetPackage="cn.ybzy.mybatisdemo.mapper" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--Mapper生成器, 当type为ANNOTATEDMAPPER时是带有@annotation的Mapper, MIXEDMAPPER是XML文件-->
<javaClientGenerator type="XMLMAPPER" targetPackage="cn.ybzy.mybatisdemo.mapper" targetProject=".\src\main\java">
<property name="enableSubPackages" value="true"/>
<!--每个Mapper所继承的接口-->
<property name="rootInterface" value="com.github.prontera.Mapper"/>
</javaClientGenerator>
<!--字段命名策略过程: <columnRenamingRule> >> property name="useActualColumnNames"-->
<!--alias属性是个神器, 会为所有SQL都添加, 做关联的时候就非常方便了-->
<!--至于什么Example, 全关了就是-->
<table alias="u" tableName="sb_users" domainObjectName="User"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
<!--指定是否用数据库中真实的字段名, 而不是采用MBG转换后的驼峰-->
<!-- <property name="useActualColumnNames" value="true"/> -->
<!--自动集成改类-->
<!-- <property name="rootClass" value="com.github.prontera.domain.base.HelloBasicClass"/> -->
<!--Mapper自动继承的接口-->
<!-- <property name="rootInterface" value="com.github.prontera.Mapper"/> -->
<!--当遇到String的时候setter是否会先trim()-->
<!-- <property name="trimStrings" value="true"/> -->
<!--先进行columnRenamingRule, 再进行useActualColumnNames. 如果有columnOverride则忽略该配置-->
<!--关于columnRenamingRule的具体例子 http://www.mybatis.org/generator/configreference/columnRenamingRule.html-->
<!-- <columnRenamingRule searchString="^CUST_" replaceString=""/> -->
<!--顾名思义, 忽略某些列-->
<!-- <ignoreColumn column="CREATE_TIME"/> -->
<!--也是忽略数据列, 但是可以通过正则表达式, except子元素是可选的, 代表忽略除UPDATE_TIME外的列-->
<!-- <ignoreColumnsByRegex pattern=".*_TIME$">
<except column="UPDATE_TIME"/>
</ignoreColumnsByRegex> -->
</table>
<table alias="r" tableName="sb_roles" domainObjectName="Role"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
Java的方法运行插件
官方文档中,介绍了下图所示的几种方法,我选第四种方法


@Test
public void runmgb() throws IOException, XMLParserException, InvalidConfigurationException, SQLException, InterruptedException {
List<String> warnings=new ArrayList<String>();
boolean overwrite=true;
String path= this.getClass().getClassLoader().getResource("mbgConfig.xml").getPath();
File configFile=new File(path);
ConfigurationParser cp =new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback =new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator=new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
注意:生成的User.java,Role.java…模型类中,要添加一个无参构造方法,不然会出现没有构造方中找到字段异常
Mybatis的分页插件
简单使用PageHelper的步骤:
1.导入jar包:
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.4</version>
</dependency>
2.在Mybatis中全局配置文件中配置拦截器

3.Mapper接口方式的调用,推荐这种使用方式。
//分页查询测试
@Test
public void pagetest() throws IOException {
InputStream inputStream=Resources.getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sessionFactory.openSession();
try {
UserMapper userMapper=session.getMapper(UserMapper.class);
Page<User> page = PageHelper.startPage(1,5); //设定一页记录有5条,默认是最开始5条
List<User> users= userMapper.getAllUser();
for(User user:users) {
System.out.println(user);
}
}finally {
session.close();
}
/*
User [id=14, username=xiong1, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=15, username=xiong2, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=16, username=xiong3, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=17, username=xiong4, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=9, username=tttt, password=tt, state=1, regDate=Sat Sep 01 00:00:00 CST 2018, roleId=0] */
try {
UserMapper userMapper=session.getMapper(UserMapper.class);
Page<User> page = PageHelper.startPage(1,5); //设定一页记录有5条,默认是最开始5条
List<User> users= userMapper.getAllUser();
for(User user:users) {
System.out.println(user);
}
System.out.println(page.getPageNum()); //显示页数 1
System.out.println(page.getPageSize()); //显示一页的条数 5
System.out.println(page.getTotal()); //显示整个表的记录数 13
}finally {
session.close();
}
/*
User [id=14, username=xiong1, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=15, username=xiong2, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=16, username=xiong3, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=17, username=xiong4, password=xiong, state=1, regDate=Thu Nov 20 19:55:13 CST 2025, roleId=0]
User [id=9, username=tttt, password=tt, state=1, regDate=Sat Sep 01 00:00:00 CST 2018, roleId=0]
1
5
13
*/
也可以返回PagerInfo类型,它里边包含了更丰富的分页信息:
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum()); //当前而的
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());
try {
UserMapper userMapper=session.getMapper(UserMapper.class);
//User user = userMapper.selectByPrimaryKey(2);//利用mbg自动依据表生成的Mapper接口和实现(xml格式)的文件。
//System.out.println(user);
//Page<User> page = PageHelper.startPage(1,5); //第一页记录有5条
Page<User> page2 = PageHelper.startPage(2,5); ////第二页记录有5条
List<User> users= userMapper.getAllUser();
for(User user:users) {
System.out.println(user);
}
System.out.println(page2.getTotal()); //显示整个表的记录数 13
PageInfo<User> pageInfo = new PageInfo<>(users);
System.out.println(pageInfo.getPageNum()); //显示页数 2
System.out.println(pageInfo.getPageSize()); //显示一页的条数 5
System.out.println(pageInfo.isHasNextPage()); //还有没有下一页,true
}finally {
session.close();
}
Mybatis做批量操作
前面我们将动态标签foreach的时候,做过批量操作,但是foreach只能处理记录数不多的批量操作,数据量大了后,先不说效率,能不能成功操作都是问题,所以这里讲一讲Mybatis正确的批量操作方法:在获取opensession对象的时候,我们可以传入参数,告诉Mybatis我要批量操作:

测试批量插入10000条记录:这是我们是用了有选择性的插入,当然了在User中要有一个构造方法,三个字段,username,password,reg_date.

调用存储过程
在mysql数据库中创建一个存储过程:查询所有用户记录信息
DELIMITER $$
CREATE
PROCEDURE `mybatisdemo`.`getusersprocedure`(IN sid INT,IN eid INT)
BEGIN
SELECT * FROM sb_users WHERE id>=sid AND id<=eid;
END$$
DELIMITER ;
在Mapper接口里创建方法,和普通的查询数据方法没区别:
public List<User> getUsersByProcedure(@Param("sid") int sid,@Param("eid") int eid);
在Mybatis中调用存储过程

UserMapper.xml
<!-- 调用存过程来获取所有用户记录 -->
<select id="getUsersByProcedure" resultType="cn.ybzy.mybatisdemo.model.User" statementType="CALLABLE" >
{call getusersprocedure(
#{sid,mode=IN,jdbcType=INTEGER},
#{eid,mode=IN,jdbcType=INTEGER}
)}
</select>
测试
//调用存储过程测试,这里我们获取所有用户记录,再查询记录号在sid,eid之间的记录
@Test
public void procedureTest() throws IOException {
InputStream inputStream=Resources.getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session=sessionFactory.openSession();
try {
UserMapper userMapper=session.getMapper(UserMapper.class);
List<User> users=userMapper.getUsersByProcedure(1,5);
System.out.println(users);
}finally {
session.close();
}
}
spring,springmvc整合mybatis
开发工具-sts 3.9,创建一个maven web项目




1.导入jar包,pom.xml的配置如下:
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>5.0.6.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>2.2</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.25</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-spec</artifactId>
<version>1.2.5</version>
<type>bundle</type>
</dependency>
<dependency>
<groupId>org.apache.taglibs</groupId>
<artifactId>taglibs-standard-impl</artifactId>
<version>1.2.5</version>
<type>bundle</type>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc6</artifactId>
<version>12.1.0.1-atlassian-hosted</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.1.0</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.4</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<extensions>true</extensions>
</plugin>
</plugins>
</build>
依赖有:spring核心:上下文依赖(context),springmvc的web,事务处理(spring-tx),切面编程(aspects),持久化包orm.JAVAWEB:Servlet-api,jsp-api 这两个包不发布到生产环境中去(proviced),日志包三个,oracle,mysql数据库驱动两个包,mybatis整合包(mybatis-spring),分页插件,jstl包,因为它要bundle功能,所以有一个maven-bundle-plugin插件。
2.在web.xml里做spring和springmvc的初始配置,这样我们就不用在应用中创建SqlSessionFactory对象打开会话了,直接调用映射方法即可
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd" id="WebApp_ID" version="3.1">
<!-- 给spring框架指定配置文件的位置,当在该文件中输入ContextLoaderListener会自动生成之,但要手工写位置 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<!-- <param-value>location</param-value> -->
<param-value>classpath:spring.xml</param-value>
</context-param>
<!-- spring和javaweb应用之间的一个整合 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!--springmvc整合javaweb,当在该文件中输入DispatcherServlet回车后,逢动成生一些文件,我们再修改一下即可 -->
<servlet>
<servlet-name>springDispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<!-- <param-value>location</param-value> -->
<param-value>classpath:springmvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springDispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
3.SpringMVC只扫描Controller和ControllerAdvice:

创建spring.xml与psringmvc.xml

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:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:mybatis-spring="http://mybatis.org/schema/mybatis-spring"
xsi:schemaLocation="http://mybatis.org/schema/mybatis-spring http://mybatis.org/schema/mybatis-spring-1.2.xsd
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-4.3.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- spring注解只扫描的包,不扫描Controller控制层,其它都扫描,把类放到反转容器里面,生成bean对象 -->
<context:component-scan base-package="cn.ybzy.ssmweb">
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:exclude-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 配置数据库连接与C3P0连接池, 要读取jdbc.properties-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${orcl.user}"></property>
<property name="password" value="${orcl.password}"></property>
<property name="jdbcUrl" value="${orcl.jdbcUrl}"></property>
<property name="driverClass" value="${orcl.driverClass}"></property>
<property name="initialPoolSize" value="${jdbc.initialPoolSize}"></property>
<property name="acquireIncrement" value="${jdbc.acquireIncrement}"></property>
<property name="minPoolSize" value="${jdbc.minPoolSize}"></property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}"></property>
<property name="maxStatements" value="${jdbc.maxStatements}"></property>
<property name="maxStatementsPerConnection" value="${jdbc.maxStatementsPerConnection}"></property>
</bean>
<!-- 事务配置,hibernate的类不一样 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!-- 事务属性,get,find,select,load等开头的方法这种查询的方法都是只读,其它可写的 -->
<tx:advice id="txAdvice" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="get*" read-only="true"/>
<tx:method name="find*" read-only="true"/>
<tx:method name="load*" read-only="true"/>
<tx:method name="select*" read-only="true"/>
</tx:attributes>
</tx:advice>
<!-- 切入点的配置 -->
<aop:config>
<aop:pointcut expression="execution(* cn.ybzy.ssmweb.service.*.*(..))" id="txPointcut"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="txPointcut"/>
</aop:config>
<!-- 整合mybatis,配sessionFactory的bean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis-config.xml"></property>
<property name="mapperLocations" value="classpath:cn/ybzy/ssmweb/mapper/*.xml"></property>
</bean>
<mybatis-spring:scan base-package="cn.ybzy.ssmweb.mapper"/>
</beans>
springmvc必要的命名空间

<?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:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.3.xsd
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-4.3.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.3.xsd">
<!-- springmvc注解只扫描的包,具只扫描Controller控制层,把类放到反转容器里面,生成bean对象,关掉默认扫描功能 -->
<context:component-scan base-package="cn.ybzy.ssmweb" use-default-filters="false">
<context:include-filter type="annotation" expression="org.springframework.stereotype.Controller"/>
<context:include-filter type="annotation" expression="org.springframework.web.bind.annotation.ControllerAdvice"/>
</context:component-scan>
<!-- 必须要的标签:这是一个简化的注解类驱动,把如系统的异常处理,静态资源的转换等等通通放到IOC中 -->
<mvc:annotation-driven/>
<!-- 注册默认视图解析器bean,前缀:设定把如.jsp文件放到指定的文件中,后缀指定文件格式为.jsp -->
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<!-- 将css,jpg,js这些静态资源,让springmvc自动识别,不用在运行执行 -->
<mvc:default-servlet-handler/>
</beans>
jdbc.properties—mysql,oracle,C3P0连接池的最低配置
jdbc.user=root
jdbc.password=xiong
jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://124.220.60.104:3306/mybatisdemo
orcl.user=scott
orcl.password=xiong
orcl.driverClass=oracle.jdbc.OracleDriver
orcl.jdbcUrl=jdbc:oracle:thin:@124.220.60.104:1521:orcl
jdbc.acquireIncrement=5
jdbc.initialPoolSize=10
jdbc.minPoolSize=1
jdbc.maxPoolSize=100
jdbc.maxStatements=20
jdbc.maxStatementsPerConnection=5
log4j.properties
log4j.rootLogger = debug,stdout, D
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.Threshold = INFO
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %m%n
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./log4j.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern=%d %p %m%n
mybatis-config.xml—这里我们不用配连接数据库配置和映射文件配置,它们在spring.xml中配了
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties"></properties>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/><!--驼峰命名规则允许,这样就可以让java类与数据库表字段可以这样对应regDate对应reg_date,不然查询会出出null-->
<!-- 下面两个项,是开启懒加载功能 -->
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<!-- <environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://124.220.60.104:3306/mybatisdemo"/>
<property name="username" value="root"/>
<property name="password" value="xiong"/>
</dataSource>
</environment>
<environment id="oracle">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${orcl.driverClass}"/>
<property name="url" value="${orcl.jdbcUrl}"/>
<property name="username" value="${orcl.user}"/>
<property name="password" value="${orcl.password}"/>
</dataSource>
</environment>
</environments>-->
<databaseIdProvider type="DB_VENDOR">
<!-- 为各数据库起别名,以便在Mapper映射文件中用
可用如下代码查询当前厂商名
String databasemark=session.getConnection().getMetaData().getDatabaseProductName();
System.out.println(databasemark);
-->
<property name="MySQL" value="mysql"/>
<property name="Oracle" value="oracle"/>
<property name="SQL Server" value="sqlserver"/>
</databaseIdProvider>
<mappers>
<!-- <mapper resource="cn/ybzy/mybatisdemo/model/UserMapper.xml"/> -->
<!-- <mapper class="cn.ybzy.mybatisdemo.mapper.UserMapper"/> -->
<!-- <package name="cn.ybzy.mybatisdemo.mapper"/> spring中配了-->
</mappers>
</configuration>
简单应用
我们这里必竞不是做真正的项目,只是做一个讲解应用过程,所以在这里,我的服务层只搞一个方法,所询所有记录,分页之,显示第二页所有记录。模型类必有一个无参构造方法,这里我用了上面的Generator(MBG)插件依据表sb_users,反向生成了User.java,UserMapper.xml,UserMapper.java.具体代码参考上面的Generator(MBG)讲解。
Dao层UserMapper.java,UserMapper.xml
public interface UserMapper {
//.....
public List<User> getAllUsers();//这个是我自已加的主法,mbg自动生成的文件中没有
}
<?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="cn.ybzy.ssmweb.mapper.UserMapper">
<resultMap id="BaseResultMap" type="cn.ybzy.ssmweb.model.User">
<constructor>
<idArg column="id" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="username" javaType="java.lang.String" jdbcType="VARCHAR" />
<arg column="password" javaType="java.lang.String" jdbcType="VARCHAR" />
<arg column="state" javaType="java.lang.Integer" jdbcType="INTEGER" />
<arg column="reg_date" javaType="java.util.Date" jdbcType="TIMESTAMP" />
<arg column="role_id" javaType="java.lang.Integer" jdbcType="INTEGER" />
</constructor>
</resultMap>
<sql id="Base_Column_List">
id, username, password, state, reg_date, role_id
</sql>
<!--查询所有用记录-->
<select id="getAllUsers" resultType="cn.ybzy.ssmweb.model.User">
select
<include refid="Base_Column_List" />
from sb_users
</select>
</mapper>
SERVICE服务层UserService.java,UserServcieImpl.java
public interface UserService {
public List<User> getAllUsers();
}
@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired //spring.xml中 <mybatis-spring:scan base-package="cn.ybzy.ssmweb.mapper"/>,把映射实现放进IOC中了,我们只用即可。
private UserMapper userMapper;
@Override
public List<User> getAllUsers() {
//Page是分页功能类,导的外部包com.github.pagehelper,、
//下行代码是,我们获取一页记录,记录数为5条,从第二页开始
Page<User> page2 = PageHelper.startPage(2,5);
System.out.println(page2.getPageSize());
System.out.println(page2.getPageNum());
return userMapper.getAllUsers(); //获取第二页的所有记录
}
}
控制层UserController.java
@Controller
public class UserControlloer {
@Autowired
private UserService userService;
@RequestMapping("/")
public String index(Model model) {
List<User> users=userService.getAllUsers();
model.addAttribute("users", users);
return "index";
}
}
视图层/WEB-INF/views/index.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>显示用户信息</title>
</head>
<body>
<h4>显示所有用户信息</h4>
<table border="1">
<tr>
<td>id</td>
<td>用户名</td>
<td>用户密码</td>
<td>注册日期</td>
<td>现在状态</td>
</tr>
<c:forEach var="user" items="${users}"> <!-- users 在控制类中,映射数据据表通过Model注入到了域中 -->
<tr>
<td>${user.id }</td>
<td>${user.username }</td>
<td>${user.password }</td>
<td>${user.regDate }</td>
<td>${user.state }</td>
</tr>
</c:forEach>
</table>
</body>
</html>
测试:不用像在jar工程那样在测试类中要建如下session会话,这里我通过spring把建session对象的类放进IOC容器中了,再在web.xml中配置了监听器,监听到当web tomcat启动时,马上创建会话。
@Test
public void test() throws IOException, SQLException {
//1.获取到创建数据库连接的会话的工厂,根据mybatis配置文件创 建
InputStream inputStream=Resources.getResourceAsStream("mybatisConfig.xml");
SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//2.通过工厂类,获取到数据库连接的会话
SqlSession session=sessionFactory.openSession();
//3.通过session操作数据库
try {
userMapper=session.getMapper(UserMapper.class);
}finally{
session.close();
}
}
而我只要启动tomcat就可以了,执行控制层方法了。再到浏览器中输入:http://localhost:8081/ssmweb/回车即可看到如下图所示效果

797

被折叠的 条评论
为什么被折叠?



