为什么会产生 Hibernate Mybatis 这类的dao层框架

传统的jdbc 虽然执行速度很快,但是开发效率很低,随着面向对象开发的设计思想,在面向对象编程中 将对象 进行持久化,存入关系型的数据库时,由于关系型数据库的设计思想是数学思维,在持久化时,必须要对象拆分各个属性值,才可存入数据库;传统的jdbc 持久化时 对象持久化时 ,取出对象的一个一个属性,过去繁琐,并且不便于维护,而市场上的面向对象的数据库还并不成熟,所以为了调节面向对象设计的开发思想与落后的关系型数据库之间持久化时繁琐的问题,产生了一种新的设计规范

ORM (Object Relation Mapping) 

对象关系映射,是一种规范,调节目前面向对象的程序设计与主流的关系型数据库之间 发展不同步的问题,
关系 到对象的映射;
让编程时 可以全身心的用面向对象的设计思想去编程,用对象映射关系数据表,在持久化时,可以直接操作对象进行持久化。
优点:
开发效率高;
可维护性高;
缺点:
高效率的开发 对应也要失去性能,处理复杂关系时,性能会变差;
 

Spring对数据库的操作在jdbc上面做了深层次的封装,也就是工具类 jdbcTemplate

先看一下jdbcTemplate的大致流程图

作用:

1: 它提供了AOP式的事务管理

AOP式的事物管理:在以前的事务管理是要融合在逻辑代码中的,在逻辑代码中决定事务是否提交或者回滚,这样很容易造成代码难以维护,代码冗余
但是使用spring的声明式事务后,只需要在数据库处理方法上注解事务,就可以对操作进行管理,事务的设置和逻辑代码分开,容易维护。

不修改原有代码 重新封装现有的组件
类似于: FileWrite fw = new FileWrite();
PrintWrinter pw = new Prinwriter(fw);
2:spring 提供了统一的异常处理,框架处理了异常。
不论Dao层运用什么技术实现 出现的错误全部封装成了DatyaAccessException
如何使用 
1 引入相应spring jar包 + 数据库驱动包
2  在spring的主配置文件中配置 jdbcTemplate
<!-- 定义template组件 -->
<bean id="template"
class="org.springframework.jdbc.core.JdbcTemplate">
<!-- 注入连接信息 -->
<property name="dataSource" ref="bonecp">
</property>
</bean>

定义组件时 template需要一个数据连接池 来管理数据库连接

数据连接池 有很多种 这里用的是

com.alibaba.druid.pool.DruidDataSource
<!-- DataSource 数据源 连接池 存储管理大量的链接 流行的 dbcp c3p0,proxool -->
<!-- 数据源配置, 使用 BoneCP 数据库连接池 -->
<bean id="bonecp" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="driverClassName" value="com.mysql.jdbc.Driver" /> <!-- 基本属性 url、user、password -->
<property name="url" value="jdbc:mysql://localhost:3306/medicine?useUnicode=true&amp;characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" /> <!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" /> <property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" /> <!-- 配置监控统计拦截的filters -->
<property name="filters" value="stat" />
</bean>

下一部是根据表 编写实体类

实体类

package com.mxp.jdbc.entity;

import java.io.Serializable;

public class User implements Serializable {

