Mybatis的入门

Mybatis

连接数据库的方式可以有传统的jdbchibernate方式。然而hibernate的连接效率不高,但是简便;jdbc连接效率高,不过需要自己去编写相关的代码。

JDBC的问题存在于:

1、 驱动包硬编码到代码中

2、 连接信息硬编码到代码中

3、 Sql硬编码到编码中

4、 设置输入参数需要手动编写

5、 输出数据参数需要手动编写

6、 遍历不方便

于是就推出了在JDBC方式和hibernate方式之间的mybatis技术。


Mybatis是一个类似于HibernateORM的持久化框架,支持普通SQL查询,存储过程以及高级映射。Mybatis通过使用简单的XML或注解用于配置和原始映射,将接口和POJO对象映射成数据库中的记录

 

Mybatis的整体结构:

 

 

从图中也可以得出:

1、 mybatis需要两个配置文件

第一类是全局的配置文件:mybatis-config.xml

第二类是映射文件:POJO类名+Mapper.xml 或者放在dao层和dao同一目录为:dao类名+Mapper.xml

2、 通过mybatis的配置文件获得sqlSessionFactory,然后通过sqlSEssionFactoryBuilder来创建对象builder方法获取

3、 通过sqlSessionFactory来获取sqlSession对象

4、 通过执行器Executor执行sql信息

5、 Sql输入参数类型:HashMapString基本类型、Pojo

6、 结果集输出参数类型:HashMapString基本类型、Pojo

 

实例:

通过一个maven项目来实现对mybatiscrud操作

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>
  	<!-- 扫描properties文件 -->
  	<properties resource="jdbc.properties" />
  
  	<!-- 开启驼峰自动映射文件 -->
  	<settings>
  	<setting name="mapUnderscoreToCamelCase" value="true"/>
  	</settings>
  
  	<!-- 设置变量值 -->
  	<typeAliases>
<typeAlias type="mjf.haihan.mybatis.pojo.User" alias="User"/>
  	</typeAliases>
  
  	<!-- 配置mybatis的数据库信息,以后在spring中配置 -->
  	<environments default="development">
  	<environment id="development">
  	<transactionManager type="JDBC" />
  	<dataSource type="POOLED">
  	<property name="driver" value="${jdbc.driver}"/>
  	<property name="url" value="${jdbc.url}"/>
  	<property name="username" value="${jdbc.username}"/>
  	<property name="password" value="${jdbc.password}"/>
  	</dataSource>
  	</environment>
  	</environments>
  
  	<!-- 导入映射文件 -->
  	<mappers>
  	<!-- <mapper class="mjf.haihan.mybatis.dao.UserDao"/>  采用dao类来导入映射文件 -->
  	 <!-- <mapper resource="UserMapper.xml"/> --> <!--采用映射文件直接导入 -->
  	<!-- <mapper url="D://itcast/UserMapper.xml"/>  采用文件的全路径来导入映射文件 -->
  	<package name="mjf.haihan.mybatis.dao"/>  <!-- 采用扫描dao包的dao类导入映射文件 -->
  	</mappers>
  
  </configuration>

测试类:
    package mjf.haihan.dao.test;
 
import java.io.InputStream;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import mjf.haihan.mybatis.dao.UserDao;
import mjf.haihan.mybatis.pojo.User;
 
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 org.junit.Before;
import org.junit.Test;
 
public class UserDaoTest {
 
private  SqlSessionFactory sqlSessionFactory;
private  SqlSession session;
private  UserDao userDAO;
@Before
public  void setUpBefore() throws Exception {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
session = sqlSessionFactory.openSession(true);
userDAO = session.getMapper(UserDao.class);
}
 
/** 根据id查询用户 */
@Test
public void testquerybyId() {
User user  = userDAO.queryById(1L);
System.out.println(user);
}
 
/** 根据用户名和密码查询用户(占位符) */
@Test
public void testquerybynameandpass1(){
User user = userDAO.queryByNameAndPass1("zhangsan", "123456");
System.out.println(user);
}
/** 根据用户名和密码查询用户(注解) */
@Test
public void testquerybynameandpass2(){
User user = userDAO.queryByNameAndPass2("zhangsan", "123456");
System.out.println(user);
}
/** 查询所有的用户 */
@Test
public void testqueryAll(){
List<User> list = userDAO.queryAll();
for(User user :list){
System.out.println(user);
}
}
/** 使用Map查询用户*/
@Test
public void testqueryMapUser(){
Map<String,String> map = new HashMap<>();
map.put("userName", "zhangsan");
map.put("password", "123456");
User user = userDAO.queryMap(map);
System.out.println(user);
}
/** 添加用户 */
@Test
public void testaddUser(){
User user = new User();
user.setUserName("mao");
user.setPassword("123123");
user.setName("毛竣锋");
user.setAge(20);
user.setSex(1);
Date date = new Date();
user.setBirthday(date);
userDAO.addUser(user);
}
/** 修改用户 */
@Test
public void testupdateUser(){
User user = userDAO.queryById(8L);
user.setName("毛竣锋");
user.setUserName("maojunfeng");
userDAO.updateUser(user);
}
/** 删除用户*/
@Test
public void testdeleteUser(){
userDAO.deleteUser(8L);
}
}
 

