1 Mybatis是什么?
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
2分析原生态jdbc程序中存在的问题
public static void main(String[] args) throws SQLException {
Connection connection=null;
PreparedStatement preparedstatement=null;
ResultSet resultset=null;
try {
//加载数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//通过驱动管理类获取数据库连接
connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8","root","123456");
//定义sql语句
String sql="select * from user where username=?";
//获取预处理statement
preparedstatement=connection.prepareStatement(sql);
//设置参数
preparedstatement.setString(1, "wangwu");
//向数据库发出sql查询 查询出结果集
resultset=preparedstatement.executeQuery();
//遍历查询结果集
while(resultset.next()){
System.out.println(resultset.getString("id")+"--"+resultset.getString("username"));
}
//释放资源
if (resultset!=null) {
resultset.close();
}
if (connection!=null) {
connection.close();
}
if(preparedstatement!=null){
preparedstatement.close();
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
1、 数据库连接频繁开启和关闭,会严重影响数据库的性能。
2、 代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。
1、 mybatis配置文件,包括Mybatis全局配置文件和Mybatis映射文件,其中全局配置文件配置了数据源、事务等信息;映射文件配置了SQL执行相关的 信息。
2、 mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,即会话工厂。
3、 通过SqlSessionFactory,可以创建SqlSession即会话。Mybatis是通过SqlSession来操作数据库的。
4、 SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
5、 Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括java的简单类型、HashMap集合对象、POJO对象类型。
问题总结
1.创建来连接时候,存在硬编码
配置文件(全局配置文件)
2.正在执行statement时候存在硬编码
配置文件(映射文件)
3.频繁开启和关闭数据库连接,会造成数据库性能下降
数据库连接池(全局配置文件)
需求:对订单商品案例中的用户表进行增删改查操作
4.2.1下载mybatis
mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases
4.2.2数据库脚本初始化
4.2.2.1数据库脚本
/*
SQLyog v10.2
MySQL - 5.1.72-community : Database - mybatis
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Table structure for table `items` */
CREATE TABLE `items` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL COMMENT '商品名称',
`price` float(10,1) NOT NULL COMMENT '商品定价',
`detail` text COMMENT '商品描述',
`pic` varchar(64) DEFAULT NULL COMMENT '商品图片',
`createtime` datetime NOT NULL COMMENT '生产日期',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
/*Table structure for table `orderdetail` */
CREATE TABLE `orderdetail` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`orders_id` int(11) NOT NULL COMMENT '订单id',
`items_id` int(11) NOT NULL COMMENT '商品id',
`items_num` int(11) DEFAULT NULL COMMENT '商品购买数量',
PRIMARY KEY (`id`),
KEY `FK_orderdetail_1` (`orders_id`),
KEY `FK_orderdetail_2` (`items_id`),
CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
/*Table structure for table `orders` */
CREATE TABLE `orders` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NOT NULL COMMENT '下单用户id',
`number` varchar(32) NOT NULL COMMENT '订单号',
`createtime` datetime NOT NULL COMMENT '创建订单时间',
`note` varchar(100) DEFAULT NULL COMMENT '备注',
PRIMARY KEY (`id`),
KEY `FK_orders_1` (`user_id`),
CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;
/*Table structure for table `user` */
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(32) NOT NULL COMMENT '用户名称',
`birthday` date DEFAULT NULL COMMENT '生日',
`sex` char(1) DEFAULT NULL COMMENT '性别',
`address` varchar(256) DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=27 DEFAULT CHARSET=utf8;
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
/*
SQLyog v10.2
MySQL - 5.1.72-community : Database - mybatis
*********************************************************************
*/
/*!40101 SET NAMES utf8 */;
/*!40101 SET SQL_MODE=''*/;
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
/*Data for the table `items` */
insert into `items`(`id`,`name`,`price`,`detail`,`pic`,`createtime`) values (1,'台式机',3000.0,'该电脑质量非常好!!!!',NULL,'2015-02-03 13:22:53'),(2,'笔记本',6000.0,'笔记本性能好,质量好!!!!!',NULL,'2015-02-09 13:22:57'),(3,'背包',200.0,'名牌背包,容量大质量好!!!!',NULL,'2015-02-06 13:23:02');
/*Data for the table `orderdetail` */
insert into `orderdetail`(`id`,`orders_id`,`items_id`,`items_num`) values (1,3,1,1),(2,3,2,3),(3,4,3,4),(4,4,2,3);
/*Data for the table `orders` */
insert into `orders`(`id`,`user_id`,`number`,`createtime`,`note`) values (3,1,'1000010','2015-02-04 13:22:35',NULL),(4,1,'1000011','2015-02-03 13:22:41',NULL),(5,10,'1000012','2015-02-12 16:13:23',NULL);
/*Data for the table `user` */
insert into `user`(`id`,`username`,`birthday`,`sex`,`address`) values (1,'王五',NULL,'2',NULL),(10,'张三','2014-07-10','1','北京市'),(16,'张小明',NULL,'1','河南郑州'),(22,'陈小明',NULL,'1','河南郑州'),(24,'张三丰',NULL,'1','河南郑州'),(25,'陈小明',NULL,'1','河南郑州'),(26,'王五',NULL,NULL,NULL);
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
4.3工程搭建
4.4代码实现
4.4.1创建po类 User.java
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
4.4.2创建全局配置文件
在config目录下,创建SqlMapConfig.xml文件,该名称不是固定不变的。
根据用户ID查询用户信息
在config目录下,创建User.xml(这种命名规范是由ibatis遗留下来)
全部映射文件中加载配置文件
测试代码
public class Testdemo {
@Test
public void findUserByIdTest() throws IOException{
//读取配置文件
//全局配置文件的路径
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建sqlsessionfactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建sqlSession
SqlSession sqlSession=sqlSessionFactory.openSession();
//调用sqlSession的增删改查方法
//第一个参数表示statement的唯一标识
User user=sqlSession.selectOne("test.findUserById",1);
System.out.println(user);
//关闭资源
sqlSession.close();
}
}
根据用户名模糊查询
@Test
public void findUsersByNameTest() throws IOException{
//读取配置文件
//全局配置文件的路径
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建sqlsessionfactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建sqlSession
SqlSession sqlSession=sqlSessionFactory.openSession();
//调用sqlSession的增删改查方法
//第一个参数表示statement的唯一标识
List list=sqlSession.selectList("test.findUsersByName","小明");
System.out.println(list);
//关闭资源
sqlSession.close();
}
添加用户
INSERT INTO USER (username,birthday,sex,address)
VALUES(#{username},#{birthday},#{sex},#{address})
@Test
public void insertUserTest() throws IOException{
//读取配置文件
//全局配置文件的路径
String resource="SqlMapConfig.xml";
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建sqlsessionfactory
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//创建sqlSession
SqlSession sqlSession=sqlSessionFactory.openSession();
//调用sqlSession的增删改查方法
//第一个参数表示statement的唯一标识
User user=new User();
user.setUsername("陈梦捷");
user.setAddress("杭州");
sqlSession.insert("test.insertUser",user);
//提交事务
sqlSession.commit();
//关闭资源
sqlSession.close();
}
主键返回之自增主键
SELECT LAST_INSERT_ID()
INSERT INTO USER (username,birthday,sex,address)
VALUES(#{username},#{birthday},#{sex},#{address})
主键返回值序列
序列就是sequence,它是oracle的主键生成策略
小结
* #{}和${}
#{}表示占位符?,#{}接收简单类型的参数时,里面的名称可以任意
${}表示拼接符,${}接收简单类型的参数时,里面的名称必须是value
${}里面的值会原样输出,不加解析(如果该参数值是字符串,有不会添加引号)
${}存在sql注入的风险,但是有些场景下必须使用,比如排序后面会动态传入排序的列名
*parameterType和resultType
parameterType指定输入参数的java类型,parameterType只有一个,也就是说入参只有一个。
resultType指定输出结果的java类型(是单条记录的java类型)
*selectOne和selectList
selectOne查询单个对象
selectList查询集合对象