一、Mybatis 动态SQL 配置
1. XML 标签配置
if 标签
逻辑判断标签 判断表达式 true
<if test="表达式"></if> <!-- and | or -->
使用
<!-- 01 -->
<select id="queryAccountsByParams01" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
where 1=1
<if test="aname !=null and aname !=''">
and aname like concat('%',#{aname},'%')
</if>
<if test="type !=null and type !=''">
and type=#{type}
</if>
<if test="userId=null">
and user_id=#{userId}
</if>
<if test="time !=null and time !=''">
and create_time >=#{time}
</if>
</select>
<!-- 02 -->
<select id="queryAccountsByParams02" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
where 1=1
<if test="@Ognl@isNotEmpty(aname)">
and aname like concat('%',#{aname},'%')
</if>
<if test="@Ognl@isNotEmpty(type)">
and type=#{type}
</if>
<if test="userId !=null">
and user_id=#{userId}
</if>
<if test="@Ognl@isNotEmpty(time)">
and create_time >=#{time}
</if>
</select>
where 标签
记录过滤标签
<where>
...
</where>
使用 记录过滤 | 条件过滤 如果紧跟where 后第一个逻辑判断条件成立时 and|or 单词被忽略
<select id="queryAccountsByParams" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
<where>
<if test="@Ognl@isNotEmpty(aname)">
and aname like concat('%',#{aname},'%')
</if>
<if test="@Ognl@isNotEmpty(type)">
and type=#{type}
</if>
<if test="userId !=null">
and user_id=#{userId}
</if>
<if test="@Ognl@isNotEmpty(time)">
and create_time >=#{time}
</if>
</where>
</select>
choose when otherwise 标签
对结果 条件判断 执行二选一 类似 if-else
<choose>
<when test=""></when>
<otherwise></otherwise>
</choose>
<select id="queryAccountsByParams04" parameterType="AccountQuery" resultType="Account">
select id, aname, user_id as userId, create_time as createTime, update_time as updateTime, remark,
<choose>
<when test="userId !=null">
money
</when>
<otherwise>
type
</otherwise>
</choose>
from account
<where>
<if test="aname !=null and aname !=''">
and aname like concat('%',#{aname},'%')
</if>
<if test="type !=null and type !=''">
and type=#{type}
</if>
<if test="userId !=null">
and user_id=#{userId}
</if>
<if test="time !=null and time !=''">
and create_time >=#{time}
</if>
</where>
</select>
<!--
动态sql 标签-choose when otherwise if-else 二选一
-->
<select id="queryAccountsByParams05" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
<where>
<choose>
<when test="userId != null">
<if test="aname != null and aname != ''">
aname like concat('%',#{aname},'%')
</if>
</when>
<otherwise>
<if test="type != null and type != ''">
type=#{type}
</if>
</otherwise>
</choose>
</where>
</select>
trim 标签
可以替代where(update) 标签类似功能
<trim prefix=" " prefixOverrides=" " suffixOverrides=" " suffix=" "></trim>
使用
<select id="queryAccountsByParams06" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
<trim prefix="where" prefixOverrides="and |or" >
<if test="aname !=null and aname !=''">
and aname like concat('%',#{aname},'%')
</if>
<if test="type !=null and type !=''">
and type=#{type}
</if>
<if test="userId !=null">
and user_id=#{userId}
</if>
<if test="time !=null and time !=''">
and create_time >=#{time}
</if>
</trim>
</select>
set 标签
<!--用于更新 如果最后一个字段出现, 该字符会被自动忽略-->
<set></set>
使用
<update id="updateAccountById" parameterType="Account">
update account
<set>
<if test="aname !=null">
aname=#{aname},
</if>
<if test="type !=null">
type=#{type},
</if>
<if test="money !=null">
money=#{money}
</if>
</set>
where id=#{id}
</update>
foreach 标签
用于批量操作(批量添加 更新 删除)
批量添加
<insert id="saveUserBatch" parameterType="list">
insert into user(user_name, user_pwd, flag, create_time) values
<foreach collection="list" item="item" separator=",">
(#{item.userName},#{item.userPwd},#{item.flag},#{item.createTime})
</foreach>
</insert>
批量更新
<update id="updateUserPwdByIdsBatch" parameterType="map">
update user set user_pwd=#{userPwd}
where id in
<foreach collection="ids" item="item" open="(" separator="," close=")" >
#{item}
</foreach>
</update>
批量删除
<delete id="deleteUsersByIds03" parameterType="map">
delete from user where id in
<!--
collection:array|list
如果参数类型为map map key对应的value 为数组或list 此时collection值为key 名称
-->
<foreach collection="ids" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</delete>
2. 基于注解sql 配置
添加注解
@Insert
@InsertProvider
@Insert("insert into account(aname,type,money,remark,create_time,update_time,user_id) values(#{aname},#{type},#{money},#{remark},#{createTime},#{updateTime},#{userId})")
// @InsertProvider()
public int saveAccount(Account account);
查询注解
@Select
@Select("select id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark from account where id=#{id}")
public Account queryAccountById(Integer id);
@SelectProvider
- type:Class 产生Sql字符串的Java 类
- method:方法名称
@SelectProvider(type = AccountProvider.class, method = "getQueryAccountsByParamsSql01")
public List<Account> queryAccountsByParams01(AccountQuery accountQuery);
public class AccountProvider {
public String getQueryAccountsByParamsSql01(AccountQuery accountQuery){
return new SQL(){
{
SELECT("id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark ");
FROM("account");
WHERE(" 1=1 ");
if(StringUtils.isNotBlank(accountQuery.getAname())){
WHERE(" aname like concat('%',#{aname},'%') ");
}
if(StringUtils.isNotBlank(accountQuery.getType())){
WHERE(" type=#{type} ");
}
if(StringUtils.isNotBlank(accountQuery.getTime())){
WHERE(" create_time >=#{time}") ;
}
if(accountQuery.getUserId()!=null){
WHERE(" user_id=#{userId}");
}
}
}.toString();
}
}
@SelectProvider(type = AccountProvider.class,method = "getQueryAccountsByParamsSql02")
public List<Account> queryAccountsByParams02(AccountQuery accountQuery);
public class AccountProvider {
public String getQueryAccountsByParamsSql02(AccountQuery accountQuery){
StringBuffer stringBuffer=new StringBuffer("select id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark " +
" from account where 1=1 ");
if(StringUtils.isNotBlank(accountQuery.getAname())){
stringBuffer.append(" and aname like concat('%',#{aname},'%') ");
}
if(StringUtils.isNotBlank(accountQuery.getType())){
stringBuffer.append(" and type=#{type} ");
}
if(StringUtils.isNotBlank(accountQuery.getTime())){
stringBuffer.append(" and create_time >=#{time} ");
}
if(accountQuery.getUserId()!=null){
stringBuffer.append(" and user_id=#{userId} ");
}
return stringBuffer.toString();
}
}
更新注解
@Update
@UpdateProvider
@Update("update account set aname=#{aname}, type=#{type} where id=#{id}")
//@UpdateProvider()
public int updateAccount(Account account);
删除注解
@Delete
@DeleteProvider
@Delete("delete from account where id=#{id}")
//@DeleteProvider()
public int deleteAccountById(Integer id);
二、Mybatis 关系映射查询
- 关系型数据库(ORM):主键-外键
- 实体 - 实体 对应关系
一对一
例如:学校-校长、用户-身份证、国家-总统、用户-购物车 (t_user | t_cart(user_id))…
用户-身份证
国家-总统
用户-购物车 (t_user | t_cart(user_id))
resultType
- 方法1:dto接收结果
// 接口定义查询方法 结果使用dto 接收
public UserDto queryUserCardInfoByUserId(Integer userId);
public class UserDto {
private Integer userId;
private String userName;
private String userPwd;
private String flag;
private Date createTime;
private String num;// 身份证编号
private Integer cardId;// 身份证id
.......
}
<!--
一对一关联查询 resultType
-->
<select id="queryUserCardInfoByUserId" parameterType="int" resultType="UserDto">
select
u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
from
user u left join id_card c on u.id = c.user_id
where u.id=#{userId}
</select>
- 方法2:使用map
public Map<String, Object> queryUserCardInfoByUserId02(Integer userId);
<select id="queryUserCardInfoByUserId" parameterType="int" resultType="map">
select u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
from user u left join id_card c on u.id = c.user_id
where u.id=#{userId}
</select>
resultMap
public User queryUserCardInfoByUserId03(Integer userId);
<resultMap id="user_map" type="User">
<!--
主表结果映射
id:主键映射配置
-->
<id column="userId" property="id"></id>
<result column="userName" property="userName"></result>
<result column="userPwd" property="userPwd"></result>
<result column="flag" property="flag"></result>
<result column="createTime" property="createTime"></result>
</resultMap>
<resultMap id="user_card_map" type="User" extends="user_map">
<!--
一对一 映射配置
-->
<association property="idCard" javaType="IdCard">
<!--
从表主键映射配置
-->
<id column="cardId" property="id"></id>
<result column="num" property="num"></result>
</association>
</resultMap>
<select id="queryUserCardInfoByUserId" parameterType="int" resultMap="user_card_map">
select
u.id as userId, user_name as userName, user_pwd as userPwd, flag, create_time as createTime,c.id as cardId,c.num
from
user u left join id_card c on u.id = c.user_id
where u.id=#{userId}
</select>
一对多 | 多对一
例如:班级-学生、用户-订单(t_user |t_order(user_id))、公司-员工…
resultMap
public User queryUserCardAccountInfoByUserId(Integer userId);
<resultMap id="user_account_map" type="User" extends="user_card_map">
<!--
一对多映射
property:多的一方 属性名
ofType:集合中元素的类型
id:多的一方主键值的映射配置
-->
<collection property="accounts" ofType="Account">
<id column="aid" property="id"></id>
<result column="aname" property="aname"></result>
<result column="type" property="type"></result>
<result column="money" property="money"></result>
<result column="ctime" property="createTime"></result>
<result column="update_time" property="updateTime"></result>
<result column="remark" property="remark"></result>
</collection>
</resultMap>
<select id="queryUserCardAccountInfoByUserId" parameterType="int" resultMap="user_account_map">
select u.id as userId, user_name as userName, user_pwd as userPwd, flag,
u.create_time as createTime,c.id as cardId,c.num,
a.id as aid, aname, a.type, a.money, a.create_time as ctime, a.update_time, a.remark
from user u
left join id_card c on u.id = c.user_id
left join account a on u.id=a.user_id
where u.id=#{userId}
</select>
多对多
-
例如:教师 - 课程、学生 - 课程 (t_student | t_course 中间表:t-grade(id sid cid grade) )、用户 - 角色(t_user | t_role 中间表:t_user_role)
-
解决方案:拆分为一对多进行处理
-
s01 c01
学生 成绩 课程
–> 学生-成绩:一对多
课程-成绩:一对多
-
三、Spring 整合Mybatis
1. 创建Maven工程
2. 添加坐标依赖
<!-- junit 测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- spring 核心jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring 测试jar -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring jdbc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- spring事物 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.2.RELEASE</version>
</dependency>
<!-- aspectj切面编程的jar -->
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.9</version>
</dependency>
<!-- c3p0 连接池 -->
<dependency>
<groupId>c3p0</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.1.2</version>
</dependency>
<!-- mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<!-- 添加mybatis与Spring整合的核心包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>
<!-- mysql 驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.39</version>
</dependency>
<!-- 日志打印相关的jar -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.7.2</version>
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.2</version>
</dependency>
3. 添加资源文件
- spring.xml 、 mybatis.xml、jdbc.properties、log4j.properties
- spring.xml
<?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"
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">
<!--
配置扫描器
-->
<context:component-scan base-package="com.xyz"/>
<!--
配置 加载jdbc.properties
-->
<context:property-placeholder location="classpath:jdbc.properties"/>
<!--
数据源c3p0 配置
-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driver}"></property>
<property name="jdbcUrl" value="${jdbc.url}"></property>
<property name="user" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
<!--
事物控制
-->
<aop:aspectj-autoproxy/>
<!--
事物管理器
-->
<bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"></property>
</bean>
<!--
声明事物通知
-->
<tx:advice id="txAdvice" transaction-manager="txManager">
<tx:attributes>
<tx:method name="save*" propagation="REQUIRED"/>
<tx:method name="update*" propagation="REQUIRED"/>
<tx:method name="del*" propagation="REQUIRED"/>
</tx:attributes>
</tx:advice>
<aop:config>
<aop:pointcut id="cut" expression="execution(* com.xyz.service..*.*(..))"/>
<aop:advisor advice-ref="txAdvice" pointcut-ref="cut"></aop:advisor>
</aop:config>
<!--
mybatis 整合spring
-->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="configLocation" value="classpath:mybatis.xml"></property>
<property name="mapperLocations" value="classpath:com/xyz/mappers/*.xml"></property>
</bean>
<bean id="mapperScanner" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描com.xyz.dao这个包以及它的子包下的所有映射接口类 -->
<property name="basePackage" value="com.xyz.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactoryBean" />
</bean>
</beans>
-
- mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<package name="com.xyz.query"/>
<package name="com.xyz.vo"/>
<package name="com.xyz.dto"/>
</typeAliases>
</configuration>
-
- jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8
jdbc.username=root
jdbc.password=root
-
- log4j.properties
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
4. 编写代码
以用户模块查询为主 进行测试
- UserDao.java
import com.xyz.vo.User;
public interface UserDao {
public User queryUserByUserId(Integer userId);
}
- UserMapper.xml
<?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.xyz.dao.UserDao">
<select id="queryUserByUserId" parameterType="int" resultType="User">
select id, user_name as userName, user_pwd as userPwd, flag, create_time as createTime from user where id=#{userId}
</select>
</mapper>
- UserService.java
import com.xyz.dao.UserDao;
import com.xyz.vo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class UserService {
@Autowired
private UserDao userDao;
public User queryUserByUserId(Integer userId){
return userDao.queryUserByUserId(userId);
}
}
5. 添加单元测试
import com.xyz.service.UserService;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class TestSpringMybatis {
@Test
public void test(){
ApplicationContext ac =new ClassPathXmlApplicationContext("spring.xml");
UserService userService= (UserService) ac.getBean("userService");
System.out.println(userService.queryUserByUserId(75));
}
}
import com.xyz.service.UserService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import javax.annotation.Resource;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring.xml")
public class TestSpringMybatis02 {
@Resource
private UserService userService;
@Test
public void test(){
System.out.println(userService.queryUserByUserId(75));
}
}
四、Mybatis 分页插件整合
-
添加分页插件坐标
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency>
-
添加分页插件标签-mybatis.xml
<plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
-
添加分页查询dao 方法 与sql 配置
public interface AccountDao extends BaseMapper<Account,Integer> { public List<Account> queryAccountsByParams(AccountQuery accountQuery); }
<sql id="account_columns"> id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark </sql> <!-- 动态sql 标签-if 条件判断标签 --> <select id="queryAccountsByParams" parameterType="AccountQuery" resultType="Account"> select <include refid="account_columns"/> from account where 1=1 <if test="aname !=null and aname !=''"> and aname like concat('%',#{aname},'%') </if> <if test="type !=null and type !=''"> and type=#{type} </if> <if test="userId=null"> and user_id=#{userId} </if> <if test="time !=null and time !=''"> and create_time >=#{time} </if> </select>
-
AccountService 实现分页查询
@Service public class AccountService extends BaseService<Account, Integer> { @Autowired private AccountDao accountDao; public List<Account> queryAccountsByParams(AccountQuery accountQuery){ PageHelper.startPage(accountQuery.getPageNum(),accountQuery.getPageSize()); return accountDao.queryAccountsByParams(accountQuery); } public PageInfo<Account> queryAccountsByParams02(AccountQuery accountQuery){ PageHelper.startPage(accountQuery.getPageNum(),accountQuery.getPageSize()); List<Account> accounts=accountDao.queryAccountsByParams(accountQuery); return new PageInfo<Account>(accounts); } }
-
执行测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations = "classpath:spring.xml") public class TestAccountService { @Resource private AccountService accountService; @Test public void test01(){ AccountQuery accountQuery=new AccountQuery(); accountQuery.setType("1"); accountQuery.setPageNum(3); accountService.queryAccountsByParams(accountQuery).forEach(a->{ System.out.println(a); }); } }
五、Mybatis-Generator 插件生成代码
1. 添加插件
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
2. 准备generatorConfig.xml 配置文件
-
驱动 jar 包路径:classPathEntry
-
连接数据库配置:jdbcConnection
-
javaBean dao接口 xml 映射文件:javaModelGenerator
-
table 标签配置(可以配置多个)
<?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>
<!--数据库驱动-->
<classPathEntry location="C:/m2/repository/mysql/mysql-connector-java/5.1.39/mysql-connector-java-5.1.39.jar"/>
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://127.0.0.1:3306/mybatis"
userId="root"
password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类存放位置-->
<javaModelGenerator targetPackage="com.xyz.vo" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="com.xyz.mappers" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xyz.dao" targetProject="C:\java\idea_32\spring_mybatis\src\main\java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="id_card" domainObjectName="IdCard" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
<table tableName="xx_product_category" domainObjectName="ProductCategory" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
</context>
</generatorConfiguration>
3. 配置执行插件的命令
-
复习 idea 下 maven 基本命令配置:
- clean 清除编译命令(删除target 目录)
- clean compile 先执行清除操作 再重新编译源代码到target 目录
- clean compile package 先执行清除操作 再重新编译源代码到target 目录 再执行打包 打包后文件(.jar .war )存放在 服务器的webapps目录
- clean compile install -Dmaven.test.skip=true 先执行清除操作 再重新编译源代码到target 目录 在执行安装(在maven 本地仓库目录) 执行安装 跳过(忽略) 单元测试
- tomcat7:run
- jetty:run -Djetty.port=xxxx
-
配置 生成文件命令 mybatis-generator:generate
六、MyBatis Base代码封装
- 封装目的:简化代码;提高代码复用率;提高开发效率
1. BaseMapper 接口方法定义
import org.springframework.dao.DataAccessException;
import java.util.List;
import java.util.Map;
/*
T:实体类 泛型参数
ID:表主键类型
*/
public interface BaseMapper<T, ID> {
/**
* 添加记录返回影响行数
*/
public int save(T entity) throws DataAccessException;
/**
* 添加记录返回主键
*/
public ID saveHasKey(T entity) throws DataAccessException;
/**
* 批量添加记录
*/
public int saveBatch(List<T> entities) throws DataAccessException;
/**
* 详情查询
* @param id
* @return
*/
public T queryById(ID id) throws DataAccessException;
/**
* 多条件列表查询
* @param baseQuery
* @return
*/
public List<T> queryByParams(BaseQuery baseQuery) throws DataAccessException;
/**
* 更新单条记录
* @param entity
* @return
*/
public int update(T entity) throws DataAccessException;
/**
* 批量更新
* @param map
* @return
*/
public int updateBatch(Map<String,Object> map) throws DataAccessException;
/**
* 删除单条记录
* @param id
* @return
*/
public int delete(ID id) throws DataAccessException;
/**
* 批量删除
* @param ids
* @return
*/
public int deleteBatch(ID[] ids) throws DataAccessException;
}
2. 子接口继承BaseMapper
这里以账户模块为例
import com.xyz.base.BaseMapper;
import com.xyz.vo.Account;
public interface AccountDao extends BaseMapper<Account,Integer> {
}
账户CRUD(sql) 通过Sql 映射文件体现
<?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.xyz.dao.AccountDao">
<sql id="account_columns">
id, aname, type, money, user_id as userId, create_time as createTime, update_time as updateTime, remark
</sql>
<!--
动态sql 标签-if 条件判断标签
-->
<select id="queryByParams" parameterType="AccountQuery" resultType="Account">
select <include refid="account_columns"/>
from account
where 1=1
<if test="aname !=null and aname !=''">
and aname like concat('%',#{aname},'%')
</if>
<if test="type !=null and type !=''">
and type=#{type}
</if>
<if test="userId=null">
and user_id=#{userId}
</if>
<if test="time !=null and time !=''">
and create_time >=#{time}
</if>
</select>
</mapper>
3. BaseService 封装
封装了service 业务类基本的CRUD 方法
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import java.lang.reflect.Method;
import java.util.List;
import java.util.Map;
public abstract class BaseService<T, ID> {
@Autowired
private BaseMapper<T, ID> baseMapper;
public int save(T entity){
return baseMapper.save(entity);
}
public ID saveHasKey(T entity) {
baseMapper.saveHasKey(entity);
try {
Method method= entity.getClass().getDeclaredMethod("getId",null);
return (ID) method.invoke(entity,null);
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public int saveBatch(List<T> entities){
return baseMapper.saveBatch(entities);
}
public T queryById(ID id){
return baseMapper.queryById(id);
}
public List<T> queryByParams(BaseQuery baseQuery){
return baseMapper.queryByParams(baseQuery);
}
public int update(T entity){
return baseMapper.update(entity);
}
public int updateBatch(Map<String,Object> map){
return baseMapper.updateBatch(map);
}
public int delete(ID id){
return baseMapper.delete(id);
}
public int deleteBatch(ID[] ids){
return baseMapper.deleteBatch(ids);
}
/**
* 分页查询
* @param baseQuery
* @return
*/
public PageInfo<T> queryForPage(BaseQuery baseQuery){
PageHelper.startPage(baseQuery.getPageNum(), baseQuery.getPageSize());
return new PageInfo<T>(queryByParams(baseQuery));
}
}
4. 子类继承BaseService
import com.xyz.base.BaseService;
import com.xyz.vo.Account;
import org.springframework.stereotype.Service;
@Service
public class AccountService extends BaseService<Account, Integer> {
}
七、Mybatis 缓存
-
作用:提高应用查询效率
-
查找顺序:
- 二级开启,从二级缓存找
- 二级缓存未开启,从一级缓存(Map)查找
一级缓存
- 特点:
- 同一个会话(SqlSession)
- 默认开启
- 基于内存存储
- 关闭会话,一级缓存数据被清除或者显式调用清空缓存方法
二级缓存
- 特点:
- 同一个namespace, 进程缓存
- 基于内存+硬盘
- 默认不开启,需要手动开启
- 二级缓存实现:Mybatis 框架内部实现 | 第三方实现(分布式Ehcache)