Mybatis是一种常用的JDBC框架,能够帮助我们更好地操作数据库,通过mybatis配置好数据库连接,我们只需要在相关的配置文件中编写业务需要的SQL语句,直接调用使用即可。其中的使用过程,框架已经帮我们都完成了封装。
相对于hibernate来说,他们都是JDBC框架,mybatis是操作数据库的过程层次化更明显,并且符合面对接口编程的思路。mybatis更广为开发者使用。本篇文章将介绍mybatis的基本使用方法和技巧。可供入门参考。
目录:
一:运行简介、配置文件与搭建
二:增删改查的使用、一对多等对应关系的使用
三:动态SQL标签
四:注解方式
五:事务管理、缓存、延迟加载、逆向工程、二级缓存等相关概念的介绍
一:运行简介、配置文件与搭建
1. 运行简介:
mybatis的运行主要分为三步:
首先,编写mybatis的主配置文件,mybatis-config.xml。配置数据库连接、数据源、数据类型别名扫描、SQL映射文件扫描、事务管理等工作;
其次,编写SQL映射文件:xxxx.xml,编写SQL;
最后,获取sqlsessionfactory,获取sqlsession,使用该对象调用相关方法调用SQL的id完成数据库操作。
注: 可以使用面对接口的方式调用SQL,即sqlsession对象调用getMapper(UserMapper.class)方法,参数为mapper接口的类名。获取一个UserMapper对象,调用该对象的方法即可调用SQL(要注意方法名与SQLID一直,SQL.xml文件的namespace为mapper的类路径)。
2. 创建工程,导入jar包。
以eclipse为例,创建一个java project,并导入相关jar包,主要使用一下两个jar包。
3. src下创建编写配置文件,mybatis-config.xml
<typeAliases>为自动扫描的实体类,主要用作SQL映射文件中的参数和返回值的别名使用。下面配置文件使用的是自动扫描自动生成别名,例如,pojo包中的User类,会自动配置别名User。
<?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>
<typeAliases>
<package name="pojo"/>
</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://localhost:3306/test"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mybatis/User.xml"/> <!--映射SQL.xml文件--!>
</mappers>
</configuration>
还可以使用如下
<typeAliases>
<typeAlias alias="User" type="pojo.User"/>
</typeAliases>
的方式分别给每个类配置别名,此配置可以写在总配置文件中,也可以写在每个SQL的映射文件中。此种方式的别名可自行定义。
4. 调用
创建test类,完成调用SQL。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
User u2 = new User();
u2 = session.selectOne("getUserByid",5); //通过id为5查询user对象。
//使用mapper的方式调用SQL
UserMapper mapper = session.getMapper(UserMapper.class);
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
mapper.addUser(u1);
二:增删改查的使用、对应关系介绍
配置完成了mybatis的配置文件,现在距离介绍增删盖查操作数据库。有两种方式完成,一种直接调用SQLID,一种使用mapper接口完成调用,这里再增加中介绍两种方式,其他只介绍mapper接口方式。
1. 新增User。
直接调用:运行,即可完成数据库插入
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
session.insert("addUser");
User.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">
<typeAliases>
<typeAlias alias="uuu" type="pojo.User"/>
</typeAliases>
<mapper namespace="mapper.UserMapper">
<insert id="addUser" parameterType="pojo.User">
insert into user_1
(
username,
password,
name
)
values
(
#{userName},
#{passWord},
#{name}
)
</insert>
</mapper>
通过mapper接口,创建UserMapper接口,新增addUser方法。
package mapper;
public interface UserMapper {
void addUser(User user);
}
在测试类中:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
mapper.addUser(u1);
2. 查询:
//user.xml
<select id="userList" resultType="pojo.User">
select * from user_1
</select>
//mapper接口
List<User> userList();
//测试类
List<User> lu = mapper.userList();
for (User user : lu) {
System.out.println(user.getName());
}
3. 删除、修改的方式如出一辙,不再赘述。此时介绍到这里,相信小伙伴们已经知道如何使用mybatis来操作数据库了。
mybatis是如何通过获取mapper从而通过调用接口方法的方式完成SQL语句的调用的呢?
首先,测试类会读取主配置文件,加载数据库连接,加载SQL映射文件,测试类通过sqlsession对象的getMapper,加载我们已经创建的mapper接口,此时,mybatis会自动寻找该mapper接口中方法名,优先查找所对应sql.xml的namespace为该接口的类路径,然后将方法名与SQLID完成匹配注入,相当于实现了该接口方法。所以,调用接口方法时,会调用SQL语句。
4. 一对多的关系:
一个分类对应多个产品,该方式的主要实现过程为通过一个resultMap的映射关系,将查询出来的数据通过别名分别映射到相关的实体类属性中去。然后返回这个实体。
表结构中,每个产品都相应的有个cid为分类id,可以关联分类表的id;
实体类中,分类类有一个集合属性,为产品集合。
我们查询一个分类,并获取该分类的所有产品。
SQL.xml写法如下:通过配置映射配合SQL语句查询,最终将查询结果显示出来。
<resultMap type="Category" id="categoryBean">
<id column="cid" property="id" />
<result column="cname" property="name" />
<!-- 一对多的关系 -->
<!-- property: 指的是集合属性的值, ofType:指的是集合中元素的类型 -->
<collection property="products" ofType="Product">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
</collection>
</resultMap>
<!-- 关联查询分类和产品表 -->
<select id="listCategory" resultMap="categoryBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
</select>
5. 多对一,多个产品对应一个分类:
<resultMap type="Product" id="productBean">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
<!-- 多对一的关系 -->
<!-- property: 指的是属性名称, javaType:指的是属性的类型 -->
<association property="category" javaType="Category">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</association>
</resultMap>
<!-- 根据id查询Product, 关联将Orders查询出来 -->
<select id="listProduct" resultMap="productBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
</select>
三:动态SQL标签
所谓动态SQL标签,就是在sql.xml中通过一些特定的功能标签,辅助完成一些复杂的SQL操作。常用的标签有
if、where、forEach、set、trim、bind 等。使用方式分别介绍一下:
1. if使用if标签可以用来在SQL中完成条件的过滤。如下,当user的name不为空时,也就是调用SQL时传入了参数值,则执行对该name的模糊查询,否则不满足条件则查询所有。 其中if中的test为固定用法,意为判断条件。 concat为字符串拼接用法。
<select id="listUser" resultType="User">
select * from user_
<if test="name!=null">
where name like concat('%',#{name},'%')
</if>
</select>
2. where、set、trim用法
where会自动会if进行判断,如果都不满足则不执行,如果有一个满足则会去掉and和or关键字,如下;其实可以通过加上where1=1再结合if完成判断,不必使用where。
<select id="listUser" resultType="User">
select * from user_
<where>
<if test="name!=null">
and name like concat('%',#{name},'%')
</if>
<if test="price!=null and price!=0">
and price > #{price}
</if>
</where>
</select>
set,用于update操作,类似where标签,用法如下:
<update id="update" parameterType="User" >
update user
<set>
<if test="name != null">name=#{name},</if>
<if test="price != null">price=#{price}</if>
</set>
where id=#{id}
</update>
trim标签,可完成需要的定制功能。如下:prefix代表前缀词、suffixOverrides代表分隔符(trim会自动根据条件把分隔符去除掉多余的 分隔符)。
<update id="update" parameterType="User" >
update user
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name=#{name},</if>
<if test="price != null">price=#{price}</if>
</trim>
where id=#{id}
</update>
3.forEach标签,遍历循环。
通常用在oracle中的in用法、批量删除添加等操作中,可以将参数传递进来的集合类型进行遍历。如下;
item为遍历是每个元素的名、index为遍历的位置、collection有三个值:list、array{数组类型}、map,这里为list,代表这是一个List集合、
open为开始符号(,close为结束符号)、separator :分隔符,表示遍历时每个元素之间以什么分隔。
<select id="list" resultType="User">
SELECT * FROM user
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
四:注解方式
通过写注解,就可以免去写SQL.xml映射文件了,不过一般还是用xml文件的多,使用注解虽然省了一步,但对于复杂的SQL查询并不方便。下面介绍如何使用注解。
1. mapper接口中添加SQL注解:
public interface UserMapper {
@Insert(" insert into user ( name ) values (#{name}) ")
public int add(Category category);
@Delete(" delete from user where id= #{id} ")
public void delete(int id);
@Update("update user set name=#{name} where id=#{id} ")
public int update(Category category);
@Select(" select * from user ")
public List<Category> list();
}
2. 在mybatis-config.xml中声明该映射类。
<configuration>
<mappers>
<mapper resource="User.xml"/>
<mapper class="mapper.UserMapper"/>
</mappers>
</configuration>
3. 编写测试类:至此完成。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User u= mapper.get(8);
u.setName("修改了的user名字");
mapper.update(u);
session.commit();
session.close();
五:事务管理、缓存、延迟加载等相关概念的介绍
1. 事务管理:
在mybatis-config.xml配置文件中,配置
<transactionManager type="JDBC"/> 代表JDBC开启事务管理。
开启后,在测试类中提交sqlsession.commit()之后,提交事务,此时如果提交的数据库操作中有一个操作失败了,则所有的操作均不会成功,只有都成功才会生效。这就代表着事务启动成功。
2. 延迟加载:
mybatis默认是积极加载的,即没有延迟加载。查询一个对象时,如果该对象中有集合属性并且做了映射,则查询该对象时集合属性也会一起被查询出来。
如何设置延迟加载:在mybatis-config.xml中添加延迟加载设置:
<settings>
<!-- 打开延迟加载的开关 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 将积极加载改为消息加载即按需加载 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
3. 二级缓存与一级缓存
mybatis的二级缓存与hibernate的二级缓存基本一致,一级缓存查询过后的数据时将缓存存在 sqlsession中的,二级缓存的缓存是存在sqlsessionFactory中的。
4. mybatis的逆向工程:
可以自动生成代码的jar包工具类。
添加jar包:mybatis-generator-core-1.3.5.jar
src下新建配置文件:generatorConfig.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>
<!--数据库驱动-->
<!--
如果IDE(eclipse或者idea) 项目里导入了jar包,那么就不需要配置了jar包的绝对路径了
<classPathEntry location="e:/project/mybatis/lib/mysql-connector-java-5.0.8-bin.jar"/>
-->
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<!--数据库链接地址账号密码-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/test" userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model类存放位置-->
<javaModelGenerator targetPackage="pojo" targetProject="src">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成映射文件存放位置-->
<sqlMapGenerator targetPackage="mybatis" targetProject="src">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao类存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="mapper" targetProject="src">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成对应表及类名-->
<table tableName="category_" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>
自动生成文件类:
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
InputStream is= TestMybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
System.out.println("生成代码成功,刷新项目,查看文件");
}
运行之后,相应代码自动生成,调用方法就可完成数据库操作了。
以上就是mybatis的基本介绍,关于mybatis的使用更多的是结合其他框架技术完成项目的搭建。