    /**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String userName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
} }

还需要根据实体类写一个rowmapper

注意这里要继承

org.springframework.jdbc.core.RowMapper,然后重写maprow方法
package com.mxp.jdbc.entity;

import java.sql.ResultSet;
import java.sql.SQLException; import org.springframework.jdbc.core.RowMapper; /**
* 每个实体类都有这个封装组件
* 将User记录封装成 User对象
* @author Administrator
*
*/
public class UserRowMapper implements RowMapper<User>{ /**
* arg1:第几行记录
*/
@Override
public User mapRow(ResultSet arg0, int arg1) throws SQLException {
User user = new User();
user.setId(arg0.getString("id"));
user.setUserName(arg0.getString("user_name"));
return user;
} }

下面可以编写dao了 编写之前我们在spring的主配置文件中要把spring的扫描组件启动

<!-- spring组件扫描 -->
<context:component-scan base-package="com.mxp">
</context:component-scan>

dao

package com.mxp.jdbc.dao;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository; import com.mxp.jdbc.entity.User;
import com.mxp.jdbc.entity.UserRowMapper; @Repository
public class ItinerantDAO {
@Autowired
private JdbcTemplate template;//注入的方式
public void save(User user){
String sql = "insert into test_user" +
"(id,user_name) values (?,?)";
Object[] params = {
user.getId(),user.getUserName()
};
template.update(sql, params);
}
public List<User> findAll(){
String sql ="select * from test_user";
UserRowMapper rowMapper = new UserRowMapper();
List<User> list = template.query(sql, rowMapper);
return list;
} }

那现在就可以写测试方法

package test;

import java.io.IOException;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.mxp.ControllerQW; import com.mxp.jdbc.dao.ItinerantDAO;
import com.mxp.jdbc.entity.User;
import com.mxp.mybatis.util.MybatisUtil; public class Test {
public static void main(String[] args) {
//spring的主配置文件名
String conf = "spring-context.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ItinerantDAO dao = ac.getBean("itinerantDAO",ItinerantDAO.class);
User user = new User();
user.setId("1455");
user.setUserName("文森特");
dao.save(user);
} @org.junit.Test
public void test(){
String conf = "spring-context.xml";
ApplicationContext ac = new ClassPathXmlApplicationContext(conf);
ItinerantDAO dao = ac.getBean("itinerantDAO",ItinerantDAO.class);
List<User> list = dao.findAll();
for(User u:list){
System.out.println(u.getUserName());
} } }

这jdbcTemplate 见的次数很少 至今为止 还没有见到用的 

Mybatis

原来在我们使用jdbc的问题

1 对数据库的连接 使用时就创建连接,不使用就立即释放,对数据库进行频繁连接开启和关闭,造成数据库的资源浪费,影响数据库的性能;

解决办法:使用数据库连接池,管理数据库的连接。

2 将sql语句硬编码到java代码中,如果sql语句修改,需要重新编译java代码,不利于系统维护,

解决办法:把sql语句I定义到xml配置文件里;

3 在向statement中设置参数,对站位符位置和设置参数数值,硬编码到java代码中,

4 从result结果集中遍历数据时,存在硬编码,讲获取表的字段名硬编码,不便于维护,

讲结果集 自动映射成java对象

mybatis的架构

是一个持久层的项目,是阿帕奇的顶级项目,

通过 mybatis提供的映射方式,半自动的生成sql,大部分还是需要程序员编写sql

核心:输入映射:可以将statement中的输入参数自动输入到映射 通过ongl表达式,将查询的结果集灵活映射成为java对象(输出映射)

mybatis的结构
那么说一下myabtis的大致工作流程

1、  mybatis配置

SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。

mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在SqlMapConfig.xml中加载。

2、  通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂

3、  由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。

4、  mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。

5、  Mapped Statement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个Mapped Statement对象,sql的id即是Mapped statement的id。

6、  Mapped Statement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql前将输入的java对象映射至sql中,输入参数映射就是jdbc编程中对preparedStatement设置参数。

7、  Mapped Statement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过 Mapped Statement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于jdbc编程中对结果的解析处理过程。

 
第一步主配置文件
<?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="environment">
<environment id="environment">
<transactionManager type="JDBC" />
<!-- mybatis 自带连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/medicine?useUnicode=true&amp;characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 定义sqlMapper文件位置的 -->
<mappers>
<mapper resource="com/mxp/mybatis/entity/UserMapper.xml" />
</mappers>
</configuration>

第二步 实体类及其sqlmap映射文件

package com.mxp.mybatis.entity;

import java.io.Serializable;

public class User implements Serializable {

    /**
*
*/
private static final long serialVersionUID = 1L;
private String id;
private String userName;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
} }
<?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.mxp.mybatis.entity.UserMapper"> <sql id="userColumns">
a.id AS "id",
a.user_name AS "userName"
</sql> <select id="findAll" resultType="com.mxp.mybatis.entity.User" >
SELECT <include refid="userColumns"/>
FROM test_user a
</select> <select id="findLikeName" parameterType="string" resultType="com.mxp.mybatis.entity.User" >
SELECT <include refid="userColumns"/>
FROM test_user a
<where>
a.user_name like #{name}
</where> </select> </mapper>

