MyBatis环境下利用XML和接口操作数据库
在搭建好MyBatis应用后,我们不妨来了解一下MyBatis的一些核心部件。
MyBatis的核心部分分为如下四个部分:
- SqlSessionFactory:生成SqlSession的类,利用工厂模式
- SqlSessionFactoryBuilder:构造SqlSessionFactory所需要的类,通过调用他的builder方法,采用分步构建的Builder模式
- SqlSession:通过它来发送SQL语句,还可以获取Mapper的接口
- SQL Mapper:映射器,有一个Java接口和XML文件(或注解)组成,通过给出对应的SQL和映射规则,发送SQL语句去执行,并返回结果
SqlSessionFactory的获取方法
首先我们要知道,在MyBatis中XML分为两种,一种是基础配置文件,一种是映射文件,前者主要配置一些基本的参数和环境,而后者则主要执行某个具体的映射以及SQL语句,参数等等。
我们将基础配置文件命名为: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>
<settings>
<!-- 配置mybatis日志采用的是log4j -->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true" />
</settings>
<typeAliases>
<typeAlias type="com.jimmy.entity.Product" alias="product"/>
</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/mytestdb"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.jimmy.mapper"/>
</mappers>
</configuration>
我们来看一下里面的一些基础配置
<typeAliases> :定义别名,在上面的XML文件中,为com.jimmy.entity.Product这个类定义了别名,这样在MyBatis中就可以使用别名来代替本来的名字。
<dataSource>:配置数据库
<mapper>:这里面放着引入的映射器。
我们在com.jimmy.mapper创建了一个ProductMapper.xml文件,在 配置XML文件中的<mapper>里面,就存着ProductMapper.xml的路径,它的作用主要是引入XML文件创建映射器。在ProductMapper.xml文件中有一个<mapper>元素,我们设置一个namespace参数,将ProductMapper.xml的路径写入,这样MaBatis上下文就可以通过它找到对应接口。而我们就是在ProductMapper.xml中编写SQL语句。
我们在数据库中创建一个t_product表,在MyBatis中创建Product类,表与类的属性要对应,数据库的连接就交给MyBatis实现, 现在我们通过测试方法来创建一个SqlSessionFactory,再来获取SqlSession,如下图:接下来进入主题,
如何利用XML和接口操作数据库
我们来通过一个实例来了解一下:
各个文件的作用 |
---|
TestProduct.java:程序入口 |
ProductMapper.java:映射器接口 |
ProductMapper.xml:映射器XML文件 |
Product.java:执行对象 |
log4j.properties:日志配置文件,后台数据显示MyBatis的过程日志 |
mybatis-config.xml:基础配置文件 |
先来编写Product类:
package com.jimmy.entity;
import java.io.Serializable;
import java.util.Date;
public class Product implements Serializable {
public Product() {
super();
// TODO Auto-generated constructor stub
}
private int id;
private String name;
private String code;
private Double price;
private String description;
private Integer status;
private Date create_time;
private Integer count;
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 getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreate_time() {
return create_time;
}
public void setCreate_time(Date create_time) {
this.create_time = create_time;
}
public Integer getCount() {
return count;
}
public void setCount(Integer count) {
this.count = count;
}
@Override
public String toString() {
return "Product [id=" + id + ", name=" + name + ", code=" + code + ", price=" + price + ", description="
+ description + ", status=" + status + ", create_time=" + create_time + ", count=" + count + "]";
}
}
此外在我的测试类中我并没有通过main方法来测试,而是通过@Test注解来单个测试一个方法,
编写的测试方法必须符合以下规则:我们来看ProductMapper.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.jimmy.mapper.ProductMapper">
<insert id="saveProduct" parameterType="product">
insert into t_product values(null,#{name},#{code},#{price},#{count},#{description},#{status},#{create_time})
</insert>
<insert id="saveProductreturnPK" parameterType="product">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into t_product values(null,#{name},#{code},#{price},#{count},#{description},#{status},#{create_time})
</insert>
<update id="updateProduct" parameterType="product">
update t_product set price= #{price} where id=#{id}
</update>
<select id="selectProductById" parameterType="int" resultType="product">
select * from t_product where id=#{id}
</select>
<select id="selectAllProduct" resultType="product">
select * from t_product
</select>
<delete id="delectProductById" parameterType="int">
delete from t_product where id=#{id}
</delete>
<!-- 开启mapper的二级缓存 -->
<cache/>
</mapper>
细心的人会发现我在这里开启了二级缓存,不过在本篇文章中不多介绍。
给每一个标签设置id,在ProductMapper.java中定义一个同名的方法,parameterType表示传进来的参数类型,resultType表示返回结果的类型,这时候我们刚才起的别名就派上用场了,在这个XML文件中,product就是com.jimmy.entity.Product的别名,我们再来看ProductMapper.java的代码:
package com.jimmy.mapper;
import java.util.List;
import com.jimmy.entity.Product;
public interface ProductMapper {
public void saveProduct(Product product);
public void updateProduct(Product product);
public void delectProductById(int id);
public Product selectProductById(int id);
public List<Product> selectAllProduct();
}
要注意在XML的id名要和接口文件中的方法名一致,且注意返回结果的数据类型。
接下来看看测试方法的代码,我们以一个按id查找商品的方法为例:
@Test
public void testSelectProductById() throws IOException{
//获取SqlSessionFactory对象
SqlSessionFactory sf=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
//获取SqlSession对象
SqlSession sqlSession=sf.openSession();
//获取Mapper接口
ProductMapper mapper = sqlSession.getMapper(ProductMapper.class);
Product product = mapper.selectProductById(3);
System.out.println(product);
sqlSession.close();
}
测试该方法:再补充一下log4j.properties的配置信息:
# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
同时在配置XML文件中设置setting元素:
这样就完成了MyBatis中利用XML和接口操作数据库的功能。