Mybatis使用详解
1.下载相对应的Mybatis包与数据库驱动包
2.创建实体类
3.创建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/>
<!-- setting标签修改 MyBatis在运行时的行为方式 -->
<settings>
<!-- 指定MyBatis应该使用哪个日志实现。如果此设置不存在,将自动发现日志记录实现 -->
<!-- 后台输出详细sql执行信息 -->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 实例,详细信息参考mybatisAPI -->
<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>
<!-- 类型别名,给Java类型起一个简短名称代替,只与XML配置相关,减少完全限定名 -->
<typeAliases>
<typeAlias type="entiy.Websites" alias="we"/>
</typeAliases>
<!-- 环境集合属性对象,可配置多种环境,但只能为每一个SqlSessionFactory实例选择一个。 -->
<environments default="mysqlTest">
<!-- 默认的环境和环境 ID 是自我解释的。你可以使用你喜欢的名称来命名,只要确定默认的要匹配其中之一 -->
<environment id="mysqlTest">
<!-- JDBC的事务管理 -->
<transactionManager type="JDBC">
</transactionManager>
<!-- 数据源 -->
<dataSource type="POOLED">
<property name="url" value="${url}"/>
<property name="driver" value="${driver}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
<environment id="oracleTest">
<!-- 创建的Oracle连接,相应的也要闯将一个SqlSessionFactory -->
<transactionManager type="JDBC">
</transactionManager>
<dataSource type="POOLED">
<property name="url" value="jdbc:oracle:thin:@localhost:1521:adminDBTest"/>
<property name="driver" value="oracle.jdbc.OracleDriver"/>
<property name="username" value="Admin"/>
<property name="password" value="admin000"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件,选择一种即可 -->
<mappers>
<!-- 使用类路径相关资源 -->
<mapper resource="com/test/WebsitesMapper.xml"/>
<!--
使用url完全限定路径
<mapper url="file:///com/test/WebsitesMapper.xml"/>
使用mapper接口类
<mapper class="com.test.WebsitesMapper"/>
将包中的所有接口注册为映射器
<package name="com.test"/>
-->
</mappers>
</configuration>
4.创建外部配置文件:db.peoperties
url=jdbc:mysql://localhost:3306/test_l
driver=com.mysql.jdbc.Driver
username=username
password=password
5.创建SqlSessionFactory类:GetSqlSessionFactory
public class GetSqlsessionFactory {
private static SqlSessionFactory sqlSessionFactory;
synchronized public static SqlSessionFactory getSqlSessionFactory(){
String resource = "mybatis-config.xml";
try {
//加载properties配置文件
InputStream isRef = GetSqlsession.class.getResourceAsStream("/db.properties");
Properties prpo = new Properties();
prpo.load(isRef);
InputStream stream = Resources.getResourceAsStream(resource);
//这里我们选用创建的mysqlTest环境以及加载properties文件,若不选用则选用默认的环境
sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream,"mysqlTest",prpo);
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactory;
}
}
6.创建SqlSession类:GetSqlsession
public class GetSqlsession {
private static ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();
public static SqlSession getSqlsession(){
SqlSession session = tl.get();
if(session == null){
session = GetSqlsessionFactory.getSqlSessionFactory().openSession();
tl.set(session);
}
return session;
}
public static void commit(){
if(tl.get() != null){
tl.get().commit();
tl.get().close();
tl.set(null);
}
}
public static void rollback(){
if(tl.get() != null){
tl.get().rollback();
tl.get().close();
tl.set(null);
}
}
}
7.创建Mapper接口
public interface WebstiesMapper {
List<Websites> SelectAll();
List<Map> userInfo(HashMap map);
List<Map> selectUserChoose(Websites we);
List<Map> selectUserTrim(Websites we);
List<Map> selectUserForeach(List list);
int insertUserinfo(Websites we);
int insertUserinfoSelectKey(Websites we);
int insertUsersForeach(List list);
int updateUserinfo(Websites we);
int updateUserTrim(Websites we);
}
8.创建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.test.WebstiesMapper">
<!-- 若数据表中的字段与实体类字段不一致就需要resultMap标签 -->
<resultMap type="we" id="user">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="url" property="url"/>
<result column="alexa" property="alexa"/>
<result column="country" property="country"/>
</resultMap>
<!-- 避免重复Sql语句 减少代码配置-->
<sql id="userField">name,url,alexa,country</sql>
<select id="SelectAll" resultType="we">
select
<include refid="userField"/>
from
websites
</select>
<!-- 将Sql语句作为字符串变量传入
//测试将Sql语句作为字符串变量传入,安全性不高,不建议使用
HashMap maps = new HashMap();
maps.put("id", 1);
maps.put("orderSql", "id desc");
WebstiesMapper mapper = GetSqlsession.getSqlsession().getMapper(WebstiesMapper.class);
List<Map> listUserinfo = mapper.userInfo(maps);
for (int i = 0; i < listUserinfo.size(); i++) {
Map map = listUserinfo.get(i);
System.out.println(map.get("name"));
}
-->
<select id="userInfo" parameterType="map" resultType="map">
<!-- 默认情况下,使用#{}格式的语法会导致 MyBatis创建预处理语句属性并以它为背景设 置安全的值(比如?).这样做很安全,很迅速也是首选做法
有时你只是想直接在 SQL语句中插入一个不改变的字符串。比如,像 ORDER BY,你可以这样来使用-->
select
<include refid="userField"/>
from
websites where id>#{id}
order by ${sql}
</select>
<!-- 插入空值的处理方法(jabcType) -->
<!-- 数据库主键包括自增和非自增,有时候新增一条数据不仅仅知道成功就行了,后边的逻辑可能还需要这个新增的主键,
useGeneratedKeys="true" keyProperty="id" (useGeneratedKeys设置为true后,mybatis会
使用JDBC的getGeneratedkeys方法获取由数据库内部自动生成的主键, 插入后的id赋给Websites中相对应的属性,
keyProperty指定的字段,但这样有很大的局限性)-->
<insert id="insertUserinfo" useGeneratedKeys="true" keyProperty="id" parameterType="we">
into websites
(<include refid="userField"/>)
values
(#{name,jdbcType=VARCHAR},
#{url,jdbcType=VARCHAR},
#{alexa,jdbcType=INTEGER},
#{country,jdbcType=VARCHAR})
</insert>
<!-- 插入空值的处理方法(if) -->
<insert id="insertUserinfoSelectKey" parameterType="we">
<!-- 获取插入数据后的主键,这里使用的是MySQl,Oracle不支持自增,获取序列。
order设置属性AFTER在inert之后执行 ,设置BEFORE则在insert之前执行-->
<selectKey keyProperty="id" order="AFTER" resultType="INTEGER">
SELECT LAST_INSERT_ID()
<!-- select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
order属性设置成BEFORE,selectKey 元素将会首先运行,websites的 id会被设置,然后插入
语句会被调用。values后也要加#{id},这是对于JDBC或者数据库不支持主键自动生成的情况而使用,
但是这种方法不建议使用,使用 LAST_INSERT_ID()获取插入后获取主键ID的功能便好-->
</selectKey>
<if test="name!=null">
<if test="url!=null">
<if test="alexa!=null">
<if test="country!=null">
insert into websites
(<include refid="userField"/>)
values
(#{name},#{url},#{alexa},#{country})
</if>
</if>
</if>
</if>
</insert>
<!-- 在多条件中选择一个条件:choose -->
<select id="selectUserChoose" parameterType="we" resultType="map">
select * from websites
<!-- where元素知道如果由被包含的标记返回任意内容,就仅仅插入“WHERE”
而且,如果以“AND”或“OR”开头的内容,那么就会跳过 WHERE不插入
如下,我们使用了otherwise,所以这种情况不会出现,多使用于if中-->
<where>
<!-- <if test="name!=null">and name like 'T%'</if>
<if test="url!=null">and url like '%one%'</if> -->
<choose>
<when test="name!=null">and name like 'T%'</when>
<when test="url!=null">and url like '%one%'</when>
<!-- 都不满足则执行otherwise中的内容 -->
<otherwise>and alexa=#{alexa}</otherwise>
</choose>
</where>
</select>
<!-- 与where元素相等,自定义内容:trim。prefix:前缀,prefixOverrides:自动去除第一个AND或OR-->
<select id="selectUserTrim" parameterType="we" resultType="map">
select * from websites
<trim prefix="WHERE" prefixOverrides="AND | OR">
<if test="name!=null">and name like 'T%'</if>
<if test="url!=null">and url like '%one%'</if>
</trim>
</select>
<update id="updateUserTrim" parameterType="we">
update websites
<!-- suffix:后缀;suffixOverrides:去掉最后一个逗号(也可以是其它符号) -->
<trim prefix="SET" suffixOverrides="," suffix="WHERE">
<if test="name!=null and name.length()>0">name=#{name},</if>
<if test="url!=null and url.length()>0">url=#{url},</if>
</trim>
<if test="id!=null">id=#{id}</if>
</update>
<!-- 动态指定需要更新的列:set -->
<update id="updateUserinfo" parameterType="we">
update websites
<set>
<if test="name!=null">name=#{name}</if>
<if test="url!=null">url=#{url}</if>
<if test="alexa!=null">alexa=#{alexa}</if>
<if test="country!=null">country=#{country}</if>
</set>
<if test="id!=null">where id=#{id}</if>
</update>
<!-- 迭代一个集合, 通常是构建在IN条件中:foreach -->
<select id="selectUserForeach" parameterType="java.util.List" resultType="map">
select * from websites where id in
<!-- foreach允许你指定一个集合,声明集合项和索引变量,它们可 以用在元素体内。它也允许你指定开放和关闭的字符串,在迭代之间放置分隔符
collection:必须指定,传入参数为List时为list;传入参数为数组时,为array;传入参数为Map时,为Map的键key
item:迭代集合时元素别名
index:在list和数组中,index是元素的序号,在map中,index是元素的key
open:被迭代元素前缀
close:被迭代元素后缀
separator:被迭代元素之间的分隔符
多用于批量执行Sql语句
-->
<foreach collection="list" item="item" index="index" open="(" close=")" separator=",">
#{item}
</foreach>
</select>
<!-- foreach批量插入数据 -->
<insert id="insertUsersForeach" parameterType="java.util.List">
insert into websites
(<include refid="userField"/>)
values
<foreach collection="list" item="item" separator=",">
(#{item.name},#{item.url},#{item.alexa},#{item.country})
</foreach>
</insert>
</mapper>
9.测试
public class Test {
public static void main(String[] args) {
WebstiesMapper mapper = GetSqlsession.getSqlsession().getMapper(WebstiesMapper.class);
}
}
10.Mybatis逆向工具的侍弄
下载相对应的逆向工具包与数据库驱动包
10.1 编写逆向xml配置文件
<?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="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test_l" userId="root"
password="0000">
</jdbcConnection>
<!-- <jdbcConnection driverClass="oracle.jdbc.OracleDriver"
connectionURL="jdbc:oracle:thin:@localhost:1521:mybatis"
userId=""
password="">
</jdbcConnection> -->
<!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer,为 true时把JDBC DECIMAL 和
NUMERIC 类型解析为java.math.BigDecimal -->
<javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.ssm.po"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.ssm.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.ssm.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<!--
tableName:要生成的表名
domainObjectName:生成后的实例名
enableCountByExample:Count语句中加入where条件查询,默认true开启
enableUpdateByExample:Update语句中加入where条件查询,默认true开启
enableDeleteByExample:Delete语句中加入where条件查询,默认true开启
enableSelectByExample:Select多条语句中加入where条件查询,默认true开启
selectByExampleQueryId:Select单个对象语句中加入where条件查询,默认true开启
-->
<table tableName="websites">
<!--
常用:
property:将所有字段逆向生成为类属性,默认全部
ignoreColumn:生成时忽略列字段
-->
</table>
</context>
</generatorConfiguration>
10.2 编写运行类
public class GeneratorFromXML {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
File configFile = new File("generatorConfig.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);
}
}