第三部 获取sqlsession

package com.mxp.mybatis.util;

import java.io.InputStream;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class MybatisUtil { public static SqlSession getInsertance(){
SqlSessionFactoryBuilder builder =
new SqlSessionFactoryBuilder();
//这是读取文件后 形成一个输入流 涨知识了
//Test 其实就是一个类型 写自己的什么类型都行 主要是为了获取到getClassLoader().getResourceAsStream
InputStream reader = MybatisUtil.class.getClassLoader().getResourceAsStream("SqlMapConfig.xml");
//获取sqlsessionFactory
SqlSessionFactory factory = builder.build(reader);
//获取session
SqlSession session = factory.openSession();
return session;
} }

第四部 写测试类

package test;

import java.io.IOException;

import java.util.List;

import org.apache.ibatis.session.SqlSession;
import com.mxp.mybatis.util.MybatisUtil; public class Test { @org.junit.Test
public void getSqllSession() throws IOException{ SqlSession session = MybatisUtil.getInsertance();
System.out.println("获取session");
session.close();
}
@org.junit.Test
public void findall(){
SqlSession sqlsession = MybatisUtil.getInsertance();
List<com.mxp.mybatis.entity.User> list = sqlsession.selectList("findAll");
for(com.mxp.mybatis.entity.User u:list){
System.out.println(u.getUserName());
}
sqlsession.close(); }
@org.junit.Test
public void findLike(){
SqlSession sqlsession = MybatisUtil.getInsertance();
List<com.mxp.mybatis.entity.User> list = sqlsession.selectList("findLikeName","%文%");
for(com.mxp.mybatis.entity.User u:list){
System.out.println(u.getUserName());
}
sqlsession.close(); }
}

Mybatis的

Mapper映射器接口规则,会自动生成接口实现类。

修饰public

a.根据sqlMapper定义的id属性当接口方法名

b 根据sqlMapper定义的parameterType类型定义参数类型

c 根据sqlMapper定义的resultType的类型 定义方法的返回类型

(多行使用list<泛型(resultType的类型)>,单行使resultType的类型)

d 将sqlMapper的namespace属性指定成为 包名.接口名字,就是接口的位置,

如何取到接口实现类呢

从sqlsession中获取

sqlsession.getMapper(接口的class对象);

mybatis替我生成实现类,在实现类中把sqlsession.select*的各种操作封装起来

首先实现 d

<?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.mxp.mybatis.dao.UserDao"> <sql id="userColumns">
a.id AS "id",
a.user_name AS "userName"
</sql> <select id="findAll" resultType="com.mxp.mybatis.entity.User" >
SELECT <include refid="userColumns"/>
FROM test_user a
</select> <select id="findLikeName" parameterType="string" resultType="com.mxp.mybatis.entity.User" >
SELECT <include refid="userColumns"/>
FROM test_user a
<where>
a.user_name like #{name}
</where> </select> </mapper>

 a b c

package com.mxp.mybatis.dao;

import java.util.List;

import com.mxp.mybatis.entity.User;

public interface UserDao {
public List<User> findAll();
public List<User> findLikeName(String name);
}

测试生成的映射器接口实现类

@org.junit.Test
public void testMapper(){
SqlSession sqlsession = MybatisUtil.getInsertance();
UserDao dao = sqlsession.getMapper(UserDao.class);
List<com.mxp.mybatis.entity.User> os = dao.findAll();
for(com.mxp.mybatis.entity.User u:os){
System.out.println(u.getUserName());
}
sqlsession.close(); }

