MyBatis
MyBatis简介
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
通俗来说MyBatis是一个关于数据库的框架,通过简单的配置可以实现用java对数据库进行增删改查等操作。
环境的准备
使用MyBatis需要导入Jar包,使用Maven为以下代码
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
创建Utils类
从 XML 中构建 SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。
//MyBatisUtils
public class MyBatisUtils{
private static SqlSessionFactory sqlSessionFactory;
//当类加载时执行以下代码
static{
try{
//Mybatis配置文件位置
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建Session工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}catch(Exception e){
e.printStackTrace();
}
}
//静态方法获取SqlSession
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}
}
MyBatis配置文件
XML配置文件是MyBatis核心配置文件由以下几个组成:
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
以上组件需要时要按照顺序书写,不能打乱顺序
对以上几个常用的进行介绍:
properties(属性)
<!--这个模块主要是对连接数据库参数文件进行导入使用-->
<!--resoure 为文件的位置-->
<properties resource="org/mybatis/example/config.properties">
<!--property为当添加的内容,比如说文件中没有的内容可以依靠它来添加,name是key,value是value-->
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
<!--当文件中和添加的key=value重复时优先使用文件中内容-->
<!--设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值-->
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
<!--上面${key}的值就是properties内容-->
typeAliases(类型别名)
别名就是一个JAVA类的名字缩写,如果没有别名的话就需要com.xxxx.xxxx.User这样书写会使代码冗余和复杂
<!--typeAliases有两种方式可以指定包名-->
<typeAliases>
<package name="com.xxxx.xxx"/>
</typeAliases>
<!--这样写的在xxx包下的类在没有注解的情况下为首字母小写来作为它的别名,如在xxx下的User它的别名为user-->
<!--我们还可以通过注解的方式指定别名如指定User的别名为User可以使用以下方法-->
@Alias("User")
public class User{
....
}
<!--除了以上方法还有另一个方法起别名-->
<typeAliases>
<typeAlias alias="User" type="com.xxxx.xxx.User"/>
<!--通过这样配置就能在项目的任何地方使用User代替com.xxxx.xxx.User了-->
</typeAliases>
下面是一些常见的类型别名
别名 | 映射类型 |
---|---|
_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 |
environments(环境配置)
MyBatis 可以配置成适应多种环境,这种机制有助于将 SQL 映射应用于多种数据库之中, 现实情况下有多种理由需要这么做。例如,开发、测试和生产环境需要有不同的配置;或者想在具有相同 Schema 的多个生产数据库中使用相同的 SQL 映射。还有许多类似的使用场景。
不过要记住:尽管可以配置多个环境,但每个 SqlSessionFactory 实例只能选择一种环境。
所以,如果你想连接两个数据库,就需要创建两个 SqlSessionFactory 实例,每个数据库对应一个。而如果是三个数据库,就需要三个实例,依此类推,记起来很简单:
environments 元素定义了如何配置环境。
<!--default选择要使用的配置-->
<environments default="development">
<environment id="development">
<!--
事务管理器类型,在MyBatis中有两种事务管理器(也就是 type="[JDBC|MANAGED]")
JDBC – 这个配置直接使用了 JDBC 的提交和回滚设施,它依赖从数据源获得的连接来管理事务作用域。
MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务 器的上下文)。 默认情况下它会关闭连接。然而一些容器并不希望连接被关闭,因此需要将 closeConnection 属性设置为 false 来阻止默认的关闭行为。
例如:
<transactionManager type="MANAGED">
<property name="closeConnection" value="false"/>
</transactionManager>
-->
<transactionManager type="JDBC">
<property name="..." value="..."/>
</transactionManager>
<!--这里面是数据库连接所需要的参数,可以直接写出来,也可以用properties配置文件的方法-->
<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(映射器)
既然 MyBatis 的行为已经由上述元素配置完了,我们现在就要来定义 SQL 映射语句了。 但首先,我们需要告诉 MyBatis 到哪里去找到这些语句。 在自动查找资源方面,Java 并没有提供一个很好的解决方案,所以最好的办法是直接告诉 MyBatis 到哪里去找映射文件。 你可以使用相对于类路径的资源引用,或完全限定资源定位符(包括 file:/// 形式的 URL),或类名和包名等。
例如:
<!-- 使用相对于类路径的资源引用 -->
<mappers>
<mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
<mapper resource="org/mybatis/builder/BlogMapper.xml"/>
<mapper resource="org/mybatis/builder/PostMapper.xml"/>
</mappers>
<!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
<mapper class="org.mybatis.builder.PostMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
<!-- 使用完全限定资源定位符(URL)**这种方法不推荐使用** -->
<mappers>
<mapper url="file:///var/mappers/AuthorMapper.xml"/>
<mapper url="file:///var/mappers/BlogMapper.xml"/>
<mapper url="file:///var/mappers/PostMapper.xml"/>
</mappers>
这些配置会告诉 MyBatis 去哪里找映射文件。
MyBatis实现增删改查
创建实体类
package com.jia.pojo;
import lombok.Data;
//这里使用lombok注释生成get set方法等,看不懂建议百度一下lombok
@Data
public class User {
private int id;
private String name;
private String pwd;
}
创建DAO
package com.jia.dao;
import com.jia.pojo.User;
public interface UserMapper {
//增加用户
int insertUser(User user);
//根据id删除用户
int delectUser(int id);
//根据id修改用户
int updateUser(int id,String name,String pwd);
//根据id查询用户
User selectUser(int id);
}
创建DAO对应的Mapper
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--与Mapper对应的包名-->
<mapper namespace="com.jia.dao.UserMapper">
<!--
对接口中方法进行实现
其中id为接口中方法名
parameterType为要传入的参数类型
resultType为返回值类型
注:对增删改等操作需要进行事务处理,需要手动提交事务
-->
<!--增-->
<insert id="insertUser" parameterType="User" >
insert into user(id,username,pwd) value(#{id},#{username},#{pwd})
</insert>
<!--删-->
<delete id="delectUser" parameterType="_int">
delete from user where id=#{id}
</delete>
<!--改-->
<update id="updateUser" parameterType="map">
update user set id=#{id},username=#{username},pwd=#{pwd} where id=#{id}
</update>
<!--查-->
<select id="selectUser" parameterType="_int" resultType="user">
select * from user where id=#{id}
</select>
</mapper>
将Mapper注册到MyBatis配置文件中
<?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"/>
<!--对下面包进行别名设置-->
<typeAliases>
<package name="com.jia.pojo"/>
</typeAliases>
<!--
设置环境
使用${}的方式引入properties中的内容
-->
<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>
<!--将Mapper注册到配置文件中-->
<mappers>
<mapper class="com.jia.dao.UserMapper"/>
</mappers>
</configuration>
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/user
username=root
password=你自己要连接数据库密码
创建测试类
package com.jia.dao;
import com.jia.pojo.User;
import com.jia.utils.MyBatisUtils;
import junit.framework.TestCase;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.Map;
public class UserMapperTest extends TestCase {
public void testInsertUser() {
//通过工具类获取sqlsession
SqlSession session = MyBatisUtils.getSession();
//获取mapper
UserMapper mapper = session.getMapper(UserMapper.class);
//掉用添加方法
int a = mapper.insertUser(new User(4, "往往", "12563554"));
System.out.println(a);
//掉用删除方法
mapper.delectUser(4);
Map<String,String> map = new HashMap<>();
map.put("id","4");
map.put("username","李六");
map.put("pwd","12563");
//掉用修改方法
mapper.updateUser(map);
//调用查询方法
User user = mapper.selectUser(4);
System.out.println(user);
session.commit();
session.close();
}
}
通过注释实现功能
MyBatis可以通过注释实现增删改查,但是当涉及到一对多或者多对一的问题时不好处理,所以MyBatis使用时简单的可以使用注释进行开发,复杂的建议使用配置文件开发
package com.jia.dao;
import com.jia.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.Map;
public interface UserMapper {
//像这样就可以了,@Param是对传入的数据进行命名
@Select("select * from user where id=#{id}")
User selectUser(@Param("id") int id);
}
万能的Map
使用MyBatis时,有时候我们传入的参数可能不是一个对象而是,一堆不同类型的数据
比如说当我们要修改一个用户时我们要传入负责查询的数据id,要修改的username和pwd,这时我们就不能直接传入一个User对象了,这时候就需要万能的Map了。
我们可以直接传入一个Map对象,需要什么就往Map里put什么,这样就没有参数的限制了
修改数据的实例
业务需要:我们需要通过id,对用户进行数据的更改
User接口
package com.jia.dao;
import com.jia.pojo.User;
import java.util.Map;
public interface UserMapper {
//根据id修改用户
int updateUser(Map map);
}
Mapper配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.jia.dao.UserMapper">
<update id="updateUser" parameterType="map">
update user set id=#{id},username=#{username},pwd=#{pwd} where id=#{id}
</update>
</mapper>
测试文件
package com.jia.dao;
import com.jia.pojo.User;
import com.jia.utils.MyBatisUtils;
import junit.framework.TestCase;
import org.apache.ibatis.session.SqlSession;
import java.util.HashMap;
import java.util.Map;
public class UserMapperTest extends TestCase {
public void testInsertUser() {
SqlSession session = MyBatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
//创建一个Mapper,将需要的值传入其中
Map<String,String> map = new HashMap<>();
map.put("id","4");
map.put("username","李六");
map.put("pwd","12563");
//将map传给方法
mapper.updateUser(map);
//提交事务
session.commit();
session.close();
}
}