简介:
MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以对配置和原生Map使用简单的 XML 或注解,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis的功能架构:
分为三层
1.API接口层:提供给外部使用的接口API,开发人员通过这些本地API来操纵数据库。接口层一接收到调用请求就会调用数据处理层来完成具体的数据处理。
2.数据处理层:负责具体的SQL查找、SQL解析、SQL执行和执行结果映射处理等。它主要的目的是根据调用的请求完成一次数据库操作。
3.基础支撑层:负责最基础的功能支撑,包括连接管理、事务管理、配置加载和缓存处理,这些都是共用的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基础的支撑。
优点:
1.解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
2.提供映射标签,支持对象与数据库的orm字段关系映射
3.提供对象关系映射标签,支持对象关系组建维护
4.提供xml标签,支持编写动态sql。
until
public class MyBatisDBUtil {
//SqlSession
//工厂模式
private static SqlSessionFactory sqlSessionFactory; //以一个 SqlSessionFactory 的实例为中心的
public static void main (String[] args) { //测试连接数据库是否成功
System.out.println(getSqlSession());
}
public static SqlSession getSqlSession() {
if(sqlSessionFactory == null) {
sqlSessionFactory = getSqlSessionFactory();
}
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
public static SqlSessionFactory getSqlSessionFactory() { //SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得
String configPath = "conf/mybatis-config.xml";
try {
InputStream in = Resources.getResourceAsStream(configPath);//输入流(InputStream)
sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);//SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得
} catch (IOException e) {
e.printStackTrace();
}
return sqlSessionFactory;
}
}
不用再建一个Servlet接收参数,直接建一个实体类,直接把变量传进去即可
数据模型 (往数据库进行一个girl表的操作)
public class Girl {
private String name;
private Integer age;
private Date birth;
public Girl() {
super();
}
public Girl(String name, Integer age, Date birth) {
super();
this.name = name;
this.age = age;
this.birth = birth;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Girl [name=" + name + ", age=" + age + ", birth=" + birth + "]";
}
}
属性文件
jdbc.username=TEST
jdbc.password=TEST
jdbc.ClassName=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
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> <!-- XML 配置文件(configuration XML)中包含了对 MyBatis 系统的核心设置 -->
<!-- 获取属性文件 -->
<properties resource="conf/jdbc_orcl.properties"></properties>
<!-- 类型别名, 为实体类定义一个别名 -->
<typeAliases>
<package name="model"/> <!-- 包名,在映射的XML文件里面的resultType直接写类名即可 -->
</typeAliases>
<environments default="test">
<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>
<!-- 使用属性文件里面的值, -->
<environment id="test">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.ClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers> <!-- mappers 元素则是包含一组 mapper 映射器(这些 mapper 的 XML 文件包含了 SQL 代码和映射定义信息),
引入映射文件, 引入方式有四种:url, class, resource, package -->
<mapper resource="mapper/GirlMapper.xml"/> <!-- 直接扫描的是映射文件本身 -->
</mappers>
</configuration>
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="mapper.GirlMapper"> <!-- 映射的SQL语句 -->
<!-- <insert id="addGirl" parameterType="model.Girl"> 表示的是参数类型,model下面的实体类,里面的变量直接进入
insert into girl values(#{name},#{age}) 这里面获取的名字是跟Girl实体类里面的名称是相对应的
</insert> -->
<!-- 查询表中所有数据 -->
<select id="selectGirls" resultType="Girl"> <!-- 直接写那个类名就好,此处写的id名称为映射接口里面定义的方法名-->
select * from girl
</select>
<!-- 条件查询,根据年龄查找 -->
<select id="selectGirl2" resultType="Girl">
select * from girl g where g.age = #{param1}
</select>
<!-- 条件删除 -->
<delete id="deleteGirl" parameterType="String">
delete girl g where g.name = #{param1}
</delete>
<!-- 添加数据 -->
<insert id="insertGirl" parameterType="map">
insert into girl values(#{girl_name},#{girl_age},to_date(#{girl_birth},'yyyy-mm-dd'))
</insert>
<!-- 修改数据 -->
<update id="updateGirl" parameterType="Integer">
update girl g set g.name = '王大娘' where g.age = #{param1}
</update>
</mapper>
Mapper接口
public interface GirlMapper { //接口的名字要与xml里面的名字相同,这里面的方法不允许重载
List<Girl> selectGirls(); //查找全表
List<Girl> selectGirl2(Integer age); //根据年龄查询
int deleteGirl(String name); //根据姓名删除
int insertGirl(Map<String,Object> map); //插入数据
int updateGirl(Integer age); //更新数据
}
Junit单元测试框架
class JTest { //单元测试框架
private SqlSession sqlSession;
private GirlMapper gm;
void test() { //查询表的全部
List<Girl> list = gm.selectGirls();
for (Girl g : list) {
System.out.println(g);
}
}
void test2() { //根据年龄查询
List<Girl> list = gm.selectGirl2(20);
for (Girl g : list) {
System.out.println(g);
}
}
void test3() { //根据姓名删除
int i = gm.deleteGirl("小孩");
System.out.println(i);
}
void test4() { //添加数据
Map<String,Object> map = new HashMap<String,Object>();
map.put("girl_name", "哈哈");
map.put("girl_age", 21);
map.put("girl_birth","1993-11-24");
int i = gm.insertGirl(map);
System.out.println(i);
}
@Test
void test5() { //根据年龄更新数据
int i = gm.updateGirl(20);
System.out.println(i);
}
@BeforeEach
void setUp() throws Exception {
sqlSession = MyBatisDBUtil.getSqlSession(); //调用until包下面的MybatisDBUtil类里面的getSqlSession方法
gm = sqlSession.getMapper(GirlMapper.class); //sqlSession先把映射的文件和接口放进一个集合里面,找到映射接口的路径
}
@AfterEach
void tearDown() throws Exception {
sqlSession.commit(); //提交
sqlSession.close(); //关闭
}
}