UserDao.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="mjf.haihan.mybatis.dao.UserDao">
  	<!-- 根据id来查询user -->
 	<select id="queryById"  resultType="User">
 	SELECT * from tb_user where id =#{id}
 	</select>
 
 	<!-- 一、 根据用户名和密码查询用户 -->
 	<select id="queryByNameAndPass1" resultType="User">
 	SELECT * from tb_user where user_name =#{0} and password = #{1}
 	</select>
 	<!-- 二、根据用户名和密码查询用户 -->
 	<select id="queryByNameAndPass2" resultType="User">
 	SELECT * from tb_user where user_name = #{userName} and password = #{password}
 	</select>
 
 	<!-- 查询所有user -->
 	<select id="queryAll" resultType="User" >
 	SELECT * from tb_user
 	</select>
 
 	<!-- 添加用户
 useGeneratedKeys : 是否开启自添回填
  keyProperty : 对象中的属性名
  keyColumn :数据库表的字段名
  -->
 	<insert id="addUser" parameterType="User"
 	keyColumn="id" keyProperty="id" useGeneratedKeys="true"
 	>
 	INSERT INTO tb_user (
user_name,
password,
name,
age,
sex,
birthday,
created,
updated
)
VALUES
(
#{userName},
#{password},
#{name},
#{age},
#{sex},
#{birthday},
NOW(),
NOW()
);
 	</insert>
 
 	<!-- 修改用户 -->
 	<update id="updateUser" parameterType="User">
 	UPDATE tb_user set
 user_name = #{userName},
 password = #{password},
 name = #{name},
 age = #{age},
 sex = #{sex},
 birthday = #{birthday},
 updated = NOW()
WHERE id =#{id}
 	</update>
 
 	<!-- 删除用户 -->
 	<delete id="deleteUser">
 	DELETE FROM tb_user where id = #{id};
 	</delete>
 
 	<!-- hashMap -->
 	<select id="queryMap"  resultType="User">
 	SELECT * from tb_user where user_name = #{userName} and password = #{password};
 	</select>
 
  </mapper>
 


使用mybatis可以不实现dao实现类,实现类:使用不方便,实现的方法都几乎差不多。所以交给mybatis来实现

 

dao层的方法中,方法名和映射文件中的id需要一致,如果没有使用dao层的方法,则可以使用sqlsession的方法,参数为namespaceid名:

SqlSession.selectOne(mjf.haihan.mybatis.selectOne,1L);

 

Mybatis的动态代理实现

Namespace的作用:

Mapper中的namespace的定义本身是没有限制的,只要不重复即可,但是如果想要使用Mybatis提供的DAO的动态代理,namespace就必须为DAO接口的全路径

在代码中就只需要定义一个DAO接口就行 ,使用sqlSessiongetMapper方法,参数为接口类

userDAO = session.getMapper(UserDao.class);

Mapper.xml配置文件中,每个方法的定义id必须和DAO层的方法一致

public User queryById(Long id);
<select id="queryByNameAndPass1" resultType="User">


在使用映射文件进行操作时,除了在映射文件定义selectupdate...语句外,还可以使用注解@select@update...参数为sql语句

@Select("SELECT * from tb_user where id =#{id}")

Mybatis-config的全局配置文件:

 

settings属性:

设置参数

描述

有效值

默认值

cacheEnabled

该配置影响的所有映射器中配置的缓存的全局开关。

true | false

true

lazyLoadingEnabled

延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。

true | false

false

aggressiveLazyLoading

当启用时,带有延迟加载属性的对象的加载与否完全取决于对任意延迟属性的调用;反之,每种属性将会按需加载。

true | false

true

multipleResultSetsEnabled

是否允许单一语句返回多结果集(需要兼容驱动)。

true | false

true

useColumnLabel

使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。

true | false

true

useGeneratedKeys

允许 JDBC 支持自动生成主键,需要驱动兼容。如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。

true | false

False

autoMappingBehavior

