Mybatis01

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();
		}
		
		
		
		
	}

2.2 Jdbc问题总结

1、 数据库连接频繁开启和关闭,会严重影响数据库的性能。

2、 代码中存在硬编码,分别是数据库部分的硬编码和SQL执行部分的硬编码。

 

3 Mybatis框架原理(核心)

3.1 框架图

Mybatis01_第1张图片

3.2分析结论

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.频繁开启和关闭数据库连接,会造成数据库性能下降

数据库连接池(全局配置文件)

四、入门程序

    需求:对订单商品案例中的用户表进行增删改查操作

  1. 根据用户ID查询用户信息
  2. 根据用户名称模糊查询用户列表
  3. 添加用户
  4. 删除用户(练习)
  5. 修改用户(练习)

4.2.1下载mybatis

mybaits的代码由github.com管理,下载地址:https://github.com/mybatis/mybatis-3/releases

Mybatis01_第2张图片

  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工程搭建

Mybatis01_第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遗留下来)






  全部映射文件中加载配置文件

Mybatis01_第4张图片

测试代码


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查询集合对象

 

你可能感兴趣的:(mybatis)