MyBatis学习总结(二)——MyBatis核心配置文件与输入输出映射
在上一章中我们学习了《mybatis学习总结(一)——orm概要与mybatis快速起步》,这一章主要是介绍mybatis核心配置文件、使用接口+xml实现完整数据访问、输入参数映射与输出结果映射等内容。
一、mybatis配置文件概要
mybatis核心配置文件在初始化时会被引用,在配置文件中定义了一些参数,当然可以完全不需要配置文件,全部通过编码实现,该配置文件主要是是起到解偶的作用。如第一讲中我们用到conf.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> <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/nfmall?useunicode=true&characterencoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </datasource> </environment> </environments> <mappers> <!--<mapper resource="mapper/studentmapper.xml"/>--> <mapper class="com.zhangguo.mybatis02.dao.studentmapper"></mapper> </mappers> </configuration>
mybatis 的配置文件包含了会深深影响 mybatis 行为的设置(settings)和属性(properties)信息。文档的顶层结构如下::
- configuration 配置
- typealiases 类型别名
- typehandlers 类型处理器
- objectfactory 对象工厂
-
- environment 环境变量
- transactionmanager 事务管理器
- datasource 数据源
- environment 环境变量
- databaseidprovider 数据库厂商标识
二、mybatis配置文件详解
。
2.1、properties属性
作用:将数据连接单独配置在db.properties中,只需要在mybatisconfig.xml中加载db.properties的属性值,在mybatisconfig.xml中就不需要对数据库连接参数进行硬编码。数据库连接参数只配置在db.properties中,方便对参数进行统一管理,其它xml可以引用该db.properties。
db.properties的内容:
##mysql连接字符串 #驱动 mysql.driver=com.mysql.jdbc.driver #地址 mysql.url=jdbc:mysql://127.0.0.1:3306/nfmall?useunicode=true&characterencoding=utf-8 #用户名 mysql.username=root #密码 mysql.password=uchr@123
在mybatisconfig.xml中加载db.properties
<?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> <!--导入db.properties文件中的所有key-value数据--> <properties resource="db.properties"> <!--定义一个名称为driver,值为com.mysql.jdbc.driver的属性--> <property name="driver" value="com.mysql.jdbc.driver"></property> </properties> <!--环境配置,default为默认选择的环境--> <environments default="work"> <!--开发--> <environment id="development"> <!--事务管理--> <transactionmanager type="jdbc"/> <!--连接池--> <datasource type="pooled"> <!--引用属性${mysql.driver}--> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </datasource> </environment> <!--运行--> <environment id="work"> <transactionmanager type="jdbc"/> <datasource type="pooled"> <property name="driver" value="${driver}"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/nfmall?useunicode=true&characterencoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </datasource> </environment> </environments> <mappers> <!--<mapper resource="mapper/studentmapper.xml"/>--> <mapper class="com.zhangguo.mybatis02.dao.studentmapper"></mapper> </mappers> </configuration>
properties特性:
注意:
- 在properties元素体内定义的属性优先读取。
- 然后读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性。
- 最后读取parametertype传递的属性,它会覆盖已读取的同名属性
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。
在properties文件中定义属性名要有一定的特殊性,如xxxx.xxxx(jdbc.driver)
2.2、settings全局参数配置
mybatis框架运行时可以调整一些运行参数。比如,开启二级缓存,开启延迟加载等等。全局参数会影响mybatis的运行行为。
mybatis-settings的配置属性以及描述
setting(设置) | description(描述) | valid values(验证值组) | default(默认值) |
cacheenabled | 在全局范围内启用或禁用缓存配置 任何映射器在此配置下。 | true | false | true |
lazyloadingenabled | 在全局范围内启用或禁用延迟加载。禁用时,所有相关联的将热加载。 | true | false | true |
aggressivelazyloading | 启用时,有延迟加载属性的对象将被完全加载后调用懒惰的任何属性。否则,每一个属性是按需加载。 | true | false | true |
multipleresultsetsenabled | 允许或不允许从一个单独的语句(需要兼容的驱动程序)要返回多个结果集。 | true | false | true |
usecolumnlabel | 使用列标签,而不是列名。在这方面,不同的驱动有不同的行为。参考驱动文档或测试两种方法来决定你的驱动程序的行为如何。 | true | false | true |
usegeneratedkeys | 允许jdbc支持生成的密钥。兼容的驱动程序是必需的。此设置强制生成的键被使用,如果设置为true,一些驱动会不兼容性,但仍然可以工作。 | true | false | false |
automappingbehavior | 指定mybatis的应如何自动映射列到字段/属性。none自动映射。 partial只会自动映射结果没有嵌套结果映射定义里面。 full会自动映射的结果映射任何复杂的(包含嵌套或其他)。 |
none,partial,full |
partial |
defaultexecutortype | 配置默认执行人。simple执行人确实没有什么特别的。 reuse执行器重用准备好的语句。 batch执行器重用语句和批处理更新。 |
simple,reuse,batch |
simple |
saferowboundsenabled | 允许使用嵌套的语句rowbounds。 | true | false | false |
mapunderscoretocamelcase | 从经典的数据库列名a_column启用自动映射到骆驼标识的经典的java属性名acolumn。 | true | false | false |
localcachescope | mybatis的使用本地缓存,以防止循环引用,并加快反复嵌套查询。默认情况下(session)会话期间执行的所有查询缓存。如果localcachescope=statment本地会话将被用于语句的执行,只是没有将数据共享之间的两个不同的调用相同的sqlsession。 |
session statement |
session |
dbctypefornull | 指定为空值时,没有特定的jdbc类型的参数的jdbc类型。有些驱动需要指定列的jdbc类型,但其他像null,varchar或other的工作与通用值。 | jdbctype enumeration. most common are: null, varchar and other | other |
lazyloadtriggermethods | 指定触发延迟加载的对象的方法。 | a method name list separated by commas | equals,clone,hashcode,tostring |
defaultscriptinglanguage | 指定所使用的语言默认为动态sql生成。 | a type alias or fully qualified class name. |
org.apache.ibatis.scripting.xmltags .xmldynamiclanguagedriver |
callsettersonnulls | 指定如果setter方法或map的put方法时,将调用检索到的值是null。它是有用的,当你依靠map.keyset()或null初始化。注意(如整型,布尔等)不会被设置为null。 | true | false | false |
logprefix | 指定的前缀字串,mybatis将会增加记录器的名称。 | any string | not set |
logimpl | 指定mybatis的日志实现使用。如果此设置是不存在的记录的实施将自动查找。 | slf4j | log4j | log4j2 | jdk_logging | commons_logging | stdout_logging | no_logging | not set |
proxyfactory | 指定代理工具,mybatis将会使用创建懒加载能力的对象。 | cglib | javassist | cglib |
官方文档settings的例子:
<setting name="cacheenabled" value="true"/> <setting name="lazyloadingenabled" value="true"/> <setting name="multipleresultsetsenabled" value="true"/> <setting name="usecolumnlabel" value="true"/> <setting name="usegeneratedkeys" value="false"/> <setting name="automappingbehavior" value="partial"/> <setting name="defaultexecutortype" value="simple"/> <setting name="defaultstatementtimeout" value="25"/> <setting name="saferowboundsenabled" value="false"/> <setting name="mapunderscoretocamelcase" value="false"/> <setting name="localcachescope" value="session"/> <setting name="jdbctypefornull" value="other"/> <setting name="lazyloadtriggermethods" value="equals,clone,hashcode,tostring"/> </settings>
示例:
这里设置mybatis的日志输出到控制台:
<!--外部引入的内容将覆盖内部定义的--> <properties resource="db.properties"> <!--定义一个名称为driver,值为com.mysql.jdbc.driver的属性--> <property name="mysql.driver" value="com.mysql.jdbc.driver"></property> </properties> <settings> <!--设置是否允许缓存--> <setting name="cacheenabled" value="true"/> <!--设置日志输出的目标--> <setting name="logimpl" value="stdout_logging"/> </settings>
结果:
2.3、typeaiases(别名)
在mapper.xml中,定义很多的statement,statement需要parametertype指定输入参数的类型、需要resulttype指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parametertype或resulttype指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。
如下所示类型com.zhangguo.mybatis02.entities.student会反复出现,冗余:
<?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.zhangguo.mybatis02.mapper.studentmapper"> <select id="selectstudentbyid" resulttype="com.zhangguo.mybatis02.entities.student"> select id,name,sex from student where id=#{id} </select> <select id="selectstudentsbyname" parametertype="string" resulttype="com.zhangguo.mybatis02.entities.student"> select id,name,sex from student where name like '%${value}%'; </select> <insert id="insertstudent" parametertype="com.zhangguo.mybatis02.entities.student"> insert into student(name,sex) values(#{name},'${sex}') </insert> <update id="updatestudent" parametertype="com.zhangguo.mybatis02.entities.student"> update student set name=#{name},sex=#{sex} where id=#{id} </update> <delete id="deletestudent" parametertype="int"> delete from student where id=#{id} </delete> </mapper>
2.3.1.mybatis默认支持的别名
别名 |
映射的类型 |
_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 |
2.3.2.自定义别名
(一)、单个别名定义(在mybatisconfig.xml)
<settings> <!--设置是否允许缓存--> <setting name="cacheenabled" value="true"/> <!--设置日志输出的目标--> <setting name="logimpl" value="stdout_logging"/> </settings> <!--别名--> <typealiases> <!--定义单个别名,指定名称为student,对应的类型为com.zhangguo.mybatis02.entities.student--> <typealias type="com.zhangguo.mybatis02.entities.student" alias="student"></typealias> </typealiases>
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.zhangguo.mybatis02.mapper.studentmapper"> <select id="selectstudentbyid" resulttype="student"> select id,name,sex from student where id=#{id} </select> <select id="selectstudentsbyname" parametertype="string" resulttype="student"> select id,name,sex from student where name like '%${value}%'; </select> <insert id="insertstudent" parametertype="student"> insert into student(name,sex) values(#{name},'${sex}') </insert> <update id="updatestudent" parametertype="student"> update student set name=#{name},sex=#{sex} where id=#{id} </update> <delete id="deletestudent" parametertype="int"> delete from student where id=#{id} </delete> </mapper>
(二)批量定义别名,扫描指定的包
定义单个别名的缺点很明显,如果项目中有很多别名则需要一个一个定义,且修改类型了还要修改配置文件非常麻烦,可以指定一个包,将下面所有的类都按照一定的规则定义成别名:
<settings> <!--设置是否允许缓存--> <setting name="cacheenabled" value="true"/> <!--设置日志输出的目标--> <setting name="logimpl" value="stdout_logging"/> </settings> <!--别名--> <typealiases> <!--定义单个别名,指定名称为student,对应的类型为com.zhangguo.mybatis02.entities.student--> <!--<typealias type="com.zhangguo.mybatis02.entities.student" alias="student"></typealias>--> <!--指定包名下所有的类被自动扫描并定义默认别名, mybatis会自动扫描包中的pojo类,自动定义别名,别名就是类名(首字母大写或小写都可以)--> <package name="com.zhangguo.mybatis02.entities"></package> </typealiases>
如果com.zhangguo.mybatis02.entities包下有一个名为student的类,则使用别名时可以是:student,或student。
你一定会想到当两个名称相同时的冲突问题,可以使用注解解决
解决方法:
2.4、typehandlers(类型处理器)
mybatis中通过typehandlers完成jdbc类型和java类型的转换。
通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义.
mybatis支持类型处理器:
类型处理器 |
java类型 |
jdbc类型 |
booleantypehandler |
boolean,boolean |
任何兼容的布尔值 |
bytetypehandler |
byte,byte |
任何兼容的数字或字节类型 |
shorttypehandler |
short,short |
任何兼容的数字或短整型 |
integertypehandler |
integer,int |
任何兼容的数字和整型 |
longtypehandler |
long,long |
任何兼容的数字或长整型 |
floattypehandler |
float,float |
任何兼容的数字或单精度浮点型 |
doubletypehandler |
double,double |
任何兼容的数字或双精度浮点型 |
bigdecimaltypehandler |
bigdecimal |
任何兼容的数字或十进制小数类型 |
stringtypehandler |
string |
char和varchar类型 |
clobtypehandler |
string |
clob和longvarchar类型 |
nstringtypehandler |
string |
nvarchar和nchar类型 |
nclobtypehandler |
string |
nclob类型 |
bytearraytypehandler |
byte[] |
任何兼容的字节流类型 |
blobtypehandler |
byte[] |
blob和longvarbinary类型 |
datetypehandler |
date(java.util) |
timestamp类型 |
dateonlytypehandler |
date(java.util) |
date类型 |
timeonlytypehandler |
date(java.util) |
time类型 |
sqltimestamptypehandler |
timestamp(java.sql) |
timestamp类型 |
sqldatetypehandler |
date(java.sql) |
date类型 |
sqltimetypehandler |
time(java.sql) |
time类型 |
objecttypehandler |
任意 |
其他或未指定类型 |
enumtypehandler |
enumeration类型 |
varchar-任何兼容的字符串类型,作为代码存储(而不是索引)。 |
2.5、mappers(映射配置)
映射配置可以有多种方式,如下xml配置所示:
<!-- 将sql映射注册到全局配置中--> <mappers> <!-- mapper 单个注册(mapper如果多的话,不太可能用这种方式) resource:引用类路径下的文件 url:引用磁盘路径下的资源 class,引用接口 package 批量注册(基本上使用这种方式) name:mapper接口与mapper.xml所在的包名 --> <!-- 第一种:注册sql映射文件--> <mapper resource="com/zhangguo/mapper/usermapper.xml" /> <!-- 第二种:注册接口sql映射文件必须与接口同名,并且放在同一目录下--> <mapper class="com.zhangguo.mapper.usermapper" /> <!-- 第三种:注册基于注解的接口 基于注解 没有sql映射文件,所有的sql都是利用注解写在接口上--> <mapper class="com.zhangguo.mapper.teachermapper" /> <!-- 第四种:批量注册 需要将sql配置文件和接口放到同一目录下--> <package name="com.zhangguo.mapper" /> </mappers>
2.5.1、通过resource加载单个映射文件
<mappers> <!--根据路径注册一个基于xml的映射器--> <mapper resource="mapper/studentmapper.xml"/> </mappers>
注意位置
2.5.2:通过mapper接口加载单个映射文件
<!-- 通过mapper接口加载单个映射配置文件 遵循一定的规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中; 上边规范的前提是:使用的是mapper代理方法; --> <mapper class="com.mybatis.mapper.usermapper"/>
按照上边的规范,将mapper.java和mapper.xml放在一个目录 ,且同名。
注意:
对于maven项目,intellij idea默认是不处理src/main/java中的非java文件的,不专门在pom.xml中配置<resources>是会报错的,参考处理办法:
<resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources>
所以src/main/java中最好不要出现非java文件。实际上,将mapper.xml放在src/main/resources中比较合适。
2.5.3、批量加载mapper
<!-- 批量加载映射配置文件,mybatis自动扫描包下面的mapper接口进行加载 遵循一定的规范:需要将mapper接口类名和mapper.xml映射文件名称保持一致,且在一个目录中; 上边规范的前提是:使用的是mapper代理方法; --> <package name="com.mybatis.mapper"/>
最后的配置文件:
<?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> <!--导入db.properties文件中的所有key-value数据--> <!--外部引入的内容将覆盖内部定义的--> <properties resource="db.properties"> <!--定义一个名称为driver,值为com.mysql.jdbc.driver的属性--> <property name="mysql.driver" value="com.mysql.jdbc.driver"></property> </properties> <settings> <!--设置是否允许缓存--> <setting name="cacheenabled" value="true"/> <!--设置日志输出的目标--> <setting name="logimpl" value="stdout_logging"/> </settings> <!--别名--> <typealiases> <!--定义单个别名,指定名称为student,对应的类型为com.zhangguo.mybatis02.entities.student--> <!--<typealias type="com.zhangguo.mybatis02.entities.student" alias="student"></typealias>--> <!--指定包名下所有的类被自动扫描并定义默认别名, mybatis会自动扫描包中的pojo类,自动定义别名,别名就是类名(首字母大写或小写都可以)--> <package name="com.zhangguo.mybatis02.entities"></package> </typealiases> <!--注册自定义的类型处理器--> <typehandlers> <!--<typehandler handler="" javatype="" jdbctype=""></typehandler>--> </typehandlers> <!--环境配置,default为默认选择的环境--> <environments default="development"> <!--开发--> <environment id="development"> <!--事务管理--> <transactionmanager type="jdbc"/> <!--连接池--> <datasource type="pooled"> <!--引用属性${mysql.driver}--> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </datasource> </environment> <!--运行--> <environment id="work"> <transactionmanager type="jdbc"/> <datasource type="pooled"> <property name="driver" value="${driver}"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/nfmall?useunicode=true&characterencoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </datasource> </environment> </environments> <mappers> <!--根据路径注册一个基于xml的映射器--> <mapper resource="mapper/studentmapper.xml"/> <!--根据类型注册一个基于注解的映射器,接口--> <mapper class="com.zhangguo.mybatis02.dao.studentmapper"></mapper> <!--根据包名批量注册包下所有基于注解的映射器--> <package name="com.zhangguo.mybatis02.dao"></package> </mappers> </configuration>
三、使用接口+xml实现完整数据访问
上一章中使用xml作为映射器与使用接口加注解的形式分别实现了完整的数据访问,可以点击《mybatis学习总结(一)——orm概要与mybatis快速起步》查看,这里综合两种方式实现数据访问,各取所长,配置灵活,在代码中不需要引用很长的id名称,面向接口编程,示例如下:
3.1、在idea中创建一个maven项目
创建成功的目录结构如下:
3.2、添加依赖
pom.xml文件如下:
<?xml version="1.0" encoding="utf-8"?> <project xmlns="http://maven.apache.org/pom/4.0.0" xmlns:xsi="http://www.w3.org/2001/xmlschema-instance" xsi:schemalocation="http://maven.apache.org/pom/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelversion>4.0.0</modelversion> <groupid>com.zhangguo.mybatis03</groupid> <artifactid>mybatis03</artifactid> <version>1.0-snapshot</version> <dependencies> <!--mybatis --> <dependency> <groupid>org.mybatis</groupid> <artifactid>mybatis</artifactid> <version>3.4.6</version> </dependency> <!--mysql数据库驱动 --> <dependency> <groupid>mysql</groupid> <artifactid>mysql-connector-java</artifactid> <version>5.1.38</version> </dependency> <!-- junit单元测试工具 --> <dependency> <groupid>junit</groupid> <artifactid>junit</artifactid> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
添加成功效果如下:
3.3、创建pojo类
学生pojo类如下:
package com.zhangguo.mybatis03.entities; /** * 学生实体 */ public class student { private int id; private string name; private string sex; public int getid() { return id; } public void setid(int id) { this.id = id; } public string getname() { return name; } public void setname(string name) { this.name = name; } public string getsex() { return sex; } public void setsex(string sex) { this.sex = sex; } @override public string tostring() { return "student{" + "id=" + id + ", name='" + name + '\'' + ", sex='" + sex + '\'' + '}'; } }
3.4、创建数据访问接口
studentmapper.java:
package com.zhangguo.mybatis03.dao; import com.zhangguo.mybatis03.entities.student; import java.util.list; public interface studentmapper { /** * 根据学生编号获得学生对象 */ student selectstudentbyid(int id); /** * 根据学生姓名获得学生集合 */ list<student> selectstudentsbyname(string name); /** * 添加学生 */ int insertstudent(student entity); /** * 更新学生 */ int updatestudent(student entity); /** * 删除学生 */ int deletestudent(int id); }
3.5、根据接口编写xml映射器
要求方法名与id同名,包名与namespace同名。
在src/main/resources/mapper目录下创建studentmapper.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.zhangguo.mybatis03.dao.studentmapper"> <select id="selectstudentbyid" resulttype="student"> select id,name,sex from student where id=#{id} </select> <select id="selectstudentsbyname" parametertype="string" resulttype="student"> select id,name,sex from student where name like '%${value}%'; </select> <insert id="insertstudent" parametertype="student"> insert into student(name,sex) values(#{name},'${sex}') </insert> <update id="updatestudent" parametertype="student"> update student set name=#{name},sex=#{sex} where id=#{id} </update> <delete id="deletestudent" parametertype="int"> delete from student where id=#{id} </delete> </mapper>
3.6、添加mybatis核心配置文件
在src/main/resources目录下创建两个配置文件。
mybatiscfg.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> <!--导入db.properties文件中的所有key-value数据--> <!--外部引入的内容将覆盖内部定义的--> <properties resource="db.properties"> <!--定义一个名称为driver,值为com.mysql.jdbc.driver的属性--> <property name="mysql.driver" value="com.mysql.jdbc.driver"></property> </properties> <settings> <!--设置是否允许缓存--> <setting name="cacheenabled" value="true"/> <!--设置日志输出的目标--> <setting name="logimpl" value="stdout_logging"/> </settings> <!--别名--> <typealiases> <!--定义单个别名,指定名称为student,对应的类型为com.zhangguo.mybatis02.entities.student--> <!--<typealias type="com.zhangguo.mybatis02.entities.student" alias="student"></typealias>--> <!--指定包名下所有的类被自动扫描并定义默认别名, mybatis会自动扫描包中的pojo类,自动定义别名,别名就是类名(首字母大写或小写都可以)--> <package name="com.zhangguo.mybatis03.entities"></package> </typealiases> <!--注册自定义的类型处理器--> <typehandlers> <!--<typehandler handler="" javatype="" jdbctype=""></typehandler>--> </typehandlers> <!--环境配置,default为默认选择的环境--> <environments default="development"> <!--开发--> <environment id="development"> <!--事务管理--> <transactionmanager type="jdbc"/> <!--连接池--> <datasource type="pooled"> <!--引用属性${mysql.driver}--> <property name="driver" value="${mysql.driver}"/> <property name="url" value="${mysql.url}"/> <property name="username" value="${mysql.username}"/> <property name="password" value="${mysql.password}"/> </datasource> </environment> <!--运行--> <environment id="work"> <transactionmanager type="jdbc"/> <datasource type="pooled"> <property name="driver" value="${driver}"/> <property name="url" value="jdbc:mysql://127.0.0.1:3306/nfmall?useunicode=true&characterencoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="uchr@123"/> </datasource> </environment> </environments> <mappers> <!--根据路径注册一个基于xml的映射器--> <mapper resource="mapper/studentmapper.xml"/> </mappers> </configuration>
db.properties文件内容如下:
##mysql连接字符串 #驱动 mysql.driver=com.mysql.jdbc.driver #地址 mysql.url=jdbc:mysql://127.0.0.1:3306/nfmall?useunicode=true&characterencoding=utf-8 #用户名 mysql.username=root #密码 mysql.password=uchr@123
3.7、编写mybatis通用的工具类
sqlsessionfactoryutil.java内容如下:
package com.zhangguo.mybatis03.utils; import org.apache.ibatis.session.sqlsession; import org.apache.ibatis.session.sqlsessionfactory; import org.apache.ibatis.session.sqlsessionfactorybuilder; import java.io.ioexception; import java.io.inputstream; /** * mybatis 会话工具类 * */ public class sqlsessionfactoryutil { /** * 获得会话工厂 * * */ public static sqlsessionfactory getfactory(){ inputstream inputstream = null; sqlsessionfactory sqlsessionfactory=null; try{ //加载mybatiscfg.xml配置文件,转换成输入流 inputstream = sqlsessionfactoryutil.class.getclassloader().getresourceasstream("mybatiscfg.xml"); //根据配置文件的输入流构造一个sql会话工厂 sqlsessionfactory = new sqlsessionfactorybuilder().build(inputstream); } finally { if(inputstream!=null){ try { inputstream.close(); } catch (ioexception e) { e.printstacktrace(); } } } return sqlsessionfactory; } /** * 获得sql会话,是否自动提交 * */ public static sqlsession opensession(boolean isautocommit){ return getfactory().opensession(isautocommit); } /** * 关闭会话 * */ public static void closesession(sqlsession session){ if(session!=null){ session.close(); } } }
3.8、通过mybatis实现数据访问
studentdao.java内容如下:
package com.zhangguo.mybatis03.dao; import com.zhangguo.mybatis03.entities.student; import com.zhangguo.mybatis03.utils.sqlsessionfactoryutil; import org.apache.ibatis.session.sqlsession; import java.util.list; public class studentdao implements studentmapper { /** * 根据学生编号获得学生对象 */ public student selectstudentbyid(int id) { student entity = null; //打开一个会话 sqlsession session = sqlsessionfactoryutil.opensession(true); //获得一个映射器 studentmapper mapper=session.getmapper(studentmapper.class); //查询单个对象,指定参数为3 entity = mapper.selectstudentbyid(id); //关闭 sqlsessionfactoryutil.closesession(session); return entity; } /** * 根据学生姓名获得学生集合 */ public list<student> selectstudentsbyname(string name) { list<student> entities = null; //打开一个会话 sqlsession session = sqlsessionfactoryutil.opensession(true); //获得一个映射器 studentmapper mapper=session.getmapper(studentmapper.class); //查询多个对象,指定参数 entities =mapper.selectstudentsbyname(name); //关闭 sqlsessionfactoryutil.closesession(session); return entities; } /** * 添加学生 */ public int insertstudent(student entity) { //影响行数 int rows=0; //打开一个会话 sqlsession session = sqlsessionfactoryutil.opensession(true); //获得一个映射器 studentmapper mapper=session.getmapper(studentmapper.class); //执行添加 rows = mapper.insertstudent(entity); //关闭 sqlsessionfactoryutil.closesession(session); return rows; } /** * 更新学生 */ public int updatestudent(student entity) { //影响行数 int rows=0; //打开一个会话 sqlsession session = sqlsessionfactoryutil.opensession(true); //获得一个映射器 studentmapper mapper=session.getmapper(studentmapper.class); //执行更新 rows =mapper.updatestudent(entity); //关闭 sqlsessionfactoryutil.closesession(session); return rows; } /** * 删除学生 */ public int deletestudent(int id) { //影响行数 int rows=0; //打开一个会话 sqlsession session = sqlsessionfactoryutil.opensession(true); //获得一个映射器 studentmapper mapper=session.getmapper(studentmapper.class); //执行删除 rows = mapper.deletestudent(id); //关闭 sqlsessionfactoryutil.closesession(session); return rows; } }
最后完成的项目结构:
3.9、测试用例
在测试类上添加注解@fixmethodorder(methodsorters.jvm)的目的是指定测试方法按定义的顺序执行。
studentdaotest.java如下所示:
package com.zhangguo.mybatis03.dao; import com.zhangguo.mybatis03.entities.student; import org.junit.*; import org.junit.runners.methodsorters; import java.util.list; /** * studentdao tester. * * @author <authors name> * @version 1.0 * @since <pre>09/26/2018</pre> */ @fixmethodorder(methodsorters.jvm)//指定测试方法按定义的顺序执行 public class studentdaotest { studentmapper dao; @before public void before() throws exception { dao=new studentdao(); } @after public void after() throws exception { } /** * method: selectstudentbyid(int id) */ @test public void testselectstudentbyid() throws exception { student entity=dao.selectstudentbyid(1); system.out.println(entity); assert.assertnotnull(entity); } /** * method: selectstudentsbyname(string name) */ @test public void testselectstudentsbyname() throws exception { list<student> students=dao.selectstudentsbyname("c"); system.out.println(students); assert.assertnotnull(students); } /** * method: insertstudent */ @test public void testinsertstudent() throws exception { student entity=new student(); entity.setname("张大"); entity.setsex("boy"); assert.assertequals(1,dao.insertstudent(entity)); } /** * method: updatestudent */ @test public void testupdatestudent() throws exception { student entity=dao.selectstudentbyid(11); entity.setname("张丽美"); entity.setsex("girl"); assert.assertequals(1,dao.updatestudent(entity)); } /** * method: deletestudent */ @test public void testdeletestudent() throws exception { assert.assertequals(1,dao.deletestudent(12)); } }
3.10、测试结果
测试前的数据库:
测试结果:
日志:
"c:\program files\java\jdk1.8.0_111\bin\java" -ea -didea.test.cyclic.buffer.size=1048576 "-javaagent:c:\program files\jetbrains\intellij idea 2017.2.1\lib\idea_rt.jar=2783:c:\program files\jetbrains\intellij idea 2017.2.1\bin" -dfile.encoding=utf-8 -classpath "c:\program files\jetbrains\intellij idea 2017.2.1\lib\idea_rt.jar;c:\program files\jetbrains\intellij idea 2017.2.1\plugins\junit\lib\junit-rt.jar;c:\program files\jetbrains\intellij idea 2017.2.1\plugins\junit\lib\junit5-rt.jar;c:\program files\java\jdk1.8.0_111\jre\lib\charsets.jar;c:\program files\java\jdk1.8.0_111\jre\lib\deploy.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\access-bridge-64.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\cldrdata.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\dnsns.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\jaccess.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\jfxrt.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\localedata.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\nashorn.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\sunec.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\sunjce_provider.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\sunmscapi.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\sunpkcs11.jar;c:\program files\java\jdk1.8.0_111\jre\lib\ext\zipfs.jar;c:\program files\java\jdk1.8.0_111\jre\lib\javaws.jar;c:\program files\java\jdk1.8.0_111\jre\lib\jce.jar;c:\program files\java\jdk1.8.0_111\jre\lib\jfr.jar;c:\program files\java\jdk1.8.0_111\jre\lib\jfxswt.jar;c:\program files\java\jdk1.8.0_111\jre\lib\jsse.jar;c:\program files\java\jdk1.8.0_111\jre\lib\management-agent.jar;c:\program files\java\jdk1.8.0_111\jre\lib\plugin.jar;c:\program files\java\jdk1.8.0_111\jre\lib\resources.jar;c:\program files\java\jdk1.8.0_111\jre\lib\rt.jar;d:\documents\downloads\compressed\mybatis03\target\test-classes;d:\documents\downloads\compressed\mybatis03\target\classes;c:\users\administrator\.m2\repository\org\mybatis\mybatis\3.4.6\mybatis-3.4.6.jar;c:\users\administrator\.m2\repository\mysql\mysql-connector-java\5.1.38\mysql-connector-java-5.1.38.jar;c:\users\administrator\.m2\repository\junit\junit\4.11\junit-4.11.jar;c:\users\administrator\.m2\repository\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar" com.intellij.rt.execution.junit.junitstarter -ideversion5 -junit4 com.zhangguo.mybatis03.dao.studentdaotest logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 662822946. ==> preparing: delete from student where id=? ==> parameters: 12(integer) <== updates: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@2781e022] returned connection 662822946 to pool. logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 1045941616. ==> preparing: select id,name,sex from student where id=? ==> parameters: 11(integer) <== columns: id, name, sex <== row: 11, lili, secret <== total: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@3e57cd70] returned connection 1045941616 to pool. logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 1540270363. ==> preparing: update student set name=?,sex=? where id=? ==> parameters: 张丽美(string), girl(string), 11(integer) <== updates: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@5bcea91b] returned connection 1540270363 to pool. logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 681384962. ==> preparing: insert into student(name,sex) values(?,'boy') ==> parameters: 张大(string) <== updates: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@289d1c02] returned connection 681384962 to pool. logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 428910174. ==> preparing: select id,name,sex from student where name like '%c%'; ==> parameters: <== columns: id, name, sex <== row: 4, candy, secret <== total: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@1990a65e] returned connection 428910174 to pool. [student{id=4, name='candy', sex='secret'}] logging initialized using 'class org.apache.ibatis.logging.stdout.stdoutimpl' adapter. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. pooleddatasource forcefully closed/removed all connections. opening jdbc connection created connection 1134612201. ==> preparing: select id,name,sex from student where id=? ==> parameters: 1(integer) <== columns: id, name, sex <== row: 1, rose, girl <== total: 1 closing jdbc connection [com.mysql.jdbc.jdbc4connection@43a0cee9] returned connection 1134612201 to pool. student{id=1, name='rose', sex='girl'} process finished with exit code 0
测试后的数据库:
四、mybatis输入输出映射
4.1、输入映射
通过parametertype指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。
mybatis的配置文件中的select,insert,update,delete有一个属性parameter来接收mapper接口方法中的参数。可以接收的类型有简单类型和复杂类型,但是只能是一个参数。这个属性是可选的,因为mybatis可以通过typehandler来判断传入的参数类型,默认值是unset。
4.1.1、基本类型
各种java的基本数据类型。常用的有int、string、data等
接口:
/** * 根据学生编号获得学生对象 */ student selectstudentbyid(int id);
映射:
<select id="selectstudentbyid" resulttype="student" parametertype="int"> select id,name,sex from student where id=#{id} </select>
测试:
/** * method: selectstudentbyid(int id) */ @test public void testselectstudentbyid() throws exception { student entity=dao.selectstudentbyid(1); system.out.println(entity); assert.assertnotnull(entity); }
结果:
用#{变量名}来取值,这里的变量名是任意的,可以用value或者是其它的什么值,这里用id是为了便于理解,并不存在什么对应关系的。因为java反射主只能够得到方法参数的类型,而无从知道参数的名字的。当在动态sql中的if语句中的test传递参数时,就必须要用_parameter来传递参数了(ognl表达式),如果你传入id就会报错。
4.1.2、多个参数
(一)、旧版本mybatis使用索引号:
<select id="selectst
相关文章:
-
-
使用mybatis报错【Result Maps collection already contains value for ...BaseResultMap】的解决方法
这个问题,相信大家在使用mybatis的重新生成 dao,pojo,mapper的时候,都有可能会遇见。 开发过程中,我们改修了表结构,需要重新生成... [阅读全文] -
shiro源码篇 - shiro的session管理,你值得拥有
前言 开心一刻 开学了,表弟和同学因为打架,老师让他回去叫家长。表弟硬气的说:不用,我打得过他。老师板着脸对他说:和你打架的那位同学已经回去叫家长了... [阅读全文] -
1.目录 2.User.java 1 package com.itheima.domain; 2 3 public class User { 4 5... [阅读全文]
-
1 import java.math.BigDecimal; 2 import java.text.DecimalFormat; 3 import ... [阅读全文]
-
Spring Boot简介: Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的初始搭建以及开发过... [阅读全文]
-
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论