Mybatis(一)实现单表的增删改查
一. 什么是Mybatis
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO)。
MyBatis参考资料官网:https://mybatis.github.io/mybatis-3/zh/index.html。
官网对Mybatis的介绍更加具有权威性:
- MyBatis 是支持定制化SQL、存储过程以及高级映射的优秀的持久层框架。
- MyBatis 避免了几乎所有的 JDBC 代码和手工设置参数以及抽取结果集。
- MyBatis 使用简单的 XML 或注解来配置和映射基本体,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
MyBatis优点:
1)、简单易学
mybatis本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
2)、灵活
mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql基本上可以实现我们不使用数据访问框架可以实现的所有功能,或许更多。
3)、解除sql与程序代码的耦合
通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。对开发人员而言,核心sql还是需要自己优化:sql和java编码分开,功能边界清晰,一个专注业务、 一个专注数据。
4)、提供映射标签,支持对象与数据库的orm字段关系映射。
5)、提供对象关系映射标签,支持对象关系组建维护。
6)、提供xml标签,支持编写动态sql。
MyBatis缺点:
1)、编写SQL语句时工作量很大,尤其是字段多、关联表多时,更是如此。
2)、SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
3)、框架还是比较简陋,功能尚有缺失,虽然简化了数据绑定代码,但是整个底层数据库查询实际还是要自己写的,工作量也比较大,而且不太容易适应快速数据库修改。
MyBatis与JDBC比较:
SQL夹在Java代码块里,耦合度高导致硬编码内伤,维护不易且实际开发需求中sql是有变化,频繁修改的情况多见。
MyBatis与Hibernate和JPA比较:
长难复杂SQL,对于Hibernate而言处理也不容易,内部自动生产的SQL,不容易做特殊优化。基于全映射的全自动框架,大量字段的POJO进行部分映射时比较困难。 导致数据库性能下降。
MyBatis与iBatis比较:
MyBatis是iBatis的升级版,用法有很多的相似之处,但是MyBatis进行了重要的改进。
1)、Mybatis实现了接口绑定,使用更加方便。
在ibatis2.x中我们需要在DAO的实现类中指定具体对应哪个xml映射文件, 而Mybatis实现了DAO接口与xml映射文件的绑定,自动为我们生成接口的具体实现,使用起来变得更加省事和方便。
2)、对象关系映射的改进,效率更高。
3)、MyBatis采用功能强大的基于OGNL的表达式来消除其他元素。
二. 开发第一个Mybatis查询
1.新建一个java工程
2.添加jar包,如下图:

3.新建包,管理代码
4.建库,建表
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`t_id` int(11) NOT NULL AUTO_INCREMENT,
`t_username` varchar(20) NOT NULL,
`t_password` varchar(8) NOT NULL,
PRIMARY KEY (`t_id`)
) -- ----------------------------
-- Records of t_user
-- ----------------------------
INSERT INTO `t_user` (t_username,t_password) VALUES ( 'lisi', '');
INSERT INTO `t_user` (t_username,t_password) VALUES ( 'wanger', '');
INSERT INTO `t_user` (t_username,t_password) VALUES ( '李四', '');
INSERT INTO `t_user` (t_username,t_password) VALUES ( '王二', '');
5.在src目录下添加全局配置文件config.xml和log4j.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>
<!--
default="development" 开发环境
default="work" 发布环境
--> <environments default="development"> <environment id="development"> <!-- 配置事物 -->
<transactionManager type="JDBC"></transactionManager> <!-- 配置数据源 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.61.22:3306/test" />
<property name="username" value="root"/>
<property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd"> <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
6.编写java实体类,生成set,get方法
public class User {
private Integer id;
private String username;
private String password;
}
7.编写sql映射文件---------------mapper文件
<?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" > <!-- 配置SQL语句,与实体类操作的对应关系。 -->
<!-- 保证唯一性 -->
<mapper namespace="com.softjx.model.UserMapper"> <!--
将返回的数据 与对象对应。将返回的数据,按照配置组装成对应的对象。
-->
<select id="selectAll" resultType="com.softjx.model.User">
select t_id as id,t_username as username,t_password password from t_user
</select> <select id="selectById" resultType="com.softjx.model.User">
select t_id as id,t_username as username,t_password password from t_user where t_id=#{id};
</select> </mapper>
8.在全局配置文件中添加mapper文件的位置
<!-- 导入映射文件 -->
<mappers>
<mapper resource="com/softjx/model/UserMapper.xml" />
</mappers>
9.编写测试代码:
public class TestMybatis {
private SqlSession session;
@Before
public void read() throws Exception {
// 构建mybatis的执行对象
FileInputStream fis = new FileInputStream("src/config.xml");
SqlSession session = new SqlSessionFactoryBuilder().build(fis)
.openSession();
// InputStream inputStream =
// Resources.getResourceAsStream("config.xml");
// SqlSession session = new
// SqlSessionFactoryBuilder().build(inputStream).openSession();
this.session = session;
}
@Test
public void TestSelectAll() {
System.out.println("查询所有用户");
try {
List<User> users = session
.selectList("com.softjx.model.UserMapper.selectAll");// 根据字符找sql语句
for (User user : users) {
System.out.println(user.getId() + " " + user.getUsername()
+ " " + user.getPassword());
}
} finally {
session.close();
}
}
@Test
public void TestSelectById() {
System.out.println("查询所有用户");
try {
User user = session
.selectOne("com.softjx.model.UserMapper.selectById",2);// 根据字符找sql语句
System.out.println(user.getId() + " " + user.getUsername() + " "
+ user.getPassword());
} finally {
session.close();
}
}
}
10.SqlSession
SqlSession 的实例不是线程安全的,因此是不能被共享的。
SqlSession每次使用完成后需要正确关闭,这个关闭操作是必须的。
三. 第一个Mybatis程序出错地方
1.全局配置文件没有指定mapper文件。
2.数据库配置出错。
3.jdbc驱动没有加载。
4.select 查询语句没有转化javabean中属性。
5.全局配置文件路径不对。
6.log4j.xml文件没有。
7.id名称写错了。
四.Mybatis添加,修改,删除
Mapper.xml文件的添加,修改,删除
<insert id="insertUser">
insert into t_user (t_username,t_password)
values (#{username},#{password})
</insert> <update id="updateUser">
update t_user set
t_username = #{username},
t_password = #{password}
where t_id = #{id}
</update> <delete id="deleteUser">
delete from t_user where t_id = #{id}
</delete>
测试添加,修改,删除
@Test
public void TestInserUser() {
System.out.println("添加一个用户");
try {
User user=new User();
user.setUsername("pkd");
user.setPassword("888888");
int count=session.insert("com.softjx.model.UserMapper.insertUser",user);// 根据字符找sql语句
session.commit();
System.out.println(count);
} finally {
session.close();
} } @Test
public void TestUpdateUser() {
System.out.println("更新一个用户");
try {
User user=new User();
user.setId(1);
user.setUsername("pkd");
user.setPassword("888888");
int count=session.update("com.softjx.model.UserMapper.updateUser",user);// 根据字符找sql语句
session.commit();
System.out.println(count);
} finally {
session.close();
} } @Test
public void TestDeleteUser() {
System.out.println("更新一个用户");
try {
int count=session.delete("com.softjx.model.UserMapper.deleteUser",1);// 根据字符找sql语句
session.commit();
System.out.println(count);
} finally {
session.close();
} }
五. Mybatis接口式编程CRUD
- 编写接口文件,作为dao层,只有定义接口,没有实现,其实现交给mapper.xml文件。
- 编写mapper.xml,注意其命名空间要是接口的路径。
- mapper.xml文件中sql语句与以前一样。
- 测试代码中使用接口的代理类对象,调用接口中的方法,实现数据处理。使用SqlSession获取映射器进行操作
接口代码:
public interface UserMapper {
//查询所有用户
public List<User> selectAll();
//查询所有用户
public List<User> selectAll1();
//查询一个用户
public User selectById(Integer id);
//添加用户
public int insertUser(User user);
//修改用户
public int updateUser(User user);
//删除用户
public int deleteUser(Integer id);
}
Mapper.xml映射文件:
<!-- 使用接口方式 加载命名空间 使用代理模式 -->
<mapper namespace="com.softjx.dao.UserMapper"> <!-- 查询数据表中的所有记录,并封装User对象集合 -->
<select id="selectAll" resultType="com.softjx.model.User">
select t_id as id,t_username as username,t_password password from t_user
</select> <select id="selectAll1" resultType="com.softjx.model.User">
select * from t_user1
</select> <!-- 根据id查询数据表中的一条记录,并封装User对象 -->
<select id="selectById" resultType="com.softjx.model.User">
select t_id as id,t_username as username,t_password password from t_user where t_id=#{id};
</select> <!-- 添加用户 -->
<insert id="insertUser">
insert into t_user (t_username,t_password)
values (#{username},#{password})
</insert> <!-- 更新用户 -->
<update id="updateUser">
update t_user set t_username=#{username},t_password=#{password}
where t_id=#{id}
</update> <!-- 删除用户 -->
<delete id="deleteUser">
delete from t_user where t_id=#{id}
</delete>
测试代码:
//查询所有
@Test
public void TestSelectAll1() {
System.out.println("查询所有用户"); //获取接口的实现类对象
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
try { UserMapper mapper=session.getMapper(UserMapper.class);
System.out.println(mapper);
List<User> users=mapper.selectAll();
System.out.println(users);
for (User user : users) {
System.out.println(user.getId() + " " + user.getUsername()
+ " " + user.getPassword());
}
} finally {
session.close();
} } //查询一个用户
@Test
public void TestSelectById() {
System.out.println("查询一个用户");
//获取接口的实现类对象
//会为接口自动的创建一个代理对象,代理对象去执行增删改查方法
try { UserMapper mapper=session.getMapper(UserMapper.class);
User user=mapper.selectById(2);
System.out.println(user);
System.out.println(user.getId() + " " + user.getUsername() + " "
+ user.getPassword());
} finally {
session.close();
} } //添加用户测试
@Test
public void TestInserUser() {
System.out.println("添加一个用户");
try {
User user=new User();
user.setUsername("pppp");
user.setPassword("666666"); UserMapper mapper=session.getMapper(UserMapper.class);
int count=mapper.insertUser(user);
session.commit();//这里一定要提交,不然数据进不去数据库中
//session.rollback();
System.out.println(count);
} finally {
session.close();
} } //修改用户测试
@Test
public void TestUpdateUser() {
System.out.println("修改用户");
try {
User user=new User();
user.setId(10);
user.setUsername("yyy");
user.setPassword("11111");
UserMapper mapper=session.getMapper(UserMapper.class);
int count=mapper.updateUser(user);// 根据字符找sql语句
session.commit();
//session.rollback();
System.out.println(count);
} finally {
session.close();
} } //删除用户测试
@Test
public void TestDeleteUser() {
System.out.println("删除用户");
try {
UserMapper mapper=session.getMapper(UserMapper.class);
int count=mapper.deleteUser(10);// 根据字符找sql语句
session.commit();
//session.rollback();
System.out.println(count);
} finally {
session.close();
} }
总结:
1.SqlSession 的实例不是线程安全的,因此是不能被共享的。
2.SqlSession每次使用完成后需要正确关闭,这个关闭操作是必须的。
3.SqlSession可以直接调用方法的id进行数据库操作,但是我们一般还是推荐使用SqlSession获取到Dao接口的代理类,执行代理对象的方法,可以更安全的进行类型检查操作。
Mybatis(一)实现单表的增删改查的更多相关文章
- python全栈开发day61-django简单的出版社网站展示,添加,删除,编辑(单表的增删改查)
day61 django内容回顾: 1. 下载: pip install django==1.11.14 pip install -i 源 django==1.11.14 pycharm 2. 创建项 ...
- hibernate对单表的增删改查
ORM: 对象关系映射(英语:Object Relational Mapping,简称ORM,或O/RM,或O/R mapping) 实现对单表的增删改查 向区域表中增加数据: 第一步: 新建一个Da ...
- Django学习笔记(10)——Book单表的增删改查页面
一,项目题目:Book单表的增删改查页面 该项目主要练习使用Django开发一个Book单表的增删改查页面,通过这个项目巩固自己这段时间学习Django知识. 二,项目需求: 开发一个简单的Book增 ...
- django模型层 关于单表的增删改查
关于ORM MTV或者MVC框架中包括一个重要的部分,就是ORM,它实现了数据模型与数据库的解耦,即数据模型的设计不需要依赖于特定的数据库, 通过简单的配置就可以轻松更换数据库,这极大的减轻了开发人员 ...
- 1.SSM整合_单表的增删改查
目标:增删改查 环境:Maven+Eclipse+Tomcat7+JDK7 思维导图: 表结构 目录结构 依赖 <dependencies> <dependency> < ...
- Django学习笔记--数据库中的单表操作----增删改查
1.Django数据库中的增删改查 1.添加表和字段 # 创建的表的名字为app的名称拼接类名 class User(models.Model): # id字段 自增 是主键 id = models. ...
- django 利用ORM对单表进行增删改查
牛小妹上周末,一直在尝试如何把数据库的数据弄到界面上.毕竟是新手,搞不出来,文档也看不懂.不过没关系,才刚上大学.今晚我们就来解释下,要把数据搞到界面的第一步.先把数据放到库里,然后再把数据从库里拿出 ...
- Django中对单表的增删改查
之前的简单预习,重点在后面 方式一: # create方法的返回值book_obj就是插入book表中的python葵花宝典这本书籍纪录对象 book_obj=Book.objects.creat ...
- 23Spring_JdbcTemplate来实现单表的增删改查
第一步建表:
随机推荐
- Java基础总结--常用类以及包的访问权限
-----Object---所有类的根类1.怎么得到的:通过对所有对象不断的向上抽取共性,具备所有对象的共性的东西2.常用的方法* equals(Object obj):比较两个对象的引用是否指向同一 ...
- LeetCode 39. Combination Sum (组合的和)
Given a set of candidate numbers (C) (without duplicates) and a target number (T), find all unique c ...
- vue 起步走 --“安装篇”
在说明之前,溶解得在这说一句 ,菜鸟开始安装这些东西真是不容易,各种疯狂的百度,搜索.(找的我眼泪都快流下来了),不说废话,开始正经. 第一步:环境的搭建 : vue推荐开发环境: Node.js: ...
- 脱壳第三讲,UPX压缩壳,以及补充壳知识
脱壳第三讲,UPX压缩壳,以及补充壳知识 一丶什么是压缩壳.以及壳的原理 在理解什么是压缩壳的时候,我们先了解一下什么是壳 1.什么是壳 壳可以简单理解为就是在自己的PE文件中包含了代码.而有不影响我 ...
- centos7 防火墙 配置
1.查看Firewall 服务状态 systemctl status firewalld 2.查看Firewall 的状态 firewall-cmd --state 注意: firewalld默认配置 ...
- .4-Vue源码之数据劫持(2)
开播了开播了! vue通过数据劫持来达到监听和操作DOM更新,上一节简述了数组变化是如何监听的,这一节先讲讲对象属性是如何劫持的. // Line-855 Observer.prototype.wal ...
- angular指令中@,=,&的区别
当directive中的scope设置为一个对象的时候,该指令就有了一个独立的作用域,AngularJS提供了一种绑定策略用于隔离作用域和外部作用域进行通信. 1.@(or @attr) 使用@符号可 ...
- MySQL冗余和重复索引
MySQL允许在相同列上创建多个索引,无论是有意还是无意,mysql需要单独维护重复的索引,并且优化器在优化查询的时候也需要逐个地进行考虑,这会影响性能. 重复索引是指的在相同的列上按照相同的顺序创建 ...
- AJAX,PHP,前端简单交互制作输入框效果
PHP数据 <?php // 数据 $arr = array( array("百度", "http://www.baidu.com/"), array(& ...
- cookie 子域名可以读父域名中的cookie
cookie 子域名可以读父域名中的cookie 如在 .ping.com域下注入cookie,则该子域下的网页如p1.ping.com.p2.ping.com 都能读取到cookie信息 path的 ...