Mybatis基础知识汇总

Mybatis学习总结:

背景介绍:

mybatis:前身ibatis,于2010年迁移到google code,并改名为Mybatis。最后在2013年11月迁移到gitbub(全球开源网站)。

Mybatis 的初步认知:

  • Mybatis 是一个半自动的ORM持久成框架。apache下的顶级项目。

  • Mybatis是JDBC的轻量级的封装,使用时程序员只需要注入sql语句,mybatis通过映射可以灵活生成满足数据库的sql语句。

  • 解决了jdbc的一下几个问题:

    • 1.jdbc创建和销毁数据库的连接耗资源过大

    • 解决方法:mybatis框架内置连接池。

    • 2.sql语句在javaWeb 项目中,修改sql语句需要修改java项目中的代码不利于维护。
      -解决方法:mybatis采用配置文件注入sql语句,使sql语句与java代码分离。

      1. 使用jdbc查询对象时,够多的参数书写不方便。(每一个参数需要书写一个?占位符,并且还需要写一句对应的java语句)且不利于维护;
    • 解决方法:Mybatis使用自动映射java对象至sql语句,通过statement的parameterType进行传参

    • 4.jdbc查询时存在硬编码,当sql语句改变,系统解析是也发生变化,造成系统不利于维护。

    • 解决方法:Mybatis使用自动sql语句至Java对象,通过statement的resultType进行传参

Mybatis的使用步骤:

    1. 导入所需要的jar包,配置SqlMapConfig.xml,写入数据库连接信息,类的别名以及映射关系等信息;
    1. 加载配置文件,获取SqlSessionFactory对象
  • 3.获取SqlSession对象:调用Mapper.xml的sql语句(insert,update,delete,selectOne,selectLists)
  • 4.释放资源

案例展示:Mybatis的DAO层的两种方式:

原始DAO层开发方式:
1.数据库创建数据表本案例使用如下数据表:

1).创建t_user数据表

CREATE TABLE t_user (
uid int(11) NOT NULL AUTO_INCREMENT,
uname varchar(255) DEFAULT NULL,
usex varchar(255) DEFAULT NULL,
uage int(11) DEFAULT NULL,
PRIMARY KEY (uid)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

2). 插入5条数据:

INSERT INTO t_user VALUES ('1', '张三', '男', '25');
INSERT INTO t_user VALUES ('2', '李四', '男', '26');
INSERT INTO t_user VALUES ('3', '王五', '男', '27');
INSERT INTO t_user VALUES ('4', '赵六', '男', '30');
INSERT INTO t_user VALUES ('5', '小敏', '男', '25');

2.导入jar包,并配置SqlMapConfig.xml文件:

1.1}. 导入如下图所示jar包和log4j.properties

注:jar包说明:

- asm-4.2.jar
- cglib-3.1.jar
-1. 处理字节码的jar包
- mybatis-3.3.0.jar
- mybatis的核心jar包
- mysql-connector-java-5.1.12-bin.jar
- 2.连接数据库jdbcjar包
- jstl-1.2
- 3.标签jar包
- 4.其余jar为日志记录jar包,因为mybatis没有日志记录系统需要引用日记jar包完成打印。
1.2). log4j.properties配置信息:

Global logging configuration

log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2}.完善配置配置信息如下:

2.1)配置jdbc.properties,基本事项信息:

jdbc.driverName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8
jdbc.user=root
jdbc.pass=520

2.2)配置SqlMapConfig.xml文件:

















(一).配置文件信息解读:
1)

写入约束文件:
注:约束标签中有DTD表示:该文件的标签的书写必须按照内部规定。

2).属性标签:properties 目的:为连接数据库提供基本四项的信息:

两种使用如下:

2.1).手动单个设置属性信息(在xml文件中)



设置一个名称为jdbc.user 值为 root的属性。

2.2).引入写好的properits文件信息中的信息

注:properties标签会先加载内部标签,再加载外部文件,名称一致时,会替换内容

解析如下:


当执行properties,先将已有的属性(即在xml中先配置的信息)记性加载,然后在加载xml外的文件即(jdbc.properties),如果加载外部信息的时候遇到相同的属性名,则先加载的内容会被覆盖。

2.3)typeAliases 别名标签 作用 :给自定义的类设置别名:

两种使用方法:

[1].通过包设置别名:




解读:将com.web.dto下的所有类都以类名为别名,可简化在mapper.xml中的传参和返回类型的书写。配置好的别名都是类的类名,别名不部分大小写。

[2].通过类设置别名:




解读:将com.web.dto下的User类起名为user;

2.4)environments 环境配置标签 作用用于配置连接数据库的信息(当使用spring框架的时候就可以不用再配置)











解读:


设置模式为:开发模式


使用的连接方式:jdbc


配置连接的信息

2.5)mapper映射

四种使用方式:
[1].使用Mapper.xml配置文件的路径:



[2].使用Mapper的接口类的路径:



[3]. 使用Mapper.xml和Mapper接口所在的包配置映射

[4]. 使用Mapper.xml在本机上的路径

3}.创将Mybatis工具类和实体类以及测试类

工具类:

/**
* 功能描述:加载文件信息,获取sqlSession
*
* @Author 落叶尘纷
* @Date 2019/8/13 10:22
* @Version 1.0
*/
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory;

static {
InputStream in = null ;
try {
in = Resources.getResourceAsStream("sqlMapConfig.xml");

sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);

} catch (IOException e) {
e.printStackTrace();
}
}

public static SqlSession getSqlSession(){

return sqlSessionFactory.openSession();
}

public static void release(SqlSession sqlSession) {
sqlSession.close();
}
}

实体类

/**
* 功能描述:分装user用户实体类
*
* @Author 落叶尘纷
* @Date 2019/8/13 8:10
* @Version 1.0
*/
public class User {
private Integer uid;
private Integer uage;
private String uname;
private String usex;

public User() {
}

public User(Integer uid, Integer uage, String uname, String usex) {
this.uid = uid;
this.uage = uage;
this.uname = uname;
this.usex = usex;
}

@Override
public String toString() {
return "User{" +
"uid=" + uid +
", uage=" + uage +
", uname='" + uname + ''' +
", usex='" + usex + ''' +
'}';
}

public Integer getUid() {
return uid;
}

public void setUid(Integer uid) {
this.uid = uid;
}

public Integer getUage() {
return uage;
}

public void setUage(Integer uage) {
this.uage = uage;
}

public String getUname() {
return uname;
}

public void setUname(String uname) {
this.uname = uname;
}

public String getUsex() {
return usex;
}

public void setUsex(String usex) {
this.usex = usex;
}
}

创建UserMapper 接口 和UserMapper.xml文件:

UserMapper.xml约束如下:



<mapper.xml 配置了映射时,此处的namespace可以随意,使用原生的DAO时就需要namespace的名称 + 方法名称>

开始测试:(原生DAO方式调用)

1.)查询所有的记录信息

mapper接口中的方法:

List findAllUsers();

mapper.xml中的sql

测试类中的方法:

@Test
/**
* 查询所有记录
* */
public void showAllUsers(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

// 调用查询方法:查询所有的信息
List userList = session.selectList("com.web.mapper.UserMapper.findAllUsers");

// 循环打印信息
for (User user : userList) {
System.out.println(user);
}

// 关闭资源
session.close();

}

执行结果:

2.1)条件查询相关记录:查询姓张的用户

mapper接口中的方法:

List findUserLikeName( String name);

mapper.xml中的sql

测试类中的方法:

public void findUserLikeName(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

//设置传给的参数
String name = "张";

// 调用查询方法:查询所有的信息
List userList = session.selectList("com.web.mapper.UserMapper.findUserLikeName",name);

// 循环打印信息
for (User user : userList) {
System.out.println(user);
}

// 关闭资源
session.close();

}

执行结果:

2.2)通过姓名查询记录

mapper接口中的方法:

1.List findUserByName(@Param("name") String name);

取值方式可以是#{name}

2. List findUserByName( String name);

取值方式只能是#{value}

mapper.xml中的sql

1.

2.

测试类中的方法:

@Test
public void findUserByName(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

//设置传给的参数
String name = "王五";

// 调用查询方法:查询所有的信息
User u = session.selectOne("com.web.mapper.UserMapper.findUserByName",name);

// 打印信息
System.out.println(u);

// 关闭资源
session.close();
}

2.2)通过id查询记录

mapper接口中的方法:

User findUserByID( Integer uid);

mapper.xml中的sql

测试类中的方法:

@Test
public void findUserByID(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

//设置传给的参数
Integer uid = 2;

// 调用查询方法:查询所有的信息
User u = session.selectOne("com.web.mapper.UserMapper.findUserByID",uid);

// 打印信息
System.out.println(u);

// 关闭资源
session.close();

}

执行结果:

3)插入数据:

mapper接口中的方法:

void addUser(User user);

mapper.xml中的sql

1.
insert into t_user(
uname,
uage,
usex
)values (
#{uname},
#{uage},
#{usex}
)

2.在idea中插入的selectKey 会报错但是不影响执行


select LAST_INSERT_ID()

insert into t_user(
uname,
uage,
usex
)values (
#{uname},
#{uage},
#{usex}
)

测试类中的方法:
@Test
public void addUser(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

//设置传给的参数
User user = new User();
user.setUage(36);
user.setUname("石敢当");
user.setUsex("男");

// 调用添加方法并返回影响行数
int insert = session.insert("com.web.mapper.UserMapper.addUser", user);
//添加
session.commit();
// 打印信息
System.out.println(user);

// 关闭资源
session.close();
}

执行结果

4)修改信息