指定 MyBatis 是否以及如何自动映射指定的列到字段或属性。NONE 表示取消自动映射;PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。FULL 会自动映射任意复杂的结果集(包括嵌套和其他情况)。

NONE, PARTIAL, FULL

PARTIAL

defaultExecutorType

配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements);BATCH 执行器将重用语句并执行批量更新。

SIMPLE REUSE BATCH

SIMPLE

defaultStatementTimeout

设置超时时间,它决定驱动等待数据库响应的秒数。

Any positive integer

Not Set (null)

safeRowBoundsEnabled

允许在嵌套语句中使用行分界(RowBounds)。

true | false

False

mapUnderscoreToCamelCase

是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。

true | false

False

localCacheScope

MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。

SESSION | STATEMENT

SESSION

jdbcTypeForNull

当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型。某些驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULLVARCHAR OTHER

JdbcType enumeration. Most common are: NULL, VARCHAR and OTHER

OTHER

lazyLoadTriggerMethods

指定哪个对象的方法触发一次延迟加载。

A method name list separated by commas

equals,clone,hashCode,toString

defaultScriptingLanguage

指定动态 SQL 生成的默认语言。

A type alias or fully qualified class name.

org.apache.ibatis.scripting.xmltags.XMLDynamicLanguageDriver

callSettersOnNulls

指定当结果集中值为 null 的时候是否调用映射对象的 settermap 对象时为 put)方法,这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。注意原始类型(intboolean等)是不能设置成 null 的。

true | false

false

logPrefix

指定 MyBatis 增加到日志名称的前缀。

Any String

Not set

logImpl

指定 MyBatis 所用日志的具体实现,未指定时将自动查找。

SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING

Not set

proxyFactory

Mybatis 用来创建具有延迟加载能力的对象设置代理工具。

CGLIB | JAVASSIST

CGLIB

 

TypeAliases类型别名属性:

使用该属性,可以将需要设置的输入参数或者输出参数,通过这个别名来简化书写

<typeAliases>
<typeAlias alias="User" type="cn.itcast.mybatis.pojo.User" />
</typeAliases>
 
<select id="queryByNameAndPass1" resultType="User">
 SELECT * from tb_user where user_name =#{0} and password = #{1}
 </select>


 

Typehadnles类型处理器

类型处理器是在设置参数,以及从Result中检索值来匹配java数据类型,Mybatis提供非常多的默认类型处理器,一般情况下都可以满足日常的使用。

类型处理器

Java 类型

JDBC 类型

BooleanTypeHandler

java.lang.Boolean, boolean

任何兼容的布尔值

ByteTypeHandler

java.lang.Byte, byte

任何兼容的数字或字节类型

ShortTypeHandler

java.lang.Short, short

任何兼容的数字或短整型

IntegerTypeHandler

java.lang.Integer, int

任何兼容的数字和整型

LongTypeHandler

java.lang.Long, long

任何兼容的数字或长整型

FloatTypeHandler

java.lang.Float, float

任何兼容的数字或单精度浮点型

DoubleTypeHandler

java.lang.Double, double

任何兼容的数字或双精度浮点型

BigDecimalTypeHandler

java.math.BigDecimal

任何兼容的数字或十进制小数类型

StringTypeHandler

java.lang.String

CHAR VARCHAR 类型

ClobTypeHandler

java.lang.String

CLOB LONGVARCHAR 类型

NStringTypeHandler

java.lang.String

NVARCHAR NCHAR 类型

NClobTypeHandler

java.lang.String

NCLOB 类型

ByteArrayTypeHandler

byte[]

任何兼容的字节流类型

BlobTypeHandler

byte[]

BLOB LONGVARBINARY 类型

DateTypeHandler

java.util.Date

TIMESTAMP 类型

DateOnlyTypeHandler

java.util.Date

DATE 类型

TimeOnlyTypeHandler

java.util.Date

TIME 类型

SqlTimestampTypeHandler

java.sql.Timestamp

TIMESTAMP 类型

SqlDateTypeHandler

java.sql.Date

DATE 类型

SqlTimeTypeHandler

java.sql.Time

TIME 类型

ObjectTypeHandler

Any

其他或未指定类型

EnumTypeHandler

Enumeration Type

VARCHAR-任何兼容的字符串类型,作为代码存储(而不是索引)

EnumOrdinalTypeHandler

Enumeration Type

任何兼容的 NUMERIC 或 DOUBLE 类型,作为位置存储(而不是代码本身)。

 

Environments

环境配置,可以配置测试环境、开发环境、生产环境,但是在构建SqlSessionFactory时只能选择一个,虽然这种方式也可以做到很方便的分离多个环境,但是在实际使用场景下我们是使用spring来管理数据源环境大致与spring的数据源管理一样