谈jdbcTemplate与mybatis的更多相关文章

  1. 【Spring】事务(transactional) - REQUIRES_NEW在JdbcTemplate、Mybatis中的不同表现

    环境 数据库: oracle 11g JAR: org.springframework:spring-jdbc:4.3.8.RELEASE org.mybatis:mybatis:3.4.2 概念 R ...

  2. JdbcTemplate 、Mybatis、ORM 、Druid 、HikariCP 、Hibernate是什么?它们有什么关系?

    JdbcTemplate .Mybatis.ORM .Druid .HikariCP .Hibernate是什么?它们有什么关系? 学完Spring和SpringMVC之后,就急于求成的开始学习起Sp ...

  3. JDBC、JDBCTemplate、MyBatis、Hiberante 比较与分析

    JDBC (Java Data Base Connection,java数据库连接) JDBC(Java Data Base Connection,java数据库连接)是一种用于执行SQL语句的Jav ...

  4. 08.@Scheduled定时任务、整合jdbcTemplate、mybatis区分多数据源

    @Scheduled注解执行定时任务 import org.springframework.scheduling.annotation.Scheduled; import org.springfram ...

  5. SpringBoot初学(4)– JdbcTemplate和Mybatis

    前言 github: https://github.com/vergilyn/SpringBootDemo 代码位置: 一.Spring Boot集成JdbcTemplate或NamedParamet ...

  6. [原创]Spring Boot + Mybatis 简易使用指南(一)基础环境搭建

    前言 作者: Ant QQ:517377100 相对于使用JdbcTemplate,Mybatis可自动建立pojo类型与数据库列的映射关系,数据库访问层的开发简单了许多 所有数据库访问操作,均封装在 ...

  7. Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源

    多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...

  8. Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源

    关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...

  9. Spring Boot入门系列(十四)使用JdbcTemplate操作数据库,配置多数据源!

    前面介绍了Spring Boot 中的整合Mybatis并实现增删改查.如何实现事物控制.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/c ...

随机推荐

  1. 作妖 | "该文件没有与之关联的程序来执行该操作..."的解决方法(删除快捷方式小箭头所致)

    文章目录 开始作妖 后悔作妖 终结作妖 开始作妖 这是次很作妖的体验过程.因为重新换了个系统,看着桌面上这些快捷方式都有个讨人嫌的小箭头,就在网上搜了搜解决办法. 比如,将下面的内容复制到记事本中,再 ...

  2. sql data compare

    https://documentation.red-gate.com/sdc14 About SQL Data Compare With SQL Data Compare, you can compa ...

  3. Struts2 入门笔记

    一.介绍 1.Struts网站 https://struts.apache.org/ struts 是通过基于请求响应模式的应用framework 1) 控制器(Controller)--控制整个Fr ...

  4. SpringBoot中的异常处理方式

    SpringBoot中有五种处理异常的方式: 一.自定义错误页面 SpringBoot默认的处理异常机制:SpringBoot默认的已经提供了一套处理异常的机制.一旦程序出现了异常SpringBoot ...

  5. 一个漂亮的输出MySql数据库表结构的PHP页面

    经常为了方便和直观,我们会首先直接在数据库中设计出表,但是接下来又要将表的结构和设计编写在设计文档中,以便编码的时候可以直观的查询,一旦数据库表非常多,字段非常多的时候,这无疑是件非常郁闷的工作. 这 ...

  6. osg机械臂模拟

    实现自由旋转  

  7. APP测试面试题(一)

    一.开场问题:(自由发挥) 1.请自我介绍一下: 2.为什么离开上一个公司呢? 3.做测试多久了?以前做过哪些项目?你们以前测试的流程是怎样的?用过哪些测试工具? 4.你觉得为什么要在一个团队中开展软 ...

  8. MySQL数据库表的设计和优化(上)

    一.单表设计与优化: (1)设计规范化表,消除数据冗余(以使用正确字段类型最明显):数据库范式是确保数据库结构合理,满足各种查询需要.避免数据库操作异常的数据库设计方式.满足范式要求的表,称为规范化表 ...

  9. (十八)JDBC优化使用(一)

    一.将增删改方法合并,优化代码 第十七篇的UserPOImpl.java类代码可以进行优化,因为增删改方法用的都是同一种执行方法executeUpdate(),对十七篇的例子进行优化如下: 2.1 搭 ...

  10. spark osx:WARN NativeCodeLoader:62 - Unable to load native-hadoop library for your platform

    spark-env.sh文件中增加,确保${HADOOP_HOME}/lib/native目录下有libhadoop.so文件 export JAVA_LIBRARY_PATH=${HADOOP_HO ...