谈jdbcTemplate与mybatis
为什么会产生 Hibernate Mybatis 这类的dao层框架
传统的jdbc 虽然执行速度很快,但是开发效率很低,随着面向对象开发的设计思想,在面向对象编程中 将对象 进行持久化,存入关系型的数据库时,由于关系型数据库的设计思想是数学思维,在持久化时,必须要对象拆分各个属性值,才可存入数据库;传统的jdbc 持久化时 对象持久化时 ,取出对象的一个一个属性,过去繁琐,并且不便于维护,而市场上的面向对象的数据库还并不成熟,所以为了调节面向对象设计的开发思想与落后的关系型数据库之间持久化时繁琐的问题,产生了一种新的设计规范
ORM (Object Relation Mapping)
Spring对数据库的操作在jdbc上面做了深层次的封装,也就是工具类 jdbcTemplate
先看一下jdbcTemplate的大致流程图
作用:
1: 它提供了AOP式的事务管理
AOP式的事物管理:在以前的事务管理是要融合在逻辑代码中的,在逻辑代码中决定事务是否提交或者回滚,这样很容易造成代码难以维护,代码冗余
但是使用spring的声明式事务后,只需要在数据库处理方法上注解事务,就可以对操作进行管理,事务的设置和逻辑代码分开,容易维护。
<!-- 定义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&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对象(输出映射)
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&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的更多相关文章
- 【Spring】事务(transactional) - REQUIRES_NEW在JdbcTemplate、Mybatis中的不同表现
环境 数据库: oracle 11g JAR: org.springframework:spring-jdbc:4.3.8.RELEASE org.mybatis:mybatis:3.4.2 概念 R ...
- JdbcTemplate 、Mybatis、ORM 、Druid 、HikariCP 、Hibernate是什么?它们有什么关系?
JdbcTemplate .Mybatis.ORM .Druid .HikariCP .Hibernate是什么?它们有什么关系? 学完Spring和SpringMVC之后,就急于求成的开始学习起Sp ...
- JDBC、JDBCTemplate、MyBatis、Hiberante 比较与分析
JDBC (Java Data Base Connection,java数据库连接) JDBC(Java Data Base Connection,java数据库连接)是一种用于执行SQL语句的Jav ...
- 08.@Scheduled定时任务、整合jdbcTemplate、mybatis区分多数据源
@Scheduled注解执行定时任务 import org.springframework.scheduling.annotation.Scheduled; import org.springfram ...
- SpringBoot初学(4)– JdbcTemplate和Mybatis
前言 github: https://github.com/vergilyn/SpringBootDemo 代码位置: 一.Spring Boot集成JdbcTemplate或NamedParamet ...
- [原创]Spring Boot + Mybatis 简易使用指南(一)基础环境搭建
前言 作者: Ant QQ:517377100 相对于使用JdbcTemplate,Mybatis可自动建立pojo类型与数据库列的映射关系,数据库访问层的开发简单了许多 所有数据库访问操作,均封装在 ...
- Spring Boot2 系列教程(二十)Spring Boot 整合JdbcTemplate 多数据源
多数据源配置也算是一个常见的开发需求,Spring 和 SpringBoot 中,对此都有相应的解决方案,不过一般来说,如果有多数据源的需求,我还是建议首选分布式数据库中间件 MyCat 去解决相关问 ...
- Spring Boot2 系列教程(二十二)整合 MyBatis 多数据源
关于多数据源的配置,前面和大伙介绍过 JdbcTemplate 多数据源配置,那个比较简单,本文来和大伙说说 MyBatis 多数据源的配置. 其实关于多数据源,我的态度还是和之前一样,复杂的就直接上 ...
- Spring Boot入门系列(十四)使用JdbcTemplate操作数据库,配置多数据源!
前面介绍了Spring Boot 中的整合Mybatis并实现增删改查.如何实现事物控制.不清楚的朋友可以看看之前的文章:https://www.cnblogs.com/zhangweizhong/c ...
随机推荐
- nginx+lua 设置跨域
nginx 配置: header_filter_by_lua_file cros.lua; access_by_lua ' if ngx.var.request_method == "OPT ...
- 20Flutter通过TabController定义顶部tab切换,介绍生命周期函数
基本使用: import 'package:flutter/material.dart'; class TabBarControllerPage extends StatefulWidget { Ta ...
- 【423】COMP9024 Revision
目录: array '\0' 与 EOF 二维字符数组(字符串数组) 1. array: 参考:C 数组 参考:C 字符串 参考:C笔记之NULL和字符串结束符'\0'和EOF 总结:[个人理解,可能 ...
- (四)java对象的结构和对象的访问定位
在HotSpot虚拟机中,对象在内存中存储的布局可以分为3块区域:对象头(Header).实例数据(Instance Data)和对齐填充(Padding). 一. 对象头 HotSpot虚拟机的对象 ...
- PostgreSQL创建database默认编码为UTF-8
在psql中执行如下代码: create database logdb encoding='UTF8';
- MySQL建表时添加备注以及查看某一张表的备注信息
建表的时候对列和表明添加备注: DROP TABLE IF EXISTS test_table; CREATE TABLE test_table ( ID INTEGER AUTO_INCREMENT ...
- 超详细的RNN代码实现(tensorflow)
一.学习单步的RNN:RNNCell 如果要学习TensorFlow中的RNN,第一站应该就是去了解“RNNCell”,它是TensorFlow中实现RNN的基本单元,每个RNNCell都有一个cal ...
- eclipse 解决POM文件错误:org.apache.maven.archiver.MavenArchiver.getManifest(org.apache.maven.project.MavenProject, org.apache.maven.archiver.MavenArchiveConfiguration)
解决方案: 更新eclipse中的maven插件 1.1 Help -> Install New Software -> Add 1.2 Location中输入 http://repo1. ...
- python获取昨日日期
获取昨日日期oneday = datetime.timedelta(days=1) 一天 day = datetime.datetime.strptime(self.date,'%Y-%m-%d') ...
- java基本思想
面向对象 众所周知,面向对象编程思想是java的基本思想.java的整个体系和技术实现都是以这个思想为基础.(这个通过类和接口能看出来,后面提到) 对这个事情的认知度甚至变成了很多公司的面试标准.比如 ...