搭建数据库
create datebase `mybatis`
use `mybatis`
drop table if exists `user`;
create table `user`(
`id` int(20) not null
`name` varchar(30) default null
`pwd` varchar(30) default null,
primary key(`id`)
)engine=InnoDB default charset=utf-8;
insert into `user`(`id`,`name`,`pwd`) values (1,'狂神','123456'),
(2,'张三','abcdef'),
(3,'李四','987654');
导入jar包
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.47version>
dependency>
编写mybatis核心配置文件
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"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/kuang/dao/userMapper.xml"/>
mappers>
configuration>
编写工具类
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils{
private static SqlSessionFactory sqlSessionFactory;
static{
try{
string resource ="mybatis-config.xml";
InputStream inputStream = Resources.getReSourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
catch(IOException e){
e.printStackTrace();
}
}
}
public static SqlSession getSession(){
return sqlSessionFactory.openSession();
}
创建实体类
public class User {
private int id; //id
private String name; //姓名
private String pwd; //密码
//构造,有参,无参
//set/get
//toString()
}
编写Mapper接口类
import com.kuang.pojo.User;
import java.util.List;
public interface UserMapper{
List<User> selectUser();
}
编写userMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.dao.UserMapper">
<select id="selectUser" resultType="com.kuang.pojo.User">
select * from user
select>
mapper>
编写测试类
public class Mytest{
@Test
public void selectUser() {
SqlSession session = MybatisUtils.getSession();
//方法一:
//List users = session.selectList("com.kuang.mapper.UserMapper.selectUser");
//方法二:
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> users = mapper.selectUser();
for (User user: users){
System.out.println(user);
}
session.close();
}
}
运行测试
注意点
可能出现问题,原因为mapper.xml在java包下无法解析,导致mapper无法生效(maven静态资源过滤问题)
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
<filtering>falsefiltering>
resource>
resources>
方法二
将xml文件移到resource目录下,并修改核心配置文件里mapper 的地址位置
userMapper 接口添加方法
public interface UserMapper {
//查询全部用户
List<User> selectUser();
//根据id查询用户
User selectUserById(int id);
//添加一个用户
int addUser(User user);
//根据id删除用户
int deleteUser(int id);
}
在UserMapper.xml中添加Select语句
<select id="selectUserById" resultType="com.kuang.pojo.User">
select * from user where id = #{id}
select>
<insert id="addUser" parameterType="com.kuang.pojo.User">
insert into user (id,name,pwd) values (#{id},#{name},#{pwd})
insert>
<delete id="deleteUser" parameterType="int">
delete from user where id = #{id}
delete>
测试类中测试
注意点:其中增删改需要提交事务
@Test
public void tsetSelectUserById() {
SqlSession session = MybatisUtils.getSession(); //获取SqlSession连接
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(5,"王五","zxcvbn");
int i = mapper.addUser(user);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.deleteUser(5);
System.out.println(i);
session.commit(); //提交事务,重点!不写的话不会提交到数据库
session.close();
}
**练习:**根据密码和名字查询用户
方法一:在方法里传参数
在接口方法的参数前加 @Param属性
Sql语句编写的时候,直接取@Param中设置的值即可,不需要单独设置参数类型
//通过密码和名字查询用户
User selectUserByNP(@Param("username") String username,@Param("pwd") String pwd);
/*
<select id="selectUserByNP" resultType="com.kuang.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
select>
*/
方法二:用Map
用Map传参
User selectUserByNP2(Map<String,Object> map);
编写sql语句的时候,需要传递参数类型,参数类型为map
<select id="selectUserByNP2" parameterType="map" resultType="com.kuang.pojo.User">
select * from user where name = #{username} and pwd = #{pwd}
select>
在使用方法的时候,Map的 key 为 sql中取的值即可,没有顺序要求!
Map map = new HashMap();
map.put("username","小明");
map.put("pwd","123456");
User user = mapper.selectUserByNP2(map);
如果参数过多,我们可以考虑直接使用Map实现,如果参数比较少,直接传递参数即可
小结:
核心配置文件
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
我们可以阅读 mybatis-config.xml 上面的dtd的头文件!
environments元素
配置MyBatis的多套运行环境,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定)
子元素节点:environment
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
数据源是必须配置的。
有三种内建的数据源类型
type="[UNPOOLED|POOLED|JNDI]")
unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。
pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
数据源也有很多第三方的实现,比如dbcp,c3p0,druid等等…
详情:点击查看官方文档
这两种事务管理器类型都不需要设置任何属性。
具体的一套环境,通过设置id进行区别,id保证唯一!
子元素节点:transactionManager - [ 事务管理器 ]
子元素节点:数据源(dataSource)
mappers元素
mappers
file:///
的 URL),或类名和包名等。映射器是MyBatis中最核心的组件之一,在MyBatis 3之前,只支持xml映射器,即:所有的SQL语句都必须在xml文件中配置。而从MyBatis 3开始,还支持接口映射器,这种映射器方式允许以Java代码的方式注解定义SQL语句,非常简洁。引入资源方式
Mapper文件
namespace中文意思:命名空间,作用如下:
MyBatis 的真正强大在于它的映射语句,这是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 为聚焦于 SQL 而构建,以尽可能地为你减少麻烦。
Properties优化
数据库这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。具体的官方文档
我们来优化我们的配置文件
第一步 ; 在资源目录下新建一个db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=123456
第二步 : 将文件导入properties 配置文件
更多操作,可以查看官方文档!【演示带领学习】
typeAliases优化
类型别名是为 Java 类型设置一个短的名字。它只和 XML 配置有关,存在的意义仅在于用来减少类完全限定名的冗余。
当这样配置时,User
可以用在任何使用com.kuang.pojo.User
的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
每一个在包 com.kuang.pojo
中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
若有注解,则别名为其注解值。见下面的例子:
@Alias("user")
public class User {
...
}
去官网查看一下Mybatis默认的一些类型别名!
其他配置浏览
设置
设置(settings)相关 => 查看帮助文档
一个配置完整的 settings 元素的示例如下:
类型处理器
对象工厂
生命周期和作用域
作用域(Scope)和生命周期
理解我们目前已经讨论过的不同作用域和生命周期类是至关重要的,因为错误的使用会导致非常严重的并发问题。
我们可以先画一个流程图,分析一下Mybatis的执行过程!
作用域理解
解决Javabean的属性名与数据库表的字段不一致问题
public class User {
private int id; //id
private String name; //姓名
private String password; //密码和数据库不一样!
//构造
//set/get
//toString()
}
<resultMap id="UserMap" type="User">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
resultMap>
<select id="selectUserById" resultType="map">
select id , name , pwd
from user
where id = #{id}
select>
**注意:**利用注解开发就不需要mapper.xml映射文件了 .
1、我们在我们的接口中添加注解
//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
官方文档: mybatis-spring
Spring整合MyBatis, 主要目的就是把MyBatis核心配置文件中的内容,交给Spring来处理; 再简单点来说, 将MyBatis的SqlSessionFactory
和Mapper
的创建交给Spring处理;
要和Spring 一起使用MyBatis,需要在Spring应用上下文中定义至少两样东西:一个sqlsessionFactory
和至少一个数据映射器类。
在MyBatis-Spring 中,可使用sqlsessionFactoryBean
来创建sqlsessionFactory
。
注意:
sqlsessionFactory
需要一个Datasource
(数据源)。这可以是任意的DataSource
,只需要和配置其它Spring 数据库连接―样配置它就可以了。
在基础的MyBatis用法中,是通过SqlSessionFactoryBuilder
来创建SqlSessionFactory
的。而在 MyBatis-Spring 中,则使用SqlSessionFactoryBean
来创建。
在MyBatis 中,你可以使用SqlSessionFactory
来创建SqlSession
。一旦你获得―个session之后,你可以使用它来执行映射了的语句,提交或回滚连接,最后,当不再需要它的时候,你可以关闭session。
SqlSessionFactory
有一个唯一的必要属性:用于JDBC的DataSource
。这可以是任意的DataSource
对象,它的配置方法和其它Spring 数据库连接是―样的。
一个常用的属性是configLocation
,它用来指定MyBatis的XML配置文件路径。它在需要修改MyBatis 的基础配置非常有用。通常,基础配置指的是或元素。
需要注意的是,这个配置文件并不需要是一个完整的MyBatis配置。确切地说,任何环境配置( ),数据源( )和 MyBatis 的事务管理器()都会被忽略。SqlSessionFactoryBean会创建它自有的 MyBatis 环境配置( ) ,并按要求设置自定义环境的值。
sqlsessionTemplate
是MyBatis-Spring 的核心。作为Sqlsession
的一个实现,这意味着可以使用它无缝代替你代码中已经在使用的sqlsession
.
模板可以参与到Spring 的事务管理中,并且由于其是线程安全的,可以供多个映射器类使用,你应该总是用sqlSessionTemplate来替换 MyBatis 默认的Defaultsqlsession实现。在同一应用程序中的不同类之间混杂使用可能会引起数据—致性的问题。
可以使用 sqlsessionFactory作为构造方法的参数来创建SqlSessionTemplate对象。
注意:(下列步骤中省略mapper.xml的编写,可以参考上面例子中的编写)
通过SqlSessionFactoryBean
创建sqlSessionFactory
,再通过它创建sqlSessionTemplate。通过mapper实现类注入sqlSessionTemplate
创建Spring配置文件applicationContext.xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>
<bean id="myDataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<property name="driverClassName" value="${jdbc.driverClassName}"/>
<property name="username" value="${jdbc.username}"/>
<property name="url" value="${jdbc.url}"/>
<property name="password" value="${jdbc.password}"/>
bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="myDataSource"/>
<property name="configLocation" value="classpath:mybatis-config.xml"/>
<property name="typeAliasesPackage" value="com.sunny.ssm"/>
<property name="mapperLocations" value="classpath:mappers/*Mapper.xml"/>
bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory"/>
bean>
<bean id="userMapperImpl" class="com.sunny.ssm.mapper.UserMapperImpl">
<property name="sqlSession" ref="sqlSession"/>
bean>
增加Mapper(Dao)接口的实现类;私有化sqlSessionTemplate
public class UserMapperImpl implements UserMapper{
private SqlSessionTemplate sqlSession;
public void setSqlSession(SqlSessionTemplate sqlSession) {
this.sqlSession = sqlSession;
}
public List<User> selectAll() {
return sqlSession.getMapper(UserMapper.class).selectAll();
}
}
测试
@Test
public void test2() throws Exception{
ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
UserMapper userMapper = context.getBean("userMapperImpl", UserMapper.class);
for (User user : userMapper2.selectAll()) {
System.out.println(user);
}
}
结果成功输出!现在我们的Mybatis配置文件的状态!发现都可以被Spring整合!
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
configuration>
其实我们可以通过Spirng完全将mybatis配置文件去除,这里还是保留一个配置吧!
让Dao继承Support类 , 直接利用 getSqlSession()
获得 , 然后直接注入SqlSessionFactory
. 比起方式1 , 不需要管理SqlSessionTemplate , 而且对事务的支持更加友好
官方文档截图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JYGvw2U7-1628175901098)(C:\Users\superstrong\AppData\Roaming\Typora\typora-user-images\image-20210804150820165.png)]
修改UserMapperImpl
public class UserMapperImpl extends SqlSessionDaoSupport implements UserMapper {
public List<User> selectAll() {
return getSqlSession().getMapper(UserMapper.class).selectAll();
}
}
修改bean的配置
<bean id="userMapperImpl" class="com.sunny.ssm.mapper.UserMapperImpl2">
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
bean>
前两种的整合实现方式,都创建了Dao接口的实现类,通过实现类来获取mapper对象;
使用整合方式三,我们告诉Spring,让他来帮我们创建mapper的代理对象即可!
配置MapperFactoryBean,Spring帮我们创建 Mapper的代理对象
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="sqlSessionFactory" ref="mySqlSessionFactory"/>
<property name="mapperInterface" value="com.sunny.ssm.mapper.UserMapper"/>
bean>
或者采用下面扫描的方式
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.sunny.mapper"/>
bean>
Spring将数据访问过程中固定的和可变的部分明确划分为两个不同的类
导入jar包
MySQL的驱动包,spring-jdbc
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-jdbcartifactId>
<version>4.2.8.RELEASEversion>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.18version>
dependency>
src下创建配置db.properties
jdbc.user=root
jdbc.password=Hudie
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/jdbctemplate
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.initPoolSize=5
jdbc.maxPoolSize=10
配置xml
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.3.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<context:property-placeholder location="classpath:db.properties"/>
<bean id="dataSource"
class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="user" value="${jdbc.user}">property>
<property name="password" value="${jdbc.password}">property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}">property>
<property name="driverClass" value="${jdbc.driverClass}">property>
<property name="initialPoolSize" value="${jdbc.initPoolSize}">property>
<property name="maxPoolSize" value="${jdbc.maxPoolSize}">property>
bean>
<bean id="jdbcTemplate"
class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource">property>
bean>
beans>
测试1中的方法
import java.sql.SQLException;
import javax.sql.DataSource;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.jdbc.core.JdbcTemplate;
public class testJDBC {
private JdbcTemplate jdbcTemplate;
private ApplicationContext context = null;
//初始化连接池
{
context = new ClassPathXmlApplicationContext("applicationContext.xml");
jdbcTemplate = (JdbcTemplate) context.getBean("jdbcTemplate");
}
//update
@Test
public void testUpdate() {
String sql = "update student set name = ? where num = ?";
jdbcTemplate.update(sql, "pink",0001);
System.out.println("success");
}
//batchupdate
@Test
public void testBatechUpdate() {
String sql = "insert into student(num,password,name,age,score) value(?,?,?,?,?)";
List<Object[]> batchArgs = new ArrayList<Object[]>();
batchArgs.add(new Object[] {"007","123","pojp",23,99});
batchArgs.add(new Object[] {"008","123","trtp",23,99});
batchArgs.add(new Object[] {"009","123","QQQp",23,99});
jdbcTemplate.batchUpdate(sql, batchArgs);
}
//查询返回某个值
String sql = "select count(name) from student";
Long count = jdbcTemplate.queryForObject(sql, Long.class);
//query查询多行
String sql = "select num,name,age from student where id > ?";
RowMapper<stu> rowMapper = new BeanPropertyRowMapper<stu>(stu.class);
List<stu> s = jdbcTemplate.query(sql, rowMapper,0);//最后一个参数为id值
//query查询多行
String sql = "select num,name,age from student where id = ?";
RowMapper<stu> rowMapper = new BeanPropertyRowMapper<stu>(stu.class);
stu s = jdbcTemplate.queryForObject(sql, rowMapper,5);//最后一个参数为id值
}
可以查看下面这篇csdn博客
参考链接
原生mybatis:
主要为在工具栏中先通过配置文件获得SqlSessionFactoryBuilder
----->SqlSessionFactory
------>SqlSession
其中通过mapper.xml交给mybatis创建mapper接口的实现类,并在主配置文件中通过mapper.xml配置注册mapper
通过SqlSession
.getmapper获得mapper
spring+mybatis:
spring jdbctemplate
springboot +mybatis
其实就是将上述的spring的第三种整合方式(包扫描的方式)中的mybatis配置文件的配置信息移到到application.yml中,springboot会根据application.yml的配置更改自动配置时的信息
application.yml
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/zzz?useUnicode=true & characterEncoding=utf-8 &
useSSL=true & serverTimezone=Asia/Shanghai
username: root
password: 123456
mybatis:
mapper-locations: classpath:/mapper/*.xml
type-aliases-package: com.example.entity
在mapper的接口上加上**@mapper或者@MapperScan(“com.atguigu.admin.mapper”)**
小结:
所有说只要掌握了mybatis的实现过程,spring+mybatis的整合就会了,而springboot+mybatis的整合完全就是与spring大致相同,只是基于其的自动配置的特点发生了简单的变化,其底层的原理还是spring