Mybatis总结(一)
Mybatis总结(一)
一.Mybatis启动流程(代码层面)
关于config.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>
<properties resource="db.properties" ></properties>
<typeAliases>
<package name="com.courage.mybatis.entity"/>
</typeAliases>
<typeHandlers>
<typeHandler handler="com.courage.mybatis.converter.BooleanAndIntConverter" javaType="Boolean" jdbcType="Integer"></typeHandler>
</typeHandlers>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/courage/com.courage.mybatis/mapper/StudentMapper.xml"/>
</mappers>
</configuration>
文件头
这一部分是Mybatis用来确认的配置文件,相当于java中的魔数,主要用来检验
<?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">
数据源多处配置,properties加载顺序
<properties resource="db.properties" ></properties>
这一段主要是指定数据库的配置文件,properties中是可以设置属性的,如下:
<!-- 加载数据库属性文件 -->
<properties resource="db.properties">
<property name="username" value="Courage"/>
</properties>
那么有一个问题,就是如果数据库信息在config.xml、db.properties、以及properties中都有配置,那么会读取哪一个呢?或者说读取顺序是什么呢?直接上源码:
private void propertiesElement(XNode context) throws Exception {
if (context != null) {
/**
* 这一部分是解析properties属性中指定的属性,即上面的Courage部分。
*/
Properties defaults = context.getChildrenAsProperties();
//resource 制定的属性路径
String resource = context.getStringAttribute("resource");
String url = context.getStringAttribute("url"); //url制定的属性路径
if (resource != null && url != null) {
throw new BuilderException("The properties element cannot specify both a URL and a resource based property file reference. Please specify one or the other.");
}
/**
* 根据 properties 元素中的 resource 属性读取类路径下属性文件(db.properties),并覆盖properties 属性中指定的同名属性(Courage)。
*/
if (resource != null) {
defaults.putAll(Resources.getResourceAsProperties(resource));
} else if (url != null) {
/**
* 根据properties元素中的url(db.properties中的)属性指定的路径读取属性文件,并覆盖properties 属性中指定的同名属性(Courage那一部分)。
*/
defaults.putAll(Resources.getUrlAsProperties(url));
}
/**
* 获取方法参数传递的properties
* 创建XMLConfigBuilder实例时,this.configuration.setVariables(props);
*/
Properties vars = configuration.getVariables();
if (vars != null) {
defaults.putAll(vars);
}
parser.setVariables(defaults);
configuration.setVariables(defaults);
}
}
结论
1、在 properties 内部自定义的属性值第一个被读取(这部分:)
2、然后读取 resource 路径表示文件中的属性(db.properties),如果有,它会覆盖已经读取的属性(Courage);如果 resource 路径不存在,那么读取 url (config.xml)表示路径文件中的属性,如果有,它会覆盖第一步读取的属性值(Courage)
3、最后读取 parameterType (程序员编码时设置的值)传递的属性值,它会覆盖已读取的同名的属性
二.别名设置
typeAliases
typeAliases主要是用来给对应的类取一个别名,查询语句中,返回类型和输入参数类型都是以包名+类名,如:com.courage.mybatis.entity.Student的形式,来来回回复制粘贴很麻烦,那么就可以采用取别名的方法:
单个别名:
<typeAlias type="com.courage.mybatis.entity.Student" alias="student"></typeAlias>
以为着之前包名+类名的地方都可以用student代替,student是忽略大小写的.
批量别名:
<package name="com.courage.mybatis.entity"/>
如果包里很多类,那么注意指定别名工作量也很大,那么可以采用这种批量别名的方式对一个包里面的类进行别名,这是类的别名就是不带包名的类名,同样忽略大小写,除了自定义别名外,Mybatis还内置了一些常见的类的别名:
Mapped Type | |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
三.类型处理器
typeHandlers
数据库中的表映射成类时,某些字段可能没法匹配,例如int类型与boolean类型转换,所以需要人工写一些转换对应的规则
<typeHandlers>
<typeHandler handler="com.courage.mybatis.converter.BooleanAndIntConverter" javaType="Boolean" jdbcType="Integer"></typeHandler>
</typeHandlers>
其中BooleanAndIntConverter就是一个Boolean与int相互转换的一个类型转换类:
转换器代码
public class BooleanAndIntConverter extends BaseTypeHandler<Boolean> {
//java(boolean)-DB(number)
/*
* ps:PreparedStatement对象
* i:PreparedStatement对象操作参数的位置
* parameter:java值
* jdbcType:jdbc操作的数据库类型
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, Boolean parameter, JdbcType jdbcType)
throws SQLException {
if (parameter) {
//1
ps.setInt(i, 1);
} else {
// 0
ps.setInt(i, 0);
}
}
//db(number)->java(boolean)
@Override
public Boolean getNullableResult(ResultSet rs, String columnName) throws SQLException {
int sexNum = rs.getInt(columnName);//rs.getInt("stuno") ;
return sexNum == 1 ? true : false;
}
@Override
public Boolean getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
int sexNum = rs.getInt(columnIndex);//rs.getInt(1)
return sexNum == 1 ? true : false;
}
@Override
public Boolean getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
int sexNum = cs.getInt(columnIndex);//rs.getInt(1)
return sexNum == 1 ? true : false;
}
}
转换器的使用
1.在config.xml中配置
<typeHandlers>
<typeHandler handler="com.courage.mybatis.converter.BooleanAndIntConverter" javaType="Boolean" jdbcType="Integer"></typeHandler>
</typeHandlers>
2.在Mapper.xml中使用
<select id="queryStudentByStunoWithConverter"
parameterType="int"
resultMap="studentResult" >
select * from student where stuno = #{stuno}
</select>
<!--通过studentResult将二者联系起来-->
<resultMap type="student" id="studentResult">
<id property="stuNo" column="stuno" />
<result property="stuName" column="stuname" />
<result property="stuAge" column="stuage" />
<result property="graName" column="graname" />
<result property="stuSex" column="stusex" javaType="boolean"jdbcType="INTEGER"/>
</resultMap>
注意:
1.将boolean 与 INTEGER对应起来,并且指定类型,注意这儿只能大写,小写不行
2.查询类型转换器
1.如果 类中属性 和 表中的字段 类型能够合理识别(String-varchar2),
则可以使用resultType;否则(boolean-number)使用resultMap
2.如果 类中属性名 和表中的字段名 能够合理识别 (stuNo -stuno)
则可以使用resultType;否则(id-stuno) 使用resultMap
四.全局设置
1.参数配置方法以及位置
可以设置一些全局参数配置,配置位置很重要,在properties下面,在environments上面,通过key- value队进行设置,不熟悉的话不建议随便设置这个值,牵一发而动全身,影响mybatis的行为
<settings>
<setting name="cacheEnabled" value="false"/>
<setting name="lazyLoadingEnable" value="false"/>
</settings>
2.参数表
可以设置的参数以及描述:
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局地开启或关闭配置文件中的所有映射器已经配置的任何缓存。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 |
true | false | false |
aggressiveLazyLoading | 当开启时,任何方法的调用都会加载该对象的所有属性。 否则,每个属性会按需加载(参考 lazyLoadTriggerMethods )。 |
true | false | false (在 3.4.1 及之前的版本默认值为 true) |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要驱动支持)。 | true | false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。 | true | false | true |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要驱动支持。 如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能支持但仍可正常工作(比如 Derby)。 | true | false | False |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。 NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。 FULL 会自动映射任意复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
autoMappingUnknownColumnBehavior | 指定发现自动映射目标未知列(或者未知属性类型)的行为。NONE : 不做任何反应WARNING : 输出提醒日志 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN )FAILING : 映射失败 (抛出 SqlSessionException ) |
NONE, WARNING, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements); BATCH 执行器将重用语句并执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定驱动等待数据库响应的秒数。 | 任意正整数 | 未设置 (null) |
defaultFetchSize | 为驱动的结果集获取数量(fetchSize)设置一个提示值。此参数只可以在查询设置中被覆盖。 | 任意正整数 | 未设置 (null) |
safeRowBoundsEnabled | 允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 | true | false | False |
safeResultHandlerEnabled | 允许在嵌套语句中使用分页(ResultHandler)。如果允许使用则设置为 false。 | true | false | True |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。 | true | false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。 某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType 常量,常用值:NULL, VARCHAR 或 OTHER。 | OTHER |
lazyLoadTriggerMethods | 指定哪个对象的方法触发一次延迟加载。 | 用逗号分隔的方法列表。 | equals,clone,hashCode,toString |
defaultScriptingLanguage | 指定动态 SQL 生成的默认语言。 | 一个类型别名或完全限定类名。 | org.apache.ibatis.scripting.xmltags.XMLLanguageDriver |
defaultEnumTypeHandler | 指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5) |
一个类型别名或完全限定类名。 | org.apache.ibatis.type.EnumTypeHandler |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值初始化的时候比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。 | true | false | false |
returnInstanceForEmptyRow | 当返回行的所有列都是空时,MyBatis默认返回 null 。 当开启这个设置时,MyBatis会返回一个空实例。 请注意,它也适用于嵌套的结果集 (如集合或关联)。(新增于 3.4.2) |
true | false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | 任何字符串 | 未设置 |
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
proxyFactory | 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST (MyBatis 3.3 以上) |
vfsImpl | 指定 VFS 的实现 | 自定义 VFS 的实现的类全限定名,以逗号分隔。 | 未设置 |
useActualParamName | 允许使用方法签名中的名称作为语句参数名称。 为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1) |
true | false | true |
configurationFactory | 指定一个提供 Configuration 实例的类。 这个被返回的 Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3) |
类型别名或者全类名. | 未设置 |
五.存储过程
1.存储过程的简介
我们常用的操作数据库语言SQL语句在执行的时候需要要先编译,然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。
一个存储过程是一个可编程的函数,它在数据库中创建并保存。它可以有SQL语句和一些特殊的控制结构组成。当希望在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中的存储过程可以看做是对编程中面向对象方法的模拟。它允许控制数据的访问方式。
2.存储过程优点
- 存储过程增强了SQL语言的功能和灵活性。存储过程可以用流控制语句编写,有很强的灵活性,可以完成复杂的判断和较复杂的运算。
- 存储过程允许标准组件是编程。存储过程被创建后,可以在程序中被多次调用,而不必重新编写该存储过程的SQL语句。而且数据库专业人员可以随时对存储过程进行修改,对应用程序源代码毫无影响。
- 存储过程能实现较快的执行速度。如果某一操作包含大量的Transaction-SQL代码或分别被多次执行,那么存储过程要比批处理的执行速度快很多。因为存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析优化,并且给出最终被存储在系统表中的执行计划。而批处理的Transaction-SQL语句在每次运行时都要进行编译和优化,速度相对要慢一些。
- 存储过程能过减少网络流量。针对同一个数据库对象的操作(如查询、修改),如果这一操作所涉及的Transaction-SQL语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增加了网络流量并降低了网络负载。
- 存储过程可被作为一种安全机制来充分利用。系统管理员通过执行某一存储过程的权限进行限制,能够实现对相应的数据的访问权限的限制,避免了非授权用户对数据的访问,保证了数据的安全。
3.存储过程缺点
- 不易维护,一旦逻辑变了修改起来麻烦
- 如果写此存储过程的人离职了,对于接手她代码的人估计是一场灾难,因为别人还要去读懂你程序逻辑,还要读懂你存储逻辑。不利于扩展。
- 最大的缺点! 虽然存储过程可以减少代码量,提高开发效率。但是有一点非常致命的就是太耗性能。
4.存储过程的语法
a.创建存储过程
create procedure sp_name()
begin
.........
end
b.调用存储过程
call sp_name()
c.删除存储过程
drop procedure sp_name//
d.其他常用命令
显示数据库中所有存储的存储过程基本信息,包括所属数据库,存储过程名称,创建时间等
show procedure status
显示某一个MySQL存储过程的详细信息
show create procedure sp_name
5.Mybatis调用MySQL存储过程
a.mybatis-config.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>
<settings>
<!-- 打印查询语句 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- 配置别名 -->
<typeAliases>
<typeAlias type="com.lidong.axis2demo.DevicePOJO" alias="DevicePOJO" />
</typeAliases>
<!-- 配置环境变量 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?characterEncoding=GBK" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 配置mappers -->
<mappers>
<mapper resource="com/lidong/axis2demo/DeviceMapper.xml" />
</mappers>
</configuration>
b.实体类
public class DevicePOJO{
private String devoceName;//设备名称
private String deviceCount;//设备总数
public String getDevoceName() {return devoceName;}
public void setDevoceName(String devoceName) {
this.devoceName = devoceName;
}
public String getDeviceCount() {return deviceCount;}
public void setDeviceCount(String deviceCount) {
this.deviceCount = deviceCount;
}
}
c.interface
public interface DeviceDAO {
/**
* 调用存储过程 获取设备的总数
* @param devicePOJO
*/
public void count(DevicePOJO devicePOJO);
}
d.Mapper的实现
<?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.lidong.axis2demo.DeviceDAO">
<resultMap id="BaseResultMap" type="CusDevicePOJO">
<result column="device_sn" property="device_sn" jdbcType="VARCHAR" />
</resultMap>
<sql id="Base_Column_List">
device_sn, device_name,device_mac
</sql>
<select id="count" parameterType="DevicePOJO" useCache="false"
statementType="CALLABLE">
<![CDATA[
call countDevicesName(
#{devoceName,mode=IN,jdbcType=VARCHAR},
#{deviceCount,mode=OUT,jdbcType=INTEGER});
]]>
</select>
</mapper>
注意
1.statementType=”CALLABLE” 必须为CALLABLE,告诉MyBatis去执行存储过程, 否则会报错
Exception in thread “main” org.apache.ibatis.exceptions.PersistenceException
2.mode=IN 输入参数 mode=OUT输出参数 jdbcType为数据库定义的字段类型。
这样写 Mybatis会帮助我们自动回填输出的deviceCount的值。
e.测试
public class TestProduce {
private static SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private static SqlSessionFactory sqlSessionFactory;
private static void init() throws IOException {
String resource = "mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
sqlSessionFactory = sqlSessionFactoryBuilder.build(reader);
}
public static void main(String[] args) throws Exception {
testCallProduce();
}
/**
* @throws IOException
*/
private static void testCallProduce() throws IOException {
init();
SqlSession session= sqlSessionFactory.openSession();
DeviceDAO deviceDAO = session.getMapper(DeviceDAO.class);
DevicePOJO device = new DevicePOJO();
device.setDevoceName("设备名称");
deviceDAO.count(device);
System.out.println("获取"+device.getDevoceName()+"设备的总数="+device.getDeviceCount());
}
}
六.$和#两种符号
在Mybatis中,#和$有些区别,总结如下:
1.二者解析不同
使用${}方式传入的参数,mybatis不会对它进行特殊处理,而使用#{}传进来的参数,mybatis默认会将其当成字符串。可能在赋值给如id=#{id}和id=${id}看不出多大区别,但是作为表名或字段参数时可以明显看出,可以看看下面的例子:
假设传入的参数为表名test
selec * from #{table};
解析后是:
select * from "test";
而
select * from ${table};
解析后是:
select * from test;
很明显,前者多了字符串的引号,会失败,后者正常查询会成功;
所以对于传入分组(order)字段或者排序字段(order),应使用${},避免出现order by "id" 等情况。
#和$在预编译处理中是不一样的。#类似jdbc中的PreparedStatement,对于传入的参数,在预处理阶段会使用?代替,比如:
select * from student where id = ?;
待真正查询的时候即在数据库管理系统中(DBMS)才会代入参数。
而${}则是简单的替换,如下:
select * from student where id = 2;
2.适应的场景不同
#{}自动给String类型加单引号 (自动类型转换)
${} 原样输出,但是适合于 动态排序(动态字段)
select stuno,stuname,stuage from student where stuname = #{value}
select stuno,stuname,stuage from student where stuname = '${value}'
动态排序:
select stuno,stuname,stuage from student order by ${value} asc
3.防止SQL注入
所谓sql注入,就是指把用户输入的数据拼接到sql语句后面作为sql语句的一部分执行,例如:
select * from user where name=' "+name+" ' and password=' "+password+" '
那么只要用户输入用户名admin和密码123456' or 'abc' = 'abc',那么拼接出来的语句就为
select * from user where name=' admin ' and password='123456' or 'abc'= 'abc';
这样只要user表有数据,就会返回结果,达到sql注入的目的。同样,用户输入用户名a'则 and password=' "+password+" '就会被注释掉,也达到注入sql的目的。
附:
这里顺带提下防止sql注入的几种方式:
(1)、jdbc使用 PreparedStatement代替Statement, PreparedStatement 不仅提高了代码的可读性和可维护性.而且也提高了安全性,有效防止sql注入;
(2)、在程序代码中使用正则表达式过滤参数。使用正则表达式过滤可能造成注入的符号,如' --等
(3)、在页面输入参数时也进行字符串检测和提交时进行参数检查,同样可以使用正则表达式,不允许特殊符号出现。
Mybatis总结(一)的更多相关文章
- 【分享】标准springMVC+mybatis项目maven搭建最精简教程
文章由来:公司有个实习同学需要做毕业设计,不会搭建环境,我就代劳了,顺便分享给刚入门的小伙伴,我是自学的JAVA,所以我懂的.... (大图直接观看显示很模糊,请在图片上点击右键然后在新窗口打开看) ...
- Java MyBatis 插入数据库返回主键
最近在搞一个电商系统中由于业务需求,需要在插入一条产品信息后返回产品Id,刚开始遇到一些坑,这里做下笔记,以防今后忘记. 类似下面这段代码一样获取插入后的主键 User user = new User ...
- [原创]mybatis中整合ehcache缓存框架的使用
mybatis整合ehcache缓存框架的使用 mybaits的二级缓存是mapper范围级别,除了在SqlMapConfig.xml设置二级缓存的总开关,还要在具体的mapper.xml中开启二级缓 ...
- 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程
本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...
- mybatis plugins实现项目【全局】读写分离
在之前的文章中讲述过数据库主从同步和通过注解来为部分方法切换数据源实现读写分离 注解实现读写分离: http://www.cnblogs.com/xiaochangwei/p/4961807.html ...
- MyBatis基础入门--知识点总结
对原生态jdbc程序的问题总结 下面是一个传统的jdbc连接oracle数据库的标准代码: public static void main(String[] args) throws Exceptio ...
- Mybatis XML配置
Mybatis常用带有禁用缓存的XML配置 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE ...
- MyBatis源码分析(一)开篇
源码学习的好处不用多说,Mybatis源码量少.逻辑简单,将写个系列文章来学习. SqlSession Mybatis的使用入口位于org.apache.ibatis.session包中的SqlSes ...
- (整理)MyBatis入门教程(一)
本文转载: http://www.cnblogs.com/hellokitty1/p/5216025.html#3591383 本人文笔不行,根据上面博客内容引导,自己整理了一些东西 首先给大家推荐几 ...
- MyBatis6:MyBatis集成Spring事物管理(下篇)
前言 前一篇文章<MyBatis5:MyBatis集成Spring事物管理(上篇)>复习了MyBatis的基本使用以及使用Spring管理MyBatis的事物的做法,本文的目的是在这个的基 ...
随机推荐
- asp.net webapi关闭https配置
将s去掉就行
- 《C++ 程序设计》读书笔记
本文联合编辑:小辣辣.向她致以最崇高的敬(爱)意 第一章 C++的初步认识 在程序进行编译时,先对所有的预处理命令进行处理,将头文件的具体内容代替 #include 指令,然后再对该程序单元进行整体编 ...
- 线程 - AtomicInteger
原理 AtomicInteger是如何使用非阻塞算法来实现并发控制的 性能提升 避免多线程的优先级倒置和死锁情况的发生 任然可能存在问题 ABA问题 CAS原理 调整具有竞争的并发应用程序的可伸缩性的 ...
- 10分钟带你入门git到github
git的产生背景 开局先来一个故事吧,故事看完如果不想看枯燥无味的指令,没关系我已经把这篇文章的内容录制成了一个视频,点击文末阅读原文就可以观看.或者说你已经熟练掌握git的使用了,可以直接跳到总结部 ...
- MM-RFQ询价报价
(1).询价报价单事务码:ME41/ME42/ME43 需要的主数据:采购组织.供应商.采购组,物料 (2)ME47:维护供应商的报价.可以用项目明细的条件对供应商的报价进行详细设置. (3)供应商价 ...
- git fork , git pull request那回事
git fork 原理 相当于你在原项目的主分支上又建立了一个分支,你可以在该分支上任意修改,如果想将你的修改合并到原项目中时,可以pull request,这样原项目的作者就可以将你修改的东西合并到 ...
- 前端学习总结之——HTML
近期在找工作参加面试,想总结一下学过的东西,也会持续更新遇到的新问题.盲点. 什么是HTML? 超文本标记语言(英语:HyperText Markup Language,简称:HTML),由尖括号包围 ...
- 树莓派(4B)新手入门教程
前期准备 必要物料 树莓派4B 主机 Type-C 电源 内存卡(8G+) 一般建议一步到位64G 系统镜像 镜像写入工具 下载地址 镜像下载 官方下载地址: https://www.raspberr ...
- 免费、开源的基于tp5的快速开发框架
HisiPHP 系统官网:https://www.hisiphp.com/ 后台体验:http://v2.demo.hisiphp.com/admin.php/system/publics/index ...
- LeetCode150 逆波兰表达式求值
根据逆波兰表示法,求表达式的值. 有效的运算符包括 +, -, *, / .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 说明: 整数除法只保留整数部分. 给定逆波兰表达式总是有效的.换句话说 ...