概述
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的ORM持久层框架
MyBatis 消除了几乎所有的 JDBC 代码,参数的手动设置以及结果集的检索
MyBatis 使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
ORM(Object/Ralational Mapping)即对象/关系映射。是一种数据持久化技术,它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据,不同的持久层框架ORM是不同的
持久化:即把数据保存到可永久保存的存储设备中(如磁盘,数据库等)
持久层:dao/mapper层就是持久层
核心接口和类
每个MyBatis的应用程序都以一个SqlSessionFactory对象的实例为核心
首先获取SqlSessionFactorBuilder对象,可以根据XML配置文件或Configuration类的实例构建该对象
然后获取SqlSessionFactory对象,该对象实例可以通过SqlSessionFactoryBuilder对象来获得
最后获取SqlSession实例,SqlSession对象中完全包含以数据库为背景的所有执行SQL操作的方法,可以用该实例来直接执行已映射的SQL语句
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且提供了多个build()方法的重载
配置信息可以以三种形式提供给SqlSessionFactoryBuilder的build()方法,InputStream(字节流)、Reader(字符流)、Configuration(类)
InputStream inputStream= Resources.getResourceAsStream(“mybatis/mybatis.xml”);
SqlSessionFactoryBuilder的最大特点:用过即丢。一旦创SqlSessionFactory对象之后,这个类就不需要存在了,因此SqlSessionFactoryBuilder的最佳范围就是存在于方法体内,也就是局部变量而已
SqlSessionFactory
SqlSessionFactory提供的openSession()方法来获取SqlSession的实例
openSession()方法的参数为boolean值时,若传入为true表示关闭事务控制,自动提交;false表示开始事务控制,若不传参,默认为true
SqlSessionFactory对象一旦创建,就会在整个应用运行过程中始终存在,没有理由去销毁或再创建它,并且再应用运行中也不建议多次创建SqlSessionFactory。因此SqlSessionFactory的最佳作用域是Application,即随着应用的生命周期一同存在,那么这种存在于整个应用运行期间,并且同时只有一个对象实例的模式称之为单例模式
SqlSession
SqlSession是用于执行持久化操作的对象,类似于JDBC中的Connection。它提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句
SqlSession对应着一次数据库会话。由于数据库会话不是永久的,因此SqlSession的生命周期也不应该是永久的,相反,再每一次访问数据库都需要创建它(这里并不是说SqlSession只能执行一次SQL,SqlSession完全可以执行多次,但是若关闭了SqlSession,那么就需要重新创建它),创建SqlSession的地方只有一个,那就是SqlSessionFactory对象的openSession()方法
每个线程都有自己的SqlSession实例,SqlSession实例不能被共享,也不是线程安全的。因此最佳的作用域范围是request作用域或者方法体作用域内
使用方式
1.通过SqlSession实例来直接执行已映射的SQL语句
2.基于mapper接口方式操作数据
操作步骤
读取配置文件
InputStream inputStream= Resources.getResourceAsStream(“mybatis/mybatis.xml”);
获取一个工厂类
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(inputStream);
获取一个sqlSession会话
SqlSession session = factory.openSession();
获取Mapper的接口对象
接口类型 对象名 = session.getMapper(接口类.class);
调用接口中的方法
事务提交
关闭会话
注释
< select id = " selectUser" resultType = " com.xl.entity.UserEntity" >
SELECT
/* SQL中的注释:采用SQL多行注释 */
id, name, status
FROM
users
select>
MyBatis核心(全局)配置文件(mybatis-config.xml)
MyBatis 的配置文件包含了影响 MyBatis 行为的设置(settings)和属性(properties)信息
:配置文件的根元素节点,子元素需按顺序书写
:配置属性文件
resource属性:外部指定properties属性文件
使用不在一个地方配置执行顺序为
在 properties 元素体内指定的属性首先被读取
然后根据 properties 元素中的 resource 属性读取全类名下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性
最后读取作为方法参数传递的属性,并覆盖已读取的同名属性
:设置MyBatis运行中的全局行为
name:属性名
cacheEnabled:对在此配置文件下的所有cache二级缓存进行全局性开关设置,默认true
lazyLoadingEnabled:全局性设置懒加载,默认true,如果设为fasle,则所有相关联的都会被初始化加载
autoMappingBehavior:MyBatis对于自动映射的匹配级别为 NONE|PARTIAL|FULL
NUNE:禁止自动匹配
PARTIAL:默认。自动匹配所有属性(要求是列名和javaBean属性名一致),有内部嵌套(association,collection)的除外
FULL:自动匹配所有
aggressivelazyLoading:属性按需加载
value:属性值
:为Java类型命名别名(别名处理器)
alias:别名
type:实体类全类名
也可@Alias注解为其指定一个别名
MyBatis已经为许多常见的 Java 类型内建了相应的类型别名。它们都是大写不敏感的,我们在起别名的时候千万不要占用已有的别名
:类型处理器
无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型
:插件
插件通过动态代理机制,可以介入四大对象的任何一个方法的执行
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
:配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,该元素节点下可以配置多个environment子元素节点,但是必须指定其中一个默认运行环境(通过default指定)
:配置MyBatis的一套运行环境,
id:指定当前环境的唯一标识
:事务管理
type:MyBatis有两种事物管理类型,即JDBC、MANAGED
设置其属性为JDBC,直接使用JDBC的提交和回滚功能,依赖于从数据源获得来连接来管理事务的生命周期
MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期
可自定义事物管理类型:实现TransactionFactory接口,type=全名/别名
:数据源(库)配置
type:有三种数据源类型(UNPOOLED、POOLED、JNDI)
UNPOOLED:不使用连接池
POOLED:使用连接池
JNDI: 在EJB 或应用服务器这类容器中查找指定的数据源
自定义:实现DataSourceFactory接口,定义数据源的获取方式
:根据不同的数据库厂商执行不同的语句
type:DB_VENDOR //使用MyBatis提供的VendorDatabaseIdProvider解析数据库厂商标识。也可以实现DatabaseIdProvider接口来自定义
会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置。由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短
Property-name:数据库厂商标识
Property-value:为标识起一个别名,方便SQL语句使用databaseId属性引用
匹配规则
如果没有配置databaseIdProvider标签,那么databaseId=null
如果配置了databaseIdProvider标签,使用标签配置的name去匹配数据库信息,匹配上设置databaseId=配置指定的值,否则依旧为null
如果databaseId不为null,他只会找到配置databaseId的sql语句
MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库databaseId 属性的所有语句。如果同时找到带有 databaseId 和不带databaseId 的相同语句,则后者会被舍弃
:映射器作用是告诉MyBatis去哪里找到SQL映射文件(该文件内容是开发者定义的映射SQL语句),整个项目可以有一个或多个SQL映射文件
:获取SQL映射文件
resource:使用类资源路径获取资源
class:使用全类名获取,要求接口和映射文件同包同名
url:使用URL获取资源
:批量获取映射文件
name:文件所在包名 //要求接口和映射文件同包同名
SQL映射文件(mapper.xml)
映射文件指导着MyBatis如何进行数据库增删改查
//映射文件的根元素节点,只有一个属性namespace
namespace:用于区分不同的mapper,全局唯一,绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后(一个接口对应一个映射文件),可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句,因此namespace的属性值必须要和接口同名
//映射插入语句 //映射更新语句 //映射删除语句
id:命名空间的唯一识别符,可以被用来引用这条语句,与接口中的方法名一致
parameterType:参数类型,可不传MyBatis会根据TypeHandler自动推断
flushCache:有语句被调用,会导致本地缓存和二级缓存被清空,默认为true
timeout:在抛出异常前,驱动程序等待数据库返回请求结果的秒数,默认为unset
statementType:默认为PREPARED映射类型,也可设置为STATEMENT映射类型,CALLABLE映射类型
useGeneratedKeys:MyBatis 使用 JDBC 中的 getGeneratedKeys 方法来取出由数据库内部生成的主键(MySQL),默认为false,delete中无效
keyProperty:指定能够唯一识别对象的属性,MyBatis通过getGeneratedKeys方法的返回值或insert语句的selectKey子元素设置它的键值,默认为unset,delete中无效
keyColumn:通过生成的键值设置表中列名,当主键列不是表中的第一列时需设置,在某些数据库(PostgreSQL)是必须的,delete中无效
databaseId:与的value值对应,若配置了databaseIdProvider,MyBatis会加载所有不带databaseId或匹配当前databaseId的语句,如果带或者不带都有,则不带的会被忽略
//为语句传参
KeyProperty:selectKey语句结果应该被设置的目标属性
KeyColumn:匹配属性的返回结果集中的列名称
resultType:结果的类型
order:设置为BEFORE,表示先执行selectKey中的语句,设置为AFTER,表示先执行外层语句
statementType:默认为PREPARED映射类型,也可设置为STATEMENT映射类型,CALLABLE映射类型
#{key}:获取参数的值,预编译到SQL中,安全,类似JDBC的PreparedStatement可防止SQL注入,返回字符串带引号 ‘’
${key}:获取参数的值,拼接到SQL中,有SQL注入问题
//映射查询语句,标签内些查询语句
id:命名空间的唯一识别符,可以被用来引用这条语句
parameterType:参数类型,可不传MyBatis会根据TypeHandler自动推断
resultType:返回值类型,resultType和resultMap不能同时存在,二取其一
resultMap:对外部resultMap的引用,对应外部resultMap的id,表示返回结果映射到哪一个resultMap上,它的应用场景一般是数据库字段与对象属性不一致或者需要做复杂的联合查询以便自由控制映射结果
flushCache:表示任何时候语句被调用,都不会去清空本地缓存和二级缓存,默认为false
useCache:是否开启二级缓存,默认为true
timeout:在抛出异常前,驱动程序等待数据库返回请求结果的秒数,默认为unset
fetchSize:给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值,默认为unset(依赖驱动)
statementType:默认为PREPARED映射类型,也可设置为STATEMENT映射类型,CALLABLE映射类型
resultSetType:FORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)
databaseId:与上一个标签databaseId意义相同
resultOrdered:这个设置仅针对嵌套结果 select 语句:如果为 true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。 这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false
resultSets:这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔
//导入中的SQL块
//可以重用的SQL块,被其他语句引用(include来引用)
id:引用标识
可为sql语句片段或完整语句,也可为动态sql语句
//用来描述数据库结果集和对象的对应关系
id:中resultMap的id名称
type:需要映射到的类对象
如果设置这个属性,MyBatis 将会为本结果映射开启或者关闭自动映射。 这个属性会覆盖全局的属性 autoMappingBehavior。默认值:未设置(unset)
//将查询结果作为参数注入到实例的构造方法中
//设置主键(可多个)
column:数据表的列,使用{key1=column1,key2=column2…}的形式传递多列数据
property:将column属性指定的列结果映射到对象的哪个属性
javaType:实体类中字段类型
jdbcType:表中字段类型
//配置映射关系
column:数据表的列
property:将column属性指定的列结果映射到对象的哪个属性
javaType:实体类中字段类型
jdbcType:表中字段类型
//处理查询结果中关联其他对象的情况,映射JavaBean的某个复杂类型的属性
fetchType:eager立即加载/lazy延迟加载
columnPrefix:祛除查询结果内列名的指定前缀
javaType:完整的Java类名或者别名,若映射带一个JavaBean,则MyBatis通常会自行检测到其他类型,若映射到一个HashMap,则应该明确指定javaType
嵌套查询方式(分段查询) //指的是通过执行另外一个 SQL 映射语句来返回所关联的对象类型
column:指定数据表的列
property:将column属性指定的列结果映射到对象的哪个属性
select:调用查询当前属性的值
嵌入结果集方式 //指的是通过联表查询将所需的所有字段内容先查询出来,再通过级联属性映射来创建复杂类型的结果对象
property:映射到列结果的字段或属性
javaType:完整的Java类名或者别名
resultMap:引用外部resultMap
//设置主键
//配置映射关系
//处理查询结果中关联其他对象的情况,返回复杂类型的集
fetchType=eager立即加载/lazy延迟加载
嵌套查询方式(分步查询)
column:指定数据表的列
property:映射到列结果的字段或属性
select:调用目标的方法查询当前属性的值
javaType:完整的Java类名或者别名
嵌入结果集方式
column:指定数据表的列
property:映射到列结果的字段或属性
javaType:完整的Java类名或者别名
ofType:完整的Java类名或者别名,即集合中包含的类型(可不写)
//设置主键
//配置映射关系
鉴别器//很像Java语言中的switch 语句,允许用户根据查询结果中指定字段的不同取值来执行不同的映射规则
column:数据表的列
//基于某些值的结果映射
value :查询结果中指定字段的不同取值
resultMap:外部映射规则名
resultType:内部写映射规则
//配置给定命名空间的二级缓存
eviction:缓存的回收策略
LRU – 最近最少使用的:移除最长时间不被使用的对象(默认)
FIFO – 先进先出:按对象进入缓存的顺序来移除它们
SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象
WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
flushInterval:缓存刷新间隔(缓存多长时间清除一次,默认不清空)毫秒为单位
readOnly:缓存是否只读,默认false
true:MyBatis认为所有从缓存中读取数据库的操作都是只读操作不会修改数据,为加快获取速度,直接会将数据在缓存中的引用交给用户
MyBatis觉得获取的数据可修改,MyBatis会利用序列化&反序列的技术克隆一份新的数据给你
size:缓存存放多少元素
type:指定第三方或自定义缓存的全类名,常见第三方缓存EHCache,Redis,Memcache,需导入jar包与配置文件
//从其它命名空间引入缓存配置
主键生成方式
若数据库支持自动生成主键的字段,则可以设置useGeneratedKeys=”true”,然后再把keyProperty 设置到目标属性上
若数据库不支持自增型主键,则可以使用 selectKey 子元素:selectKey 元素将会首先运行,id 会被设置,然后插入语句会被调用
参数处理
单个参数
可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数,不需要经过任何处理
多个参数
任意多个参数,都会被MyBatis重新包装成一个Map传入
接口中方法参数只能有一个
parameterType=“Integer[]” 接收数组
使用@Param(“参数名”)为参数命名,key指定
POJO
当这些参数属于我们业务POJO时,我们直接传递POJO
#{}拓展用法:参数也可以指定一个特殊的数据类型
#{property,javaType=double,jdbcType=NUMERIC,numericScale=2}
参数位置支持的属性:javaType、jdbcType、mode(存储过程)、numericScale、resultMap、typeHandler、jdbcTypeName、expression
javaType:通常可以从参数对象中来去确定
jdbcType:通常需要在某种特定的条件下被设置,在我们数据为null的时候,有些数据库可能不能识别myBatis对null的默认处理,比如Oracle
numericScale:设置小数点后保留位数
mode:属性允许指定 IN,OUT 或 INOUT 参数。如果参数为 OUT 或 INOUT,参数对象属性的真实值将会被改变,就像在获取输出参数时所期望的那样
MyBatis两个内置参数
_parameter:代表整个参数
单个参数:_parameter就是这个参数
多个参数:参数会被封装成一个map,_parameter就是代表这个map
_databaseId:如果配置了DateBaseIdProvider标签,_databaseId代表当前数据库的别名
动态SQL
动态 SQL是MyBatis强大特性之一。极大的简化我们拼装SQL的操作
动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似
MyBatis 采用功能强大的基于 OGNL 的表达式来简化操作
OGNL对象图导航语言,这是一种强大的表达式语言,通过它可以非常方便的来操作对象属性。 类似于EL,SpEL等
访问对象属性:person.name
调用方法:person.getName()
调用静态属性/方法:@java.lang.Math @PI @java.util.UUID @randomUUID()
调用构造方法:new com.bean.Person(‘admin’).name
运算符:+,-*,/,%
逻辑运算符:in,not in,>,>=,<,<=,==,!=
xml中特殊符号如”,>,<等这些都需要使用转义字符
特殊符号 转义字符
& & amp;
< & lt;
> & gt;
" & quot;
' & apos;
a<= b a & lt; = b 或者 a < ! [ CDATA [ <= ] ] > b
a>= b a & gt; = b 或者 a < ! [ CDATA [ >= ] ] > b
a!= b a < ! [ CDATA [ < > ] ] > b 或者 a < ! [ CDATA [ != ] ] > b
简化SQL中的where,如果有条件,条件的第一个and或者or会自动取消,如果无条件,where关键字会取消.
< update id= "updateEmp" >
update tbl_employee
< set>
< if test= "lastName!=null" >
last_name= #{ lastName} ,
< / if >
< if test= "email!=null" >
email= #{ email} ,
< / if >
< if test= "gender!=null" >
gender= #{ gender} ,
< / if >
UPDATE_DATE = SYSDATE
< ! -- set语句之后一定别忘记加逗号-- >
< / set>
where id= #{ id}
< / update>
< select id= "getEmpsByConditionIf" resultType= "com.mybatis.bean.Employee" >
select * from tbl_employee
< where>
< ! --
遇见特殊符号应写转义字符或写在< ! [ CDATA [ ] ] > 区间内(语句前加空格)
-- >
< if test= "id=='0'.toString()" > < ! -- 转换-- >
and id= #{ id}
< / if >
< if test= "lastName!=null && lastName!=""" >
and last_name like #{ lastName}
< / if >
< if test= "email!=null and email.trim()!=""" >
and email= #{ email}
< / if >
< ! -- ognl会进行字符串与数字的转换判断 "0" == 0 -- >
< if test= "gender==0 or gender==1" >
and gender= #{ gender}
< / if >
< / where>
< / select>
,,
< select id= "getEmpsByConditionChoose" resultType= "com.mybatis.bean.Employee" >
select * from tbl_employee
< where>
< ! -- 如果带了id就用id查,如果带了lastName就用lastName查; 只会进入其中一个 -- >
< choose>
< when test= "id!=null" >
id= #{ id}
< / when>
< when test= "lastName!=null" >
last_name like #{ lastName}
< / when>
< when test= "email!=null" >
email = #{ email}
< / when>
< otherwise>
gender = 0
< / otherwise>
< / choose>
< / where>
< / select>
< select id= "getEmpsByConditionTrim" resultType= "com.mybatis.bean.Employee" >
select * from tbl_employee
< ! -- 后面多出的and或者or where标签不能解决
prefix= "" : 前缀:trim标签体中是整个字符串拼串后的结果。
prefix给拼串后的整个字符串加一个前缀
prefixOverrides= "" :
前缀覆盖: 去掉整个字符串前面多余的字符
suffix= "" : 后缀
suffix给拼串后的整个字符串加一个后缀
suffixOverrides= ""
后缀覆盖:去掉整个字符串后面多余的字符
-- >
< ! -- 自定义字符串的截取规则 -- >
< trim prefix= "where" suffixOverrides= "and" >
< if test= "id!=null" >
id= #{ id} and
< / if >
< if test= "lastName!=null && lastName!=""" >
last_name like #{ lastName} and
< / if >
< if test= "email!=null and email.trim()!=""" >
email= #{ email} and
< / if >
< ! -- ognl会进行字符串与数字的转换判断 "0" == 0 -- >
< if test= "gender==0 or gender==1" >
gender= #{ gender}
< / if >
< / trim>
< / select>
< select id= "getEmpsByConditionForeach" resultType= "com.mybatis.bean.Employee" >
select * from tbl_employee
< ! --
collection:指定要遍历的集合:list类型的参数会特殊处理封装在map中,map的key就叫list
item:将当前遍历出的元素赋值给指定的变量
separator: 每个元素之间的分隔符
open :遍历出所有结果拼接一个开始的字符
close: 遍历出所有结果拼接一个结束的字符
index: 索引。遍历list的时候是index就是索引,item就是当前值
遍历map的时候index表示的就是map的key,item就是map的值
#{ 变量名} 就能取出变量的值也就是当前遍历出的元素
-- >
< foreach collection= "ids" item= "item_id" separator= "," open = "where id in(" close= ")" >
#{ item_id}
< / foreach>
< / select>
示例:
List < ForDownZip > oneDownFun ( List < String > bizKeysList) ;
< foreach collection= "list" item= "bizKeysList" open = "(" separator= "," close= ")" >
#{ bizKeysList}
< / foreach>
List < ForDownZip > oneDownFun ( @Param ( "comCodeList" ) List < String > comCodeList) ;
< foreach collection= "comCodeList" item= "comCode" open = "(" separator= "," close= ")" >
#{ comCode}
< / foreach>
可以将OGNL表达式的值绑定到一个变量中,方便后来引用这个变量的值
< select id= "getEmpsTestInnerParameter" resultType= "com.mybatis.bean.Employee" >
< bind name= "_lastName" value= "'%'+lastName+'%'" / >
select * from emp where last_name like #{ _lastName}
< / select>
OGNL 表达式:
e1 or e2
e1 and e2
e1 == e2, e1 eq e2
e1 != e2, e1 neq e2
e1 lt e2:小于
e1 lte e2:小于等于,其他gt(大于), gte(大于等于) 7 e1 in e2
e1 in e2
e1 not in e2
e1 + e2, e1 * e2, e1/ e2, e1 - e2, e1% e2
! e, not e:非,求反
e. method ( args) 调用对象方法
e. property对象属性值
e1[ e2 ] 按索引取值,List , 数组和Map
@class @method ( args) 调用类的静态方法
@class @field 调用类的静态字段值
< ! --
sql片段 解决SQL 中重复的代码冗余,可以提取出来放在sql片段中
1. < sql> 定义sql片段
id 唯一标识
2. < include> 在SQL 中引用SQL 片段片段
refid 需要引用的SQL 片段的id
< property 声明变量, 就可以在SQL 片段中动态调用,让不同的SQL 调用同一个SQL 片段达到不同的功能
name 变量名
value 变量值
一般情况使用${ } 在sql片段中引用. 一单引用了,一定保证每个include都声明了该变量
-- >
< sql id= "selectEmp" >
select ${ columns} from emp
< / sql>
< select id= "QueryEmp4" resultType= "Emp" >
< include refid= "selectEmp" >
< property name= "columns" value= "*" > < / property>
< / include>
< / select>
缓存机制
MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制,缓存可以极大的提升查询效率
MyBatis系统中默认定义了两级缓存
默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启
二级缓存需要手动开启和配置,它是基于namespace级别的缓存,如果对表的操作查询可能有牵扯到多个namespace,那么得到的数据就可能是错误的
为了提高扩展性,MyBatis定义了缓存接口Cache,我们可以通过实现Cache接口来自定义二级缓存
一级缓存
一级缓存(local cache)即本地缓存, 作用域默认为sqlSession
当 Session flush 或 close 后, 该 Session 中的所有 Cache 将被清空
当表数据进行DML操作的时,缓存数据也会清空
一级缓存不能被关闭, 但可以调用 sqlSession.clearCache() 来清空本地缓存, 或者改变缓存的作用域
不同的sqlSession具有不同的缓存区域,即不同作用域的缓存互不影响
在mybatis3.1之后, 可以配置本地缓存的作用域
localCacheScope:默认为SESSION,缓存一个会话下执行的所有查询,设置为STATEMENT,可以禁用一级缓存
二级缓存
二级缓存(second level cache)即全局作用域缓存,二级缓存默认不开启,需要手动配置
二级缓存要求POJO实现Serializable接口
二级缓存在 SqlSession 关闭或提交之后才会生效
不同 SqlSession 之间,同一个Mapper数据共享
打开二级缓存
工作机制
一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中
如果会话关闭,一级缓存中的数据就会被保存在二级缓存中,新的会话查询信息,就可以参照二级缓存中的内容
不同namespace查春的数据会放在自己对应的map(缓存)中 查出的数据都会被默认先放在一级缓存中,只有会话提交或者关闭之后,一级缓存的数据才会转移到二级缓存中
缓存命中率
命中率的取值范围 [0.1),衡量查询性能的重要参数
命中率=命中个数/(命中的数+脱靶的数)
用了缓存后会增加查询的效率,但是会降低增删改的效率
第一次查询:无缓存,脱靶+1,总数+1、第二次查询:有缓存,命中+1,总数+1
MyBatis-Spring整合
整合关键配置:将MyBatis-config.xml的配置整合到Spring的配置文件中
< context: property- placeholder location= "classpath:conf/*.properties" system- properties- mode= "NEVER" / >
< bean id= "dataSource" class = "com.alibaba.druid.pool.DruidDataSource" destroy- method= "close" >
< property name= "driverClassName" value= "${mysql.driverName}" > < / property>
< property name= "url" value= "${mysql.url}" > < / property>
< property name= "username" value= "${mysql.username}" > < / property>
< property name= "password" value= "${mysql.password}" > < / property>
< / bean>
< bean id= "sqlSessionFactory" class = "org.mybatis.spring.SqlSessionFactoryBean" >
< ! -- 指定mybatis全局配置文件位置 -- >
< property name= "configLocation" value= "classpath:mybatis/mybatis-config.xml" > < / property>
< ! -- 指定数据源 -- >
< property name= "dataSource" ref= "dataSource" > < / property>
< ! -- mapperLocations:所有sql映射文件所在的位置 -- >
< property name= "mapperLocations" value= "classpath:mybatis/mapper/*.xml" > < / property>
< ! -- typeAliasesPackage:批量别名处理-- >
< property name= "typeAliasesPackage" value= "com.gc.bean" > < / property>
< / bean>
< ! -- 自动的扫描所有的mapper的实现并加入到ioc容器中 -- >
< bean id= "configure" class = "org.mybatis.spring.mapper.MapperScannerConfigurer" >
< ! -- 调用的sqlSessionFactory, 这里是String 类型,可省略 -- >
< property name= "sqlSessionFactoryBeanName" value= "sqlSessionFactory" > < / property>
< ! – basePackage: 指定包下所有的mapper接口实现自动扫描并加入到ioc容器中 -- >
< property name= "basePackage" value= "com.gc.dao" > < / property>
< / bean>
MyBatis-逆向工程
MyBatis Generator简称MBG,是一个专门为MyBatis框架使用者定制的代码生成器,可以快速的根据表生成对应的映射文件,接口,以及bean类。支持基本的增删改查,以及QBC风格的条件查询。但多表连接、存储过程等这些复杂sql的定义需要我们手工编写
使用步骤
编写MBG的配置文件
配置数据库连接信息
配置javaBean的生成策略
配置sql映射文件生成策略
配置Mapper接口的生成策略
配置要逆向解析的数据表
运行代码生成器生成代码
注:Context标签
targetRuntime=“MyBatis3“可以生成带条件的增删改查
targetRuntime=“MyBatis3Simple“可以生成基本的增删改查
如果再次生成,建议将之前生成的数据删除,避免xml向后追加内容出现的问题
MBG配置文件
< ? 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= "Tables" targetRuntime= "MyBatis" >
< commentGenerator>
< ! -- 是否去除自动生成的注释 true :是 : false : 否 -- >
< property name= "suppressAllComments" value= "true" / >
< / commentGenerator>
< jdbcConnection driverClass= "com.mysql.jdbc.Driver" connectionURL= "jdbc:mysql://localhost:3306/test" userId= "root" password= "123456" >
< / jdbcConnection>
< ! -- 默认false ,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer ,为 true 时把JDBC DECIMAL 和 NUMERIC 类型解析为java. math. BigDecimal -- >
< javaTypeResolver>
< property name= "forceBigDecimals" value= "false" / >
< / javaTypeResolver>
< javaModelGenerator targetPackage= "com.gc.bean" targetProject= ".\src" >
< ! -- enableSubPackages: 是否让schema作为包的后缀 -- >
< property name= "enableSubPackages" value= "true" / >
< ! -- 从数据库返回的值被清理前后的空格 -- >
< property name= "trimStrings" value= "true" / >
< / javaModelGenerator>
< sqlMapGenerator targetPackage= "com.gc.mapper" targetProject= ".\conf" >
< ! -- enableSubPackages: 是否让schema作为包的后缀 -- >
< property name= "enableSubPackages" value= "false" / >
< / sqlMapGenerator>
< javaClientGenerator type= "XMLMAPPER" targetPackage= "com.gc.mapper" targetProject= ".\src" >
< property name= "enableSubPackages" value= "false" / >
< / javaClientGenerator>
< table tableName= "books" domainObjectName= "Book" > < / table>
< table tableName= "dept" schema= "" enableCountByExample= "false"
enableDeleteByExample= "false" enableUpdateByExample= "false"
enableSelectByExample= "false" selectByExampleQueryId= "false" > < / table>
< / context>
< / generatorConfiguration>
public static void main ( String [ ] args) throws Exception {
List < String > warnings = new ArrayList < String > ( ) ;
boolean overwrite = true ;
File configFile = new File ( "MBG配置文件.xml" ) ;
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 ) ;
}
@Test
public void test01 ( ) {
SqlSession openSession = build. openSession ( ) ;
DeptMapper mapper = openSession. getMapper ( DeptMapper . class ) ;
DeptExample example = new DeptExample ( ) ;
Criteria criteria = example. createCriteria ( ) ;
criteria. andDeptnameLike ( "%部%" ) ;
criteria. andIdGreaterThan ( 2 ) ;
List < Dept > list = mapper. selectByExample ( example) ;
for ( Dept dept : list) {
System . out. println ( dept) ;
} }
MyBatis-插件开发
MyBatis在四大对象的创建过程中,都会有插件进行介入。插件可以利用动态代理机制一层层的包装目标对象,而实现在目标对象执行目标方法之前进行拦截的效果
MyBatis 允许在已映射语句执行过程中的某一点进行拦截调用
默认情况下,MyBatis 允许使用插件来拦截的方法调用包括
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
pageHelper分页插件
导包(jsqlparser-1.1.jar,pagehelper-5.1.2.jar)
在全局配置文件中注册
< plugins>
< plugin interceptor= "com.github.pagehelper.PageInterceptor" >
< ! -- 针对的数据库 -- >
< property name= "helperDialect" value= "mysql" / >
< ! -- 分页合理化 低于1 页面, 高于最后一页如何处理 -- >
< property name= "reasonable" value= "true" / >
< ! -- 查询没有数据时的处理 -- >
< property name= "pageSizeZero" value= "true" / >
< / plugin>
< / plugins>
PageHelper.startPage(curPage, pageSize); 放在查询之前,PageInfo info=new PageInfo(list);放在查询之后,不能有其他语句
开发步骤
编写插件实现Interceptor接口,并使用@Intercepts注解完成插件签名
@Intercepts ( {
@Signature ( type= StatementHandler . class , method= "parameterize" , args= java. sql. Statement. class )
} )
public class MyFirstPlugin implements Interceptor { }
< plugins>
< plugin interceptor= "com.mybatis.dao.MyFirstPlugin" >
< property name= "username" value= "root" / >
< property name= "password" value= "123456" / >
< / plugin>
< plugin interceptor= "com.atguigu.mybatis.dao.MySecondPlugin" >
< / plugin>
< / plugins>
插件原理
按照插件注解声明,按照插件配置顺序调用插件plugin方法,生成被拦截对象的动态代理
多个插件依次生成目标对象的代理对象,层层包裹,先声明的先包裹;形成代理链
目标方法执行时依次从外到内执行插件的intercept方法
多个插件情况下,我们往往需要在某个插件中分离出目标对象。可以借助MyBatis提供的SystemMetaObject类来进行获取最后一层的h以及target属性的值
Interceptor接口
public Object intercept(Invocation invocation) throws Throwable //拦截目标方法执行
public Object plugin(Object target) //生成动态代理对象,可以使用MyBatis提 供的Plugin类的wrap方法
public void setProperties(Properties properties) //注入插件配置时设置的属性
从代理链中分离真实被代理对象
MetaObject metaObject = SystemMetaObject . forObject ( target) ;
while ( metaObject. hasGetter ( "h" ) ) {
Object h = metaObject. getValue ( "h" ) ;
metaObject = SystemMetaObject . forObject ( h) ;
}
Object obj = metaObject. getValue ( "target" ) ;
MetaObject forObject = SystemMetaObject . forObject ( obj) ;
你可能感兴趣的:(java框架,mybatis)
insert into select 主键自增_mybatis拦截器实现主键自动生成
weixin_39521651
insert into select 主键自增 mybatis delete返回值 mybatis insert返回主键 mybatis insert返回对象 mybatis plus insert返回主键 mybatis plus 插入生成id
前言前阵子和朋友聊天,他说他们项目有个需求,要实现主键自动生成,不想每次新增的时候,都手动设置主键。于是我就问他,那你们数据库表设置主键自动递增不就得了。他的回答是他们项目目前的id都是采用雪花算法来生成,因此为了项目稳定性,不会切换id的生成方式。朋友问我有没有什么实现思路,他们公司的orm框架是mybatis,我就建议他说,不然让你老大把mybatis切换成mybatis-plus。mybat
00. 这里整理了最全的爬虫框架(Java + Python)
有一只柴犬
爬虫系列 爬虫 java python
目录1、前言2、什么是网络爬虫3、常见的爬虫框架3.1、java框架3.1.1、WebMagic3.1.2、Jsoup3.1.3、HttpClient3.1.4、Crawler4j3.1.5、HtmlUnit3.1.6、Selenium3.2、Python框架3.2.1、Scrapy3.2.2、BeautifulSoup+Requests3.2.3、Selenium3.2.4、PyQuery3.2
MyBatis 详解
阿贾克斯的黎明
java mybatis
目录目录一、MyBatis是什么二、为什么使用MyBatis(一)灵活性高(二)性能优化(三)易于维护三、怎么用MyBatis(一)添加依赖(二)配置MyBatis(三)创建实体类和接口(四)使用MyBatis一、MyBatis是什么MyBatis是一个优秀的持久层框架,它支持自定义SQL、存储过程以及高级映射。MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作。它可以通过简
mybatis 二级缓存失效_Mybatis 缓存原理及失效情况解析
weixin_39844942
mybatis 二级缓存失效
这篇文章主要介绍了Mybatis缓存原理及失效情况解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下1、什么是缓存[Cache]存在内存中的临时数据。将用户经常查询的数据放在缓存(内存)中,用户去查询数据就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,从而提高查询效率,解决了高并发系统的性能问题。2、为什么要使用缓存减少和数据库的交互次
详解mybatis的一二级缓存以及缓存失效原因
仰望天花板
缓存 数据库 mybatis java mysql
数据库的大部分场景下是从磁盘读取,如果数据从内存进行读取,速度较比磁盘要快得多。但因为内存的容量有限,所以一般只会把使用和查询较多的数据缓存起来,以便快速反应,其他使用率不太多的继续存放在磁盘。mybatis分为一级缓存和二级缓存1.一级缓存一级缓存存放在SqlSqeeion上,默认开启1.1pojo@DatapublicclassRole{privateLongid;privateStringr
36. MyBatis如何支持多数据库操作?如何配置不同的数据源?
这孩子叫逆
Mybatis笔记 mybatis 数据库
在许多企业级应用中,可能需要访问多个数据库。MyBatis可以通过配置多个数据源和动态切换数据源来支持多数据库操作。下面介绍如何在MyBatis中配置和使用多个数据源。1.多数据源的基本配置1.1配置多个数据源要支持多个数据源,首先需要在Spring或SpringBoot中配置不同的数据源。假设我们要连接两个数据库db1和db2,可以通过以下步骤进行配置。SpringBoot示例:applicat
MyBatis批量插入大量数据
小黑屋说YYDS
MyBatis java
1.思路分析批量插入这个问题,我们用JDBC操作,其实就是两种思路吧:用一个for循环,把数据一条一条的插入(这种需要开启批处理)。生成一条插入sql,类似这种insertintouser(username,address)values(‘aa’,‘bb’),(‘cc’,‘dd’)…。到底哪种快呢?我们从两方面来考虑这个问题:插入SQL本身执行的效率。网络I/O。先说第一种方案,就是用for循环循
MyBatis 查询数据库_mybatis查询某个库的所有表名(2)
2401_84181942
程序员 mybatis oracle tomcat
标签说明:***``标签**:需要指定namespace属性,表示命名空间,值为mapper接口的全限定名,包括全包名.类名。***``查询标签**:是用来执行数据库的查询操作的:`id`:是和Interface(接口)中定义的方法名称一样的,表示对接口的具体实现方法。`resultType`:是返回的数据类型,也就是开头我们定义的实体类。####2.4.4添加Service服务层实现代码如下:@
5-【JavaWeb】JUnit 单元测试及JUL 日志系统
weixin_44329069
JavaWeb junit 单元测试
1.使用JUnit进行单元测试JUnit是Java中非常流行的单元测试框架,MyBatis与JUnit可以很好地结合,来测试持久层代码的正确性。1.1添加JUnit依赖在使用JUnit之前,需要在pom.xml中引入JUnit依赖。junitjunit4.13.2test1.2单元测试基本结构假设我们要测试UserMapper中的getUserById方法,测试代码如下:importorg.apa
【免费】springboot项目申报管理系统|毕业设计|Javaweb项目
计算机学姐来啦
springboot ssm java spring boot 课程设计 后端 毕设 毕业设计 java-ee
收藏点赞不迷路关注作者有好处编号:springboot375springboot项目申报管理系统开发语言:Java数据库:MySQL技术:Spring+SpringMVC+MyBatis工具:IDEA/Ecilpse、Navicat、Maven1.万字文档展示(部分)2.系统图片展示第5章系统详细设计5.1管理员功能模块的实现5.1.1项目列表如图5.1显示的就是项目列表页面,此页面提供给管理员的
MyBatis系统学习(一)——项目结构及其含义
OEC小胖胖
MyBatis mybatis 学习 web 后端
1.MyBatis简介MyBatis是一款优秀的持久层框架,它通过SQL映射的方式实现Java对数据库操作的映射,既保留了SQL语句的灵活性,也简化了代码的编写。在一个MyBatis项目中,核心部分主要有:配置文件(mybatis-config.xml)映射文件(Mapper.xml)实体类(Entity/POJO)接口类(Mapper接口)MyBatis会话工厂(SqlSessionFactor
MyBatis 如何将 Mapper 接口与其 XML 映射文件关联:深入原理与实现
OEC小胖胖
web后端 mybatis xml java web 后端
MyBatis如何将Mapper接口与其XML映射文件关联:深入原理与实现1.概述MyBatis是一个简单、灵活的持久层框架,它通过SQL语句将Java对象与数据库进行映射。MyBatis支持基于XML和注解的配置方式。在实际开发中,XML映射文件与Mapper接口的关联是MyBatis的核心功能之一。通过这种关联,开发者可以在Mapper接口中定义方法,并在XML文件中编写SQL语句,从而实现数
Mybatis实现员工管理系统
wu1113_
mybatis java maven
文章目录1.案例需求2.编程思路3.案例源码4.小结1.案例需求在上次做的父子模块的maven以及Ajax实现人工管理系统的基础上使用Mybatis实现员工管理系统的增删改查,具体运行效果如下:2.编程思路Mybatis框架的一般执行流程:创建MyBatis配置文件mybatis-config.xml在里面加载数据源、事务等,管理映射文件创建需要的映射文件mapper.xml,用于映射表中列和实体
springboot+mybatisplus实现基本的增删改查以及分页查询。这里使用的是Restful风格包括简单描述Restful是什么
okchan666
spring boot java
先实现springboot+mybatisplus的增删改查接口使用postman测试:第一步创建项目导入依赖:直接给大家了:4.0.0org.springframework.bootspring-boot-starter-parent2.6.6com.okchanspringboot_07_ssmp0.0.1-SNAPSHOT1.8org.springframework.bootspring-b
MyBatis 方法重载的陷阱及解决方案
molashaonian
mybatis 方法重载 异常 方法名相同
在使用MyBatis进行开发时,尤其是使用注解模式(如@Select、@Insert等)时,开发者常常会遇到这样一个问题:为什么我的方法重载不能正常工作?即使在Java中允许方法名相同但参数不同的重载,MyBatis在处理注解的SQL方法时却并不支持这种方式。这篇文章将深入探讨MyBatis的这个特性及如何规避相关的坑。问题背景在标准的Java开发中,方法重载是一种常见的设计模式。方法重载允许我们
Spring Cloud+Spring Boot+Mybatis+Java版电子招标采购系统源码 及 功能清单
Xiaohong0716
mybatis java spring cloud
一、立项管理1、招标立项申请功能点:招标类项目立项申请入口,用户可以保存为草稿,提交。2、非招标立项申请功能点:非招标立项申请入口、用户可以保存为草稿、提交。3、采购立项列表功能点:对草稿进行编辑,驳回的立项编辑,在途流程查看。二、项目管理1、采购计划管理功能点:采购计划新增、编辑、删除2、采购过程管理功能点:查询、维护基准价、组建评审小组、项目答疑澄清、文件费保证金审核、供应商报价维护、查看评审
BindingException: Invalid bound statement (not found)
小卡车555
MyBatis mybatis java mysql
Mybatis出现绑定异常问题的解决org.apache.ibatis.binding.BindingException:Invalidboundstatement(notfound)一般的原因是Mapperinterface和xml文件的定义对应不上,需要检查包名,namespace,函数名称等能否对应上,需要比较细致的对比,我经常就是写错了一两个字母搞的很长时间找不到错误按以下步骤一一执行:1
工程项目管理系统源码与Spring Cloud:实现高效系统管理与二次开发
微服务技术分享
spring cloud java 工程项目管理系统源码
随着企业规模的不断扩大和业务的快速发展,传统的工程项目管理方式已经无法满足现代企业的需求。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,企业需要借助先进的数字化技术进行转型。本文将介绍一款采用SpringCloud+SpringBoot+Mybatis技术框架的工程项目管理系统,该系统涵盖了项目管理、合同管理、预警管理、竣工管理、质量管理等多个方面,通过数据字典、编码管理、用户管理
[附源码]SSM计算机毕业设计游戏账号交易平台JAVA
计算机程序源码
java 游戏 mysql
项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:SSM+mybatis+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.ID
Mybatis Mysql
莫夏_b560
1、查询失败或者结果异常andfwbdh=#{fwbdh}更换成andfwbdh=#{fwbdh}
33. MyBatis中的@Param注解如何使用?如何在Mapper接口中传递多个参数?
这孩子叫逆
Mybatis笔记 java mybatis tomcat
在MyBatis中,@Param注解用于将方法参数绑定到SQL语句中的命名参数。它主要用于在Mapper接口中传递多个参数,以便在SQL语句中更方便地引用这些参数。为什么使用@Param注解?在MyBatis中,当Mapper接口的方法只有一个参数时,MyBatis会默认将这个参数的名称绑定为#{parameter},可以直接在SQL语句中引用它。如果方法有多个参数,MyBatis默认使用para
Python+Django毕业设计校园易购二手交易平台(程序+LW+部署)
Python、JAVA毕设程序源码
课程设计 java mysql
项目运行环境配置:Jdk1.8+Tomcat7.0+Mysql+HBuilderX(Webstorm也行)+Eclispe(IntelliJIDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:SSM+mybatis+Maven+Vue等等组成,B/S模式+Maven管理等等。环境需要1.运行环境:最好是javajdk1.8,我们在这个平台上运行的。其他版本理论上也可以。2.ID
Springboot3 整合 Mybatis3
(前程似锦)
mybatis java spring boot
Springboot3整合MybatisSpringboot3整合MybatisSpringboot3整合Mybatis一、导入依赖二、编写配置文件三、定义模型entity实体类四、在启动类上添加注解,表示mapper接口所在位置五、定义mapper接口六、定义mapper.xml映射文件七、service层八、测试一、导入依赖mybatis的必要依赖注意:使用springboot3的话要使用my
mybatis支持json,Spring boot配置
Knight_9
mysql5.7版本以后支持原生json格式,基于Springboot进行配置说明。mybatis支持mysql的json格式mysql-connector,mysql的驱动版本要大于等于5.1.40,否则json字段查询会发生乱码。继承BaseTypeHandler自定义一个json类型处理器,放到一个handler包下,例:packagecom.c.config.handler;importc
【Java】Mybatis Druid连接池配置详细
beautiful_huang
Java
pom.xmlcom.alibabadruid1.0.18.propertiesspring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.url=jdbc:mysql://localhost:3306/mybatis2?characterEncoding=utf-8&useSSL=truespring.da
关于com.baomidou:mybatis-plus-boot-starter:jar:unknown was not found解决办法
波斯CD
mybatis jar java
原型com.baomidoumybatis-plus-boot-starter修改以后解决了com.baomidoumybatis-plus-boot-starter3.5.3.1
MyBatis-Plus 3.5.5的代码生成器 实践【完整代码】
qq_43513957
mybatis
MyBatis-Plus3.5.5的代码生成器实践【完整代码】1.表:要有一个version字段,乐观锁更新。配置拦截器的代码packagecom.example.demo.zmybatisplusGenerator.config;importcom.baomidou.mybatisplus.annotation.DbType;importcom.baomidou.mybatisplus.exte
springboot宠物咖啡馆平台的设计与实现
然然学长
spring boot 宠物 java 后端 intellij-idea 开发语言
运行环境环境说明:开发语言:java框架:springboot,vueJDK版本:JDK1.8数据库:mysql5.7+(推荐5.7,8.0也可以)数据库工具:Navicat11+开发软件:idea/eclipse(推荐idea)Maven包:Maven3.3.9+系统详细实现管理员模块的实现用户信息管理基于SpringBoot的宠物咖啡馆平台的设计与实现的系统管理员可以管理用户,可以对用户信息添
深入解析 MyBatis:从理论到项目实例
OEC小胖胖
web后端 mybatis java spring web 后端
深入解析MyBatis:从理论到项目实例目录MyBatis概述MyBatis项目结构及作用核心概念详解分页功能的实现与深入剖析动态SQL缓存机制详解与Spring集成常见问题与深入分析完整项目示例总结1.MyBatis概述MyBatis是一个轻量级的持久层框架,使用SQL查询语句来访问数据库。它与Java对象建立映射关系,通过配置文件或注解来管理SQL语句,灵活性高且与数据库操作直接相关,适合需要
MyBatis Plus 实战详解
Aries263
redis 分布式 数据库
一、引言MyBatisPlus(简称MP)是MyBatis的增强工具,旨在简化开发、提高效率。它保留了MyBatis的强大功能,并在其基础上进行了扩展和优化,提供了强大的CRUD操作、配置选项、条件构造器等功能。本文将详细介绍MyBatisPlus的安装、配置、基本操作以及分页和条件查询的使用。二、安装与配置1.添加依赖首先,在Maven项目的pom.xml中添加MyBatisPlus的依赖。以下
矩阵求逆(JAVA)初等行变换
qiuwanchi
矩阵求逆(JAVA)
package gaodai.matrix;
import gaodai.determinant.DeterminantCalculation;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
/**
* 矩阵求逆(初等行变换)
* @author 邱万迟
*
JDK timer
antlove
java jdk schedule code timer
1.java.util.Timer.schedule(TimerTask task, long delay):多长时间(毫秒)后执行任务
2.java.util.Timer.schedule(TimerTask task, Date time):设定某个时间执行任务
3.java.util.Timer.schedule(TimerTask task, long delay,longperiod
JVM调优总结 -Xms -Xmx -Xmn -Xss
coder_xpf
jvm 应用服务器
堆大小设置JVM 中最大堆大小有三方面限制:相关操作系统的数据模型(32-bt还是64-bit)限制;系统的可用虚拟内存限制;系统的可用物理内存限制。32位系统下,一般限制在1.5G~2G;64为操作系统对内存无限制。我在Windows Server 2003 系统,3.5G物理内存,JDK5.0下测试,最大可设置为1478m。
典型设置:
java -Xmx
JDBC连接数据库
Array_06
jdbc
package Util;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class JDBCUtil {
//完
Unsupported major.minor version 51.0(jdk版本错误)
oloz
java
java.lang.UnsupportedClassVersionError: cn/support/cache/CacheType : Unsupported major.minor version 51.0 (unable to load class cn.support.cache.CacheType)
at org.apache.catalina.loader.WebappClassL
用多个线程处理1个List集合
362217990
多线程 thread list 集合
昨天发了一个提问,启动5个线程将一个List中的内容,然后将5个线程的内容拼接起来,由于时间比较急迫,自己就写了一个Demo,希望对菜鸟有参考意义。。
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
public c
JSP简单访问数据库
香水浓
sql mysql jsp
学习使用javaBean,代码很烂,仅为留个脚印
public class DBHelper {
private String driverName;
private String url;
private String user;
private String password;
private Connection connection;
privat
Flex4中使用组件添加柱状图、饼状图等图表
AdyZhang
Flex
1.添加一个最简单的柱状图
? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
<?xml version=
"1.0"&n
Android 5.0 - ProgressBar 进度条无法展示到按钮的前面
aijuans
android
在低于SDK < 21 的版本中,ProgressBar 可以展示到按钮前面,并且为之在按钮的中间,但是切换到android 5.0后进度条ProgressBar 展示顺序变化了,按钮再前面,ProgressBar 在后面了我的xml配置文件如下:
[html]
view plain
copy
<RelativeLa
查询汇总的sql
baalwolf
sql
select list.listname, list.createtime,listcount from dream_list as list , (select listid,count(listid) as listcount from dream_list_user group by listid order by count(
Linux du命令和df命令区别
BigBird2012
linux
1,两者区别
du,disk usage,是通过搜索文件来计算每个文件的大小然后累加,du能看到的文件只是一些当前存在的,没有被删除的。他计算的大小就是当前他认为存在的所有文件大小的累加和。
AngularJS中的$apply,用还是不用?
bijian1013
JavaScript AngularJS $apply
在AngularJS开发中,何时应该调用$scope.$apply(),何时不应该调用。下面我们透彻地解释这个问题。
但是首先,让我们把$apply转换成一种简化的形式。
scope.$apply就像一个懒惰的工人。它需要按照命
[Zookeeper学习笔记十]Zookeeper源代码分析之ClientCnxn数据序列化和反序列化
bit1129
zookeeper
ClientCnxn是Zookeeper客户端和Zookeeper服务器端进行通信和事件通知处理的主要类,它内部包含两个类,1. SendThread 2. EventThread, SendThread负责客户端和服务器端的数据通信,也包括事件信息的传输,EventThread主要在客户端回调注册的Watchers进行通知处理
ClientCnxn构造方法
&
【Java命令一】jmap
bit1129
Java命令
jmap命令的用法:
[hadoop@hadoop sbin]$ jmap
Usage:
jmap [option] <pid>
(to connect to running process)
jmap [option] <executable <core>
(to connect to a
Apache 服务器安全防护及实战
ronin47
此文转自IBM.
Apache 服务简介
Web 服务器也称为 WWW 服务器或 HTTP 服务器 (HTTP Server),它是 Internet 上最常见也是使用最频繁的服务器之一,Web 服务器能够为用户提供网页浏览、论坛访问等等服务。
由于用户在通过 Web 浏览器访问信息资源的过程中,无须再关心一些技术性的细节,而且界面非常友好,因而 Web 在 Internet 上一推出就得到
unity 3d实例化位置出现布置?
brotherlamp
unity教程 unity unity资料 unity视频 unity自学
问:unity 3d实例化位置出现布置?
答:实例化的同时就可以指定被实例化的物体的位置,即 position
Instantiate (original : Object, position : Vector3, rotation : Quaternion) : Object
这样你不需要再用Transform.Position了,
如果你省略了第二个参数(
《重构,改善现有代码的设计》第八章 Duplicate Observed Data
bylijinnan
java 重构
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Label;
import java.awt.TextField;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusE
struts2更改struts.xml配置目录
chiangfai
struts.xml
struts2默认是读取classes目录下的配置文件,要更改配置文件目录,比如放在WEB-INF下,路径应该写成../struts.xml(非/WEB-INF/struts.xml)
web.xml文件修改如下:
<filter>
<filter-name>struts2</filter-name>
<filter-class&g
redis做缓存时的一点优化
chenchao051
redis hadoop pipeline
最近集群上有个job,其中需要短时间内频繁访问缓存,大概7亿多次。我这边的缓存是使用redis来做的,问题就来了。
首先,redis中存的是普通kv,没有考虑使用hash等解结构,那么以为着这个job需要访问7亿多次redis,导致效率低,且出现很多redi
mysql导出数据不输出标题行
daizj
mysql 数据导出 去掉第一行 去掉标题
当想使用数据库中的某些数据,想将其导入到文件中,而想去掉第一行的标题是可以加上-N参数
如通过下面命令导出数据:
mysql -uuserName -ppasswd -hhost -Pport -Ddatabase -e " select * from tableName" > exportResult.txt
结果为:
studentid
phpexcel导出excel表简单入门示例
dcj3sjt126com
PHP Excel phpexcel
先下载PHPEXCEL类文件,放在class目录下面,然后新建一个index.php文件,内容如下
<?php
error_reporting(E_ALL);
ini_set('display_errors', TRUE);
ini_set('display_startup_errors', TRUE);
if (PHP_SAPI == 'cli')
die('
爱情格言
dcj3sjt126com
格言
1) I love you not because of who you are, but because of who I am when I am with you. 我爱你,不是因为你是一个怎样的人,而是因为我喜欢与你在一起时的感觉。 2) No man or woman is worth your tears, and the one who is, won‘t
转 Activity 详解——Activity文档翻译
e200702084
android UI sqlite 配置管理 网络应用
activity 展现在用户面前的经常是全屏窗口,你也可以将 activity 作为浮动窗口来使用(使用设置了 windowIsFloating 的主题),或者嵌入到其他的 activity (使用 ActivityGroup )中。 当用户离开 activity 时你可以在 onPause() 进行相应的操作 。更重要的是,用户做的任何改变都应该在该点上提交 ( 经常提交到 ContentPro
win7安装MongoDB服务
geeksun
mongodb
1. 下载MongoDB的windows版本:mongodb-win32-x86_64-2008plus-ssl-3.0.4.zip,Linux版本也在这里下载,下载地址: http://www.mongodb.org/downloads
2. 解压MongoDB在D:\server\mongodb, 在D:\server\mongodb下创建d
Javascript魔法方法:__defineGetter__,__defineSetter__
hongtoushizi
js
转载自: http://www.blackglory.me/javascript-magic-method-definegetter-definesetter/
在javascript的类中,可以用defineGetter和defineSetter_控制成员变量的Get和Set行为
例如,在一个图书类中,我们自动为Book加上书名符号:
function Book(name){
错误的日期格式可能导致走nginx proxy cache时不能进行304响应
jinnianshilongnian
cache
昨天在整合某些系统的nginx配置时,出现了当使用nginx cache时无法返回304响应的情况,出问题的响应头: Content-Type:text/html; charset=gb2312 Date:Mon, 05 Jan 2015 01:58:05 GMT Expires:Mon , 05 Jan 15 02:03:00 GMT Last-Modified:Mon, 05
数据源架构模式之行数据入口
home198979
PHP 架构 行数据入口
注:看不懂的请勿踩,此文章非针对java,java爱好者可直接略过。
一、概念
行数据入口(Row Data Gateway):充当数据源中单条记录入口的对象,每行一个实例。
二、简单实现行数据入口
为了方便理解,还是先简单实现:
<?php
/**
* 行数据入口类
*/
class OrderGateway {
/*定义元数
Linux各个目录的作用及内容
pda158
linux 脚本
1)根目录“/” 根目录位于目录结构的最顶层,用斜线(/)表示,类似于
Windows
操作系统的“C:\“,包含Fedora操作系统中所有的目录和文件。 2)/bin /bin 目录又称为二进制目录,包含了那些供系统管理员和普通用户使用的重要
linux命令的二进制映像。该目录存放的内容包括各种可执行文件,还有某些可执行文件的符号连接。常用的命令有:cp、d
ubuntu12.04上编译openjdk7
ol_beta
HotSpot jvm jdk OpenJDK
获取源码
从openjdk代码仓库获取(比较慢)
安装mercurial Mercurial是一个版本管理工具。 sudo apt-get install mercurial
将以下内容添加到$HOME/.hgrc文件中,如果没有则自己创建一个: [extensions] forest=/home/lichengwu/hgforest-crew/forest.py fe
将数据库字段转换成设计文档所需的字段
vipbooks
设计模式 工作 正则表达式
哈哈,出差这么久终于回来了,回家的感觉真好!
PowerDesigner的物理数据库一出来,设计文档中要改的字段就多得不计其数,如果要把PowerDesigner中的字段一个个Copy到设计文档中,那将会是一件非常痛苦的事情。