<!-- 配置mybatis的数据库信息,以后在spring中配置 -->
  	<environments default="development">
  	<environment id="development">
  	<transactionManager type="JDBC" />
  	<dataSource type="POOLED">
  	<property name="driver" value="${jdbc.driver}"/>
  	<property name="url" value="${jdbc.url}"/>
  	<property name="username" value="${jdbc.username}"/>
  	<property name="password" value="${jdbc.password}"/>
  	</dataSource>
  	</environment>
  	</environments>

Mapper映射文件类似于Hibernatehbm映射文件,也是需要把该文件导入到全局文件中,导入全局文件有三种方式:Mappers映射文件:

1、 通过resources

直接把在类路径下的mapper文件导入到全局文件

<mappers><mapper resources=UserMapper.xml /></mappers>

2、 通过url

把在内存中的mapper文件导入全局文件,需要指定的是全路径

<mappers><mapper  url=D://m/UserMapper.xml  /></mappers>

3、 通过class

通过class引入时,需要把mapper.xml放在跟DAO层的同一个文件夹下,而名称也需要和DAO类名一致 ,引入的是DAO

<mappers><mapper class=”mjf.dao.UserDAO  /></mappers>

4、 还有一种方式:是通过包扫描的方式去加入到全局文件

对包直接进行扫描,来自动加入mapper文件,该文件也是需要放在同一个DAO层文件夹下的

<mappers><mapper package=mjf.dao  /></mappers>Mapper.xml编写:

<mappers>
  	<!-- <mapper class="mjf.haihan.mybatis.dao.UserDao"/>  采用dao类来导入映射文件 -->
  	 <!-- <mapper resource="UserMapper.xml"/> 采用映射文件直接导入 -->
  	<!-- <mapper url="D://itcast/UserMapper.xml"/>  采用文件的全路径来导入映射文件 -->
  	<package name="mjf.haihan.mybatis.dao"/>  <!-- 采用扫描dao包的dao类导入映射文件 -->
  	</mappers>

如果是直接导入类路径下的mapper文件,则不要;如果是导入class,或者是扫描包下的mapper文件,则需要:

sqlSession.getMapper(DAO);

同时需要在映射文件中的namespace设置为该DAO类的全路径:

<mapper namespace=mjf.haihan.mybatis.dao.UserDao>

 

parameterType的传入参数

1HashMap类型:

2Stringint…基本数据类型

3POJO的实体类

如果是以上三种参数,则可以省略不写;其他需要写上

传入参数为多参数时,需要使用定义名或者使用占位符

1、 定义名:@Param

Public void queryByNameandPass(@Param(username)String name,@Param(password)String password);

2、 使用占位符:从0开始

Select  *  from  table where name=#{0} and password = #{1}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
目标检测(Object Detection)是计算机视觉领域的一个核心问题,其主要任务是找出图像中所有感兴趣的目标(物体),并确定它们的类别和位置。以下是对目标检测的详细阐述: 一、基本概念 目标检测的任务是解决“在哪里?是什么?”的问题,即定位出图像中目标的位置并识别出目标的类别。由于各类物体具有不同的外观、形状和姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具挑战性的任务之一。 二、核心问题 目标检测涉及以下几个核心问题: 分类问题:判断图像中的目标属于哪个类别。 定位问题:确定目标在图像中的具体位置。 大小问题:目标可能具有不同的大小。 形状问题:目标可能具有不同的形状。 三、算法分类 基于深度学习的目标检测算法主要分为两大类: Two-stage算法:先进行区域生成(Region Proposal),生成有可能包含待检物体的预选框(Region Proposal),再通过卷积神经网络进行样本分类。常见的Two-stage算法包括R-CNN、Fast R-CNN、Faster R-CNN等。 One-stage算法:不用生成区域提议,直接在网络中提取特征来预测物体分类和位置。常见的One-stage算法包括YOLO系列(YOLOv1、YOLOv2、YOLOv3、YOLOv4、YOLOv5等)、SSD和RetinaNet等。 四、算法原理 以YOLO系列为例,YOLO将目标检测视为回归问题,将输入图像一次性划分为多个区域,直接在输出层预测边界框和类别概率。YOLO采用卷积网络来提取特征,使用全连接层来得到预测值。其网络结构通常包含多个卷积层和全连接层,通过卷积层提取图像特征,通过全连接层输出预测结果。 五、应用领域 目标检测技术已经广泛应用于各个领域,为人们的生活带来了极大的便利。以下是一些主要的应用领域: 安全监控:在商场、银行
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值