MyBatis 是一款优秀的持久层框架,它内部封装了JDBC,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJO映射成数据库中的记录。
mybatis通过xml或注解的方式将要执行的各种 statement配置起来,并通过java对象和statement中sql的动态参数进行映射生成最终执行的sql语句。
最后mybatis框架执行sql并将结果映射为java对象并返回。采用ORM思想(Object Relational Mapping:对象关系映射)解决了实体和数据库映射的问题,对jdbc 进行了封装,屏蔽了jdbc api 底层访问细节,使我们不用与jdbc api 打交道,就可以完成对数据库的持久化操作。
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.0</version>
</dependency>
public class User {
private Long id;
private String username;
private String password;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
}<?xml version="1.0" encoding="UTF-8" ?>
<!--映射文件DTD约束头-->
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--映射文件,namespace是为了方便调用映射文件中的映射方法,与下面语句的ID一起作为查询标识-->
<mapper namespace="userMapper">
<!--标签类型有select update delete等 -->
<!--resultType表示将返回的查询结果封装到的结果集,即查询结果对应的实体类型-->
<select id="findAll" resultType="cn.ywrby.domain.User">
select * from user
</select>
</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>
<!--配置数据源环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<!--配置连接池基本数据-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:hj/jdbcTest"/>
<property name="username" value="root"/>
<property name="password" value="rlm214"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="cn\ywrby\mapper\UserMapper.xml"/>
</mappers>
</configuration>@Test
public void test() throws IOException {
//加载核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象用于执行sql语句
SqlSession sqlSession = factory.openSession();
//执行sql语句 参数:namespance.id
List<User> userList=sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();
}配置映射文件
<!--配置插入操作 parameterType表示参数对象,
即执行插入操作时,传入该参数,并将该类属性值传入数据库
mybatis映射文件中的占位符是#{} 其内部传入的是类的属性值而不是数据库的列名-->
<insert id="save" parameterType="cn.ywrby.domain.User">
insert into user values (#{id},#{username},#{password})
</insert>
<update id="update" parameterType="cn.ywrby.domain.User">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<delete id="delete" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>测试用例:
/**
* 测试插入语句执行
* 要注意的是在执行插入删除语句等需要对数据库进行修改的sql语句时
* 必须进行事务的提交,mybatis默认不提交事务
* 而查询语句由于不修改数据库内容,所以不需要进行事务的提交
*/
@Test
public void test() throws IOException {
//实例化要插入的对象并传参
User user=new User();
user.setId((long) 3);
user.setUsername("Lily");
user.setPassword("5667");
//加载核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession工厂对象
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象用于执行sql语句
SqlSession sqlSession = factory.openSession();
//执行插入语句,并传入要插入的对象
sqlSession.selectList("userMapper.save",user);
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}<?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>
<!--配置数据源环境,default指定默认的环境名称-->
<environments default="development">
<!--environment进行环境配置,id指定当前环境的名称-->
<environment id="development">
<!--type属性表示指定事务管理类型是JDBC-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源,type="POOLED"表示指定当前数据源类型是连接池-->
<dataSource type="POOLED">
<!--配置连接池基本数据-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://cdb-cd3ybvc6.cd.tencentcdb.com:10056/jdbcTest"/>
<property name="username" value="root"/>
<property name="password" value="renboyu010214"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="cn\ywrby\mapper\UserMapper.xml"/>
</mappers>
</configuration>mapper标签的作用是加载映射文件,其加载文件的方式有多种:
<mapper resource="cn\ywrby\mapper\UserMapper.xml"/><mapper url="file:///var/mappers/xxx.xml"/><mapper class="cn.ywrby.builder.AuthorMapper"/><package name="cn.ywrby.mapper"/>properties标签用于加载外部properties文件,可以使各文件分工更加明确(如加载jdbc.properties)
typeAliases标签用于自定义别名,定义别名可以简化我们代码输入,type属性用于表示定义别名的实体类名,alias是自定义的别名
<!--配置别名-->
<typeAliases>
<typeAlias type="cn.ywrby.domain.User" alias="user"/>
</typeAliases>在UserMapper.xml中使用,parameterType和resultType都可以使用别名替换,另外MyBatis也为一些基本类提前定义了别名
<mapper namespace="userMapper">
<select id="findAll" resultType="user">
select * from user
</select>
<insert id="save" parameterType="user">
insert into user values (#{id},#{username},#{password})
</insert>
<delete id="delete" parameterType="int">
delete from user where id=#{id}
</delete>
</mapper>别名 | 数据类型 |
|---|---|
String | java.lang.String |
long | java.lang.Long |
int | java.lang.Integer |
double | java.lang.Double |
boolean | java.lang.Boolean |
MyBatis的传统实现方式就是通过上文测试类中的一般方法,在每次的使用过程中,都需要加载核心配置文件,初始化会话工程,执行事务提交等繁琐操作, 所以一般情况下,在开发过程中不会采用传统的实现方式
接口代理开发方式只需要我们实现Mapper接口(就是之前编写的DAO层接口),然后由MyBatis根据接口的定义(根据方法名,返回值,参数值等)创建接口的动态代理对象
Mapper接口的开发需要遵循以下的规范
修改后的UserMapper.xml配置文件
<!--命名空间的值和接口类全限定名一致-->
<mapper namespace="cn.ywrby.mapper.UserMapper">
<!--id值和方法名一致,resultType和返回值类型一致(这里了别名)-->
<select id="findAll" resultType="user">
select * from user
</select>
<!--parameterType的值也需要和传入参数一致-->
<insert id="save" parameterType="user">
insert into user values (#{id},#{username},#{password})
</insert>
<update id="update" parameterType="user">
update user set username=#{username},password=#{password} where id=#{id}
</update>
<delete id="delete" parameterType="java.lang.Long">
delete from user where id=#{id}
</delete>
</mapper>接口实现
public interface UserMapper {
//这里返回值虽然是List类型,但其中存储的是User类型,所以也可以成功实现
public List<User> findAll();
public void save(User user);
public void update(User user);
public void delete(Long id);
}测试用例
@Test
public void test() throws IOException {
User user=new User();
user.setId((long) 4);
user.setUsername("lily");
user.setPassword("1234");
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory=new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = factory.openSession();
//通过getMapper方法传入接口类,获得MyBatis返回的实现类
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//执行接口方法
mapper.update(user);
//mapper.delete((long) 4);
//mapper.findAll();
//mapper.save(user);
sqlSession.commit();
sqlSession.close();
}