提交mybatis使用

This commit is contained in:
qiurunze 2019-01-21 16:39:28 +08:00
parent 010f9fe55e
commit dfcdf0b0a9
12 changed files with 329 additions and 15 deletions

View File

@ -15,7 +15,7 @@
[![Travis](https://img.shields.io/badge/language-Java-yellow.svg)](https://github.com/qiurunze123)
高并发大流量如何进行秒杀架构我对这部分知识做了一个系统的整理写了一套系统。本GitHub还有许多其他的知识随时欢迎探讨与骚扰本文还在更新如果文章出现瑕疵请及时与我联系
文章还有许多不足,我仍在不断改进!如果你本地没有这些环境,可以先找我要我的阿里云地址,看效果! ps: 本文章基础思路来自于若鱼1919老师大家可以关注老师的课和博客很不错,老师很nice 谢谢大家
文章还有许多不足,我仍在不断改进!如果你本地没有这些环境,可以先找我要我的阿里云地址,看效果! ps: 本文章基础思路来自于若鱼1919老师大家可以关注老师的课和博客很不错,老师很nice 谢谢大家 课程地址https://coding.imooc.com/class/168.html
一点小建议:学习本系列知识之前,如果你完全没接触过 `MQ`、`SpringBoot`、`Redis`、`Dubbo`、`ZK` 、`Maven`,`lua`等,那么我建议你可以先在网上搜一下每一块知识的快速入门,
也可以下载本项目边做边学习,我的项目完全是实战加讲解不想写一堆的文章,浪费我们的生命,你还不懂内层含义,想要明白就边实际操作边学习,效果会更好!加油💪💪

View File

@ -2,9 +2,90 @@
有问题或者宝贵意见联系我的QQ,非常希望你的加入!
> mybatis 使用
> mybatis 使用总结
#### resultType 和 resultMap
MyBatis的每一个查询映射的返回类型都是ResultMap
只是当我们提供的返回类型属性是resultType的时候MyBatis对自动的给我们把对应的值赋给resultType所指定对象的属性
而当我们提供的返回类型是resultMap的时候将数据库中列数据复制到对象的相应属性上可以用于复制查询两者不能同时用。
而当我们提供的返回类型是resultMap的时候将数据库中列数据复制到对象的相应属性上可以用于复制查询两者不能同时用。
#### typeAliases类型命名
存在的意义在于减少类的完全限定名的冗余
_user可以用在任何需要com.geekq.miaosha.mybatis.User
### 当实体类中的属性名和表中的字段名不一致时使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法
解决办法一: 通过在查询的sql语句中定义字段名的别名让字段名的别名和实体类的属性名一致
这样就可以表的字段名和实体类的属性名一一对应上了这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的
解决办法二: 通过<resultMap>来映射字段名和实体类属性名的一一对应关系。
这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。
### 为什么order by 要用${xxx} 而不用 #{}
对于形如#{variable}
的变量Mybatis会将其视为字符串值在变量替换成功后缺省地给变量值加上引号。"variable"
2对于形如${variable}的变量Mybatis会将其视作直接变量即在变量替换成功后不会再给其加上引号。
variable
所以在动态sql中#{variable}
需要去掉 ""比如正常sql赋值一般是这样的and name= #{name},因为是=赋值,所以会获取内容,去掉""
${variable}可以直接使用,比如order
by ${name} 传入的直接是name不带双引号可以直接使用
并且order
by不是 =赋值所以如果直接order by #{name}结果是order
by "name",自然无法执行了
### 如何打印sql日志 ?
xml方式
<setting name="lazyLoadTriggerMethods" value="clone"/>
<!-- 打印查询语句 打印mybatis日志-->
<setting name="logImpl" value="STDOUT_LOGGING" />
配置方式:
#打印mybatis sql
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.Java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
### 动态sql标签
if
choose (when, otherwise)
trim (where, set)
foreach
### 如何使用mybatis-generator:generate
pom 配置:
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
</dependencies>
</plugin>
![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/mybatis1.png)
![使用](https://raw.githubusercontent.com/qiurunze123/imageall/master/mybatis2.png)
### generatorConfig.xml 内容解析?
已在其中备注,详细内容请见generatorConfig.xml
### generatorConfig.xml 内容解析?

19
pom.xml
View File

@ -175,7 +175,22 @@
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>false</overwrite>
</configuration>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.21</version>
</dependency>
</dependencies>
</plugin>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
@ -193,6 +208,8 @@
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/java</directory>

View File

@ -44,9 +44,9 @@ public class AccessInterceptor extends HandlerInterceptorAdapter{
logger.info("打印拦截方法handler {} ",handler);
HandlerMethod hm = (HandlerMethod)handler;
//方便mybatis 测试
if(hm.getMethod().getName().startsWith("test")){
return true;
}
// if(hm.getMethod().getName().startsWith("test")){
// return true;
// }
MiaoshaUser user = getUser(request, response);
UserContext.setUser(user);
AccessLimit accessLimit = hm.getMethodAnnotation(AccessLimit.class);

View File

@ -2,6 +2,7 @@ package com.geekq.miaosha.mybatis.Mapper;
import com.geekq.miaosha.mybatis.entity.User;
import com.geekq.miaosha.mybatis.vo.TeacherVo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.omg.CORBA.INTERNAL;
@ -36,4 +37,8 @@ public interface UserMapper {
*/
public List<User> getUserListMap(@Param("id") Integer id , @Param("name") String name);
public List<TeacherVo> getTeacherAndUser( @Param("uId") Integer uId );
public List<TeacherVo> getTeacherAndUserList( @Param("uId") List<Integer> uId );
}

View File

@ -3,6 +3,7 @@ package com.geekq.miaosha.mybatis.controller;
import com.geekq.miaosha.access.AccessLimit;
import com.geekq.miaosha.mybatis.Mapper.UserMapper;
import com.geekq.miaosha.mybatis.entity.User;
import com.geekq.miaosha.mybatis.vo.TeacherVo;
import com.geekq.miaosha.redis.KeyPrefix;
import com.geekq.miaosha.redis.RedisService;
import org.apache.commons.lang3.StringUtils;
@ -18,6 +19,7 @@ import org.thymeleaf.spring4.view.ThymeleafViewResolver;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
@Controller
@ -73,4 +75,30 @@ public class UbatisController {
int result = userMapper.delete(2 );
System.out.println(result);
}
/**
* 测试多表联合查询
*/
@RequestMapping(value = "/testTandU", produces = "text/html")
@ResponseBody
public void testTandU(){
List<TeacherVo> teacherAndUser = userMapper.getTeacherAndUser(1 );
System.out.println(teacherAndUser.size());
}
/**
* 测试多表联合查询 in
*/
@RequestMapping(value = "/testTandUIn", produces = "text/html")
@ResponseBody
public void testTandUIn(){
List<Integer> list = new ArrayList<Integer>();
list.add(1);
list.add(2);
List<TeacherVo> teacherAndUser = userMapper.getTeacherAndUserList(list );
System.out.println(teacherAndUser.size());
}
}

View File

@ -1,4 +1,4 @@
package com.geekq.miaosha.mybatis;
package com.geekq.miaosha.mybatis.vo;
import lombok.Getter;
import lombok.Setter;
@ -8,11 +8,16 @@ import java.io.Serializable;
@Setter
@Getter
public class TeacherVo implements Serializable {
private Integer cid ;
private String cName;
private String uId;
private String teacherId ;
private String tId ;
private String tName ;
private String name;
private Integer age ;
private String address ;
}

View File

@ -9,18 +9,33 @@ spring.thymeleaf.mode=HTML5
#是否开启缓存
pageCache.enbale=true
#打印mybatis sql
log4j.logger.com.ibatis=DEBUG
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.Java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
#mybatis
mybatis.type-aliases-package=com.geekq.miaosha.domain
#开启驼峰转换
#开启驼峰转换 configuration config-location 不能同時存在 如果要走流程 请 放开注释
mybatis.configuration.map-underscore-to-camel-case=true
#mybatis.mapperLocations = classpath:com/geekq/miaosha/dao/*.xml
mybatis.mapperLocations=classpath:mybatis/mapper/*.xml
#配置xml方式 因为与 mybatis.configuration.map-underscore-to-camel-case 仅用于测试
#mybatis.config-location=classpath:mybatis/mybatis-config.xml
#add mybatis
mybatis.config-locations=classpath:mybatis/conf.xml
mybatis.
#datasource
spring.datasource.url=jdbc:mysql://localhost:3306/miaosha?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.dataource.password=nihaoma
spring.datasource.password=nihaoma
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
#druid
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

View File

@ -0,0 +1,92 @@
<?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>
<context id="mysql" defaultModelType="hierarchical"
targetRuntime="MyBatis3Simple">
<!-- 自动识别数据库关键字默认false如果设置为true根据SqlReservedWords中定义的关键字列表 一般保留默认值遇到数据库关键字Java关键字使用columnOverride覆盖 -->
<property name="autoDelimitKeywords" value="false" />
<!-- 生成的Java文件的编码 -->
<property name="javaFileEncoding" value="UTF-8" />
<!-- 格式化java代码 -->
<property name="javaFormatter"
value="org.mybatis.generator.api.dom.DefaultJavaFormatter" />
<!-- 格式化XML代码 -->
<property name="xmlFormatter"
value="org.mybatis.generator.api.dom.DefaultXmlFormatter" />
<!-- beginningDelimiter和endingDelimiter指明数据库的用于标记数据库对象名的符号比如ORACLE就是双引号MYSQL默认是`反引号; -->
<property name="beginningDelimiter" value="`" />
<property name="endingDelimiter" value="`" />
<commentGenerator>
<property name="suppressDate" value="true" />
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!-- 必须要有的,使用这个配置链接数据库 @TODO:是否可以扩展 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/miaosha" userId="root" password="nihaoma">
<!-- 这里面可以设置property属性每一个property属性都设置到配置的Driver上 -->
</jdbcConnection>
<!-- java类型处理器 用于处理DB中的类型到Java中的类型默认使用JavaTypeResolverDefaultImpl 注意一点默认会先尝试使用IntegerLongShort等来对应DECIMAL和
NUMERIC数据类型 -->
<javaTypeResolver
type="org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl">
<!-- true使用BigDecimal对应DECIMAL和 NUMERIC数据类型 false默认, scale>0;length>18使用BigDecimal;
scale=0;length[10,18]使用Long scale=0;length[5,9]使用Integer scale=0;length<5使Short -->
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- java模型创建器是必须要的元素 负责1key类见context的defaultModelType2java类3查询类
targetPackage生成的类要放的包真实的包受enableSubPackages属性控制 targetProject目标项目指定一个存在的目录下生成的内容会放到指定目录中如果目录不存在MBG不会自动建目录 -->
<javaModelGenerator targetPackage="com.geekq.miaosha.mybatis.entity"
targetProject="src/main/java">
<!-- for MyBatis3/MyBatis3Simple 自动为每一个生成的类创建一个构造方法构造方法包含了所有的field而不是使用setter -->
<property name="constructorBased" value="false" />
<!-- for MyBatis3 / MyBatis3Simple 是否创建一个不可变的类如果为true 那么MBG会创建一个没有setter方法的类取而代之的是类似constructorBased的类 -->
<property name="immutable" value="false" />
<!-- 设置是否在getter方法中对String类型字段调用trim()方法 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- 生成SQL map的XML文件生成器 注意在Mybatis3之后我们可以使用mapper.xml文件+Mapper接口或者不用mapper接口
或者只使用Mapper接口+Annotation所以如果 javaClientGenerator配置中配置了需要生成XML的话这个元素就必须配置
targetPackage/targetProject:同javaModelGenerator -->
<sqlMapGenerator targetPackage="com.geekq.miaosha.mybatis.Mapper"
targetProject="src/main/java">
<!-- 在targetPackage的基础上根据数据库的schema再生成一层package最终生成的类放在这个package下默认为false -->
<property name="enableSubPackages" value="true" />
</sqlMapGenerator>
<!-- 对于mybatis来说即生成Mapper接口注意如果没有配置该元素那么默认不会生成Mapper接口 targetPackage/targetProject:同javaModelGenerator
type选择怎么生成mapper接口在MyBatis3/MyBatis3Simple下 1ANNOTATEDMAPPER会生成使用Mapper接口+Annotation的方式创建SQL生成在annotation中不会生成对应的XML
2MIXEDMAPPER使用混合配置会生成Mapper接口并适当添加合适的Annotation但是XML会生成在XML中 3XMLMAPPER会生成Mapper接口接口完全依赖XML
注意如果context是MyBatis3Simple只支持ANNOTATEDMAPPER和XMLMAPPER -->
<javaClientGenerator targetPackage="com.geekq.miaosha.mybatis.Mapper"
type="XMLMAPPER" targetProject="src/main/java">
<!-- 在targetPackage的基础上根据数据库的schema再生成一层package最终生成的类放在这个package下默认为false -->
<property name="enableSubPackages" value="true" />
<!-- 可以为所有生成的接口添加一个父接口但是MBG只负责生成不负责检查 <property name="rootInterface"
value=""/> -->
</javaClientGenerator>
<table tableName="goods">
<!-- 参考 javaModelGenerator 的 constructorBased属性 -->
<property name="constructorBased" value="false" />
<generatedKey column="id" sqlStatement="JDBC" />
</table>
</context>
</generatorConfiguration>

View File

@ -2,6 +2,9 @@
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<typeAliases>
<typeAlias alias="user" type="com.geekq.miaosha.mybatis.entity."/>
</typeAliases>
<!-- 为实体类me.gacl.domain.User配置一个别名_User -->
<!-- <typeAlias type="me.gacl.domain.User" alias="_User"/> -->

View File

@ -7,12 +7,18 @@ userMapper(userMapper.xml文件去除后缀)保证唯一性
<mapper namespace="com.geekq.miaosha.mybatis.Mapper.UserMapper">
<!-- 在select标签中编写查询的SQL语句 设置select标签的id属性为getUserid属性值必须是唯一的不能够重复
使用parameterType属性指明查询时使用的参数类型resultType属性指明查询返回的结果集类型
resultType="me.gacl.domain.User"就表示将查询结果封装成一个User类的对象返回
resultType="com.geekq.uMybatis.mapping.User"就表示将查询结果封装成一个User类的对象返回
User类就是users表所对应的实体类
-->
<!--
根据id查询得到一个user对象
-->
<!--当实体类中的属性名和表中的字段名不一致时
使用MyBatis进行查询操作时无法查询出相应的结果的问题以及针对问题采用的两种办法-->
<!--  解决办法一: 通过在查询的sql语句中定义字段名的别名让字段名的别名和实体类的属性名一致
这样就可以表的字段名和实体类的属性名一一对应上了这种方式是通过在sql语句中定义别名来解决字段名和属性名的映射关系的。-->
<!--  解决办法二: 通过<resultMap>来映射字段名和实体类属性名的一一对应关系。
这种方式是使用MyBatis提供的解决方式来解决字段名和属性名的映射关系的。-->
<resultMap type="com.geekq.miaosha.mybatis.entity.User" id="userResultMap">
<!-- id表示查询结果集中唯一标识 column:查询出的列名
property:type所指定的POJO中的属性名
@ -25,6 +31,22 @@ userMapper(userMapper.xml文件去除后缀)保证唯一性
<result column="_address" property="address"/>
</resultMap>
<resultMap type="com.geekq.miaosha.mybatis.vo.TeacherVo" id="TandUResultMap">
<!-- id表示查询结果集中唯一标识
column:查询出的列名
property:type所指定的POJO中的属性名
最终reslutMap对column和property做一个映射关系(对应关系)
-->
<id column="u_id" property="uId"/>
<!-- 对普通列的映射定义 -->
<result column="t_id" property="tId"/>
<result column="t_name" property="tName"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="_address" property="address"/>
</resultMap>
<sql id="base_column">
id,name,age,_address
</sql>
@ -56,6 +78,22 @@ userMapper(userMapper.xml文件去除后缀)保证唯一性
</if>
</select>
<select id="getTeacherAndUser" resultMap="TandUResultMap">
select * from users u, teacher t where u.id = t.u_id and t.u_id=#{uId}
</select>
<select id="getTeacherAndUserList" resultMap="TandUResultMap">
select * from users u, teacher t where u.id = t.u_id and t.u_id in
<!--<foreach item="item" collection="list" separator=",">-->
<!--(#{item.username}, #{item.password}, #{item.email}, #{item.bio})-->
<!--</foreach>-->
<foreach collection="uId" close=")" open="(" item="item" separator=",">
#{item}
</foreach>
</select>
<!-- 插入自动递增-->
<insert id="insert" parameterType="com.geekq.miaosha.mybatis.entity.User"

View File

@ -0,0 +1,30 @@
<?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">
<!-- mybatis的配置 -->
<configuration>
<!-- 配置mybatis的默认运行模式 -->
<settings>
<!-- 全局启用或禁用延迟加载。当禁用时, 所有关联对象都会即时加载。 开启延迟加载,设置为true -->
<setting name="lazyLoadingEnabled" value="true"/>
<!-- 按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
<!-- 配置哪些方法会触发所有延迟加载对象加载 -->
<setting name="lazyLoadTriggerMethods" value="clone"/>
<!-- 打印查询语句 打印mybatis日志-->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!--<typeAliases>-->
<!--<typeAlias alias="_user" type="com.geekq.miaosha.mybatis.entity.User"/>-->
<!--</typeAliases>-->
<!--<mappers>-->
<!--<mapper resource="com.geekq.miaosha.mybatis.Mapper.UserMapper"/>-->
<!--</mappers>-->
</configuration>