mapper接口中的方法:

void updateUser(User user);

mapper.xml中的sql


update t_user set uname = #{uname},
uage = #{uage},usex = #{usex} where uid =#{uid}

测试类中的方法:

@Test
public void updateUser(){
//获取 sqlSession
SqlSession session = MybatisUtil.getSqlSession();

//设置传给的参数
User user = new User();
user.setUid(1);
user.setUage(36);
user.setUname("赵小花");
user.setUsex("男");

// 查询修改修改的记录的信息
User user1 = session.selectOne("com.web.mapper.UserMapper.findUserByID", 1);
System.out.println(user1);

// 调用修改方法并返回影响行数
session.update("com.web.mapper.UserMapper.updateUser", user);

session.commit();
// 打印信息
System.out.println(user);

// 关闭资源
session.close();
}
执行结果

总结:

    1. :用于非条件拼接sql语句 例如 name like '#{name}' 这种不可取。

    1. $:用于条件拼接sql语句 正常使用会报错 例如 name = ${name} 或 name = $
  • 3.当在mapper接口中的参数没有使用@Param("别名")设置别名时,对于String类型的数据只能使用#{value} 或者 ${value} ,当起了别名时只有#可以使用别名获取。但是#和$使用的时候还需要注意使用的情况是否拼接。
  • 4.其余类型的参数如果是单个可直接使用其参数名获取。
  • 5.如果是多个相同的参数类型,可以使用@Param("别名")设置别名。
  • 6.当数据过多可以使用map集合,通过主键名获取值。
  • 7.使用list集合只能自定义封装类或是起别名。
  • 8.使用时注意mapper.xml中的id名称是唯一的,且方法和mapper中的接口对应。
  • 9.原始的DAO和动态DAO单个框架使用增删改的时候都需要使用 session.commit() 提交到数据库。(在联合spring框架就不需要,因为他有很完善的事务管理机制)
动态DAO层开发方式:

(mapper中的方法和mapper.xml和原始的一样);
1).查询所有信息:

测试类中的测试方法:
@Test
public void showAllUsers1(){
// 获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
// 通过sqlsession 放射 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);
// 调用接口中的方法
List allUsers = mapper.findAllUsers();
// 循环打印
for (User allUser : allUsers) {
System.out.println(allUser);
}
// 释放资源
session.close();
}

2).添加信息:

@Test
public void addUser1(){
// 获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
// 通过sqlsession 放射 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);

//设置传给的参数
User user = new User();
user.setUage(37);
user.setUname("赵花");
user.setUsex("男");
// 调用添加方法
mapper.addUser(user);
// 事务提交到数据库
session.commit();
System.out.println(user);
session.close();
}

3).修改信息

@Test
public void addUser1(){
// 获取SqlSession
SqlSession session = MybatisUtil.getSqlSession();
// 通过sqlsession 放射 获取Mapper接口
UserMapper mapper = session.getMapper(UserMapper.class);

//设置传给的参数
User user = new User();
user.setUid(1);
user.setUage(37);
user.setUname("赵类");
user.setUsex("女");
// 调用添加方法
mapper.updateUser(user);
// 事务提交到数据库
session.commit();
System.out.println(user);
session.close();
}

  • 1.动态DAO方法:使用sqlSession通过反射获取Mapper接口对象。增删改查的方法直接利用

动态sql语句:

  1. if 标签:

    如果判断正确,将if标签内的信息拼接进去。如下:

  • 使用的String类型只有一个的时候如果是模糊,依旧不能使用

2.1)不报错:

2.2)报错:

2).总结:当只有一个String类型的参数时,使用动态sql语句取值,非拼接转态只能使用#{value},拼接只能使用${value}。对于非动态,没有拼接的可以使用别名。拼接的只能使用${value}获取值。

3)Where 标签:
相当于一个添加一个where 关键字:语句解释如下:

等同于 :

4).sql标签:动态标签中唯一一个和select 同级别的标签:
作用:通常书写一个常用的条件,一般使用</include>引入<insert>,<update>,<delete>等标签如下所示

findAllUsers 方法查询所有的记录数据


select * from t_user;

正确格式sql语句

<![CDATA[
sql 拼接语句
]>

正确识别大于号和小于号:无法识别的原因是因为标签使用的就是大于号和小于号,容易结束整条标签语句。

5).forEach标签:(集合数据循环)


delete from t_user

uid in

${id}


相当于sql语句:
delete form t_user where uid in (1,2){小括号好内是集合中的数据}

解释:

  • collection:list属性的别名
  • item :循环中使用时的别名
  • separator每次循环中间的拼接字符
  • open:开始符号
  • close:结束符号

list 类型使用:

  • 在mapper接口中的list参数起一个别名
  • 封装在另一个类中作为属性使用
posted @ 2019-08-13 22:15  落叶尘纷  阅读(698)  评论(0)    收藏  举报