1、数据库连接频繁的创建和关闭,缺点浪费数据库的资源,影响操作效率
设想:使用数据库连接池
2、sql语句是硬编码,如果需求变更需要修改sql,就需要修改java代码,需要重新编译,系统不易维护。
设想:将sql语句统一配置在文件中,修改sql不需要修改java代码。
3、通过preparedStatement向占位符设置参数,存在硬编码( 参数位置,参数)问题。系统不易维护。
设想:将sql中的占位符及对应的参数类型配置在配置文件中,能够自动输入映射。
4、遍历查询结果集存在硬编码(列名)。
设想:自动进行sql查询结果向java对象的映射(输出映射)。
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis,实质上Mybatis对ibatis进行一些改进。 目前mybatis在github上托管。
MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
jdk1.6.0_45
myeclips10.0
mysql:mysql5.1
从mybatis官网下载(地址:https://github.com/mybatis/mybatis-3/releases)
mybatis-3.2.7.pdf---操作手册
mybatis-3.2.7.jar--核心 jar包
依赖的jar包
需要数据库的驱动包:
Mysql-connector-java-5.1.7-bin
数据库中有已经导入的四个表:items:(商品信息表);orderdetail:(订单明细表);orders:(订单表);user:(用户表)
1 CREATE TABLE items (
2 id INT NOT NULL AUTO_INCREMENT,
3 itemsname VARCHAR(32) NOT NULL COMMENT '商品名称',
4 price FLOAT(10,1) NOT NULL COMMENT '商品定价',
5 detail TEXT COMMENT '商品描述',
6 pic VARCHAR(64) DEFAULT NULL COMMENT '商品图片',
7 createtime DATETIME NOT NULL COMMENT '生产日期',
8 PRIMARY KEY (id)
9 ) DEFAULT CHARSET=utf8;
10
11 /*Table structure for table `orderdetail` */
12
13 CREATE TABLE orderdetail (
14 id INT NOT NULL AUTO_INCREMENT,
15 orders_id INT NOT NULL COMMENT '订单id',
16 items_id INT NOT NULL COMMENT '商品id',
17 items_num INT DEFAULT NULL COMMENT '商品购买数量',
18 PRIMARY KEY (id),
19 KEY `FK_orderdetail_1` (`orders_id`),
20 KEY `FK_orderdetail_2` (`items_id`),
21 CONSTRAINT `FK_orderdetail_1` FOREIGN KEY (`orders_id`) REFERENCES `orders` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION,
22 CONSTRAINT `FK_orderdetail_2` FOREIGN KEY (`items_id`) REFERENCES `items` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
23 ) DEFAULT CHARSET=utf8;
24
25 /*Table structure for table `orders` */
26
27 CREATE TABLE orders (
28 id INT NOT NULL AUTO_INCREMENT,
29 user_id INT NOT NULL COMMENT '下单用户id',
30 number VARCHAR(30) NOT NULL COMMENT '订单号',
31 createtime DATETIME NOT NULL COMMENT '创建订单时间',
32 note VARCHAR(100) DEFAULT NULL COMMENT '备注',
33 PRIMARY KEY (`id`),
34 KEY `FK_orders_1` (`user_id`),
35 CONSTRAINT `FK_orders_id` FOREIGN KEY (`user_id`) REFERENCES `t_user` (`id`) ON DELETE NO ACTION ON UPDATE NO ACTION
36 ) DEFAULT CHARSET=utf8;
37
38 /*Table structure for table `t_user` */
39
40 CREATE TABLE user (
41 id INT NOT NULL AUTO_INCREMENT,
42 username VARCHAR(32) NOT NULL COMMENT '用户名称',
43 birthday DATE DEFAULT NULL COMMENT '生日',
44 sex CHAR(1) DEFAULT NULL COMMENT '性别',
45 address VARCHAR(256) DEFAULT NULL COMMENT '地址',
46 PRIMARY KEY (`id`)
47 ) DEFAULT CHARSET=utf8;
1 /*Data for the table `items` */
2
3 INSERT INTO items(itemsname,price,detail,pic,createtime) VALUES
4 ('台式机',3000.0,'该电脑质量非常好!',NULL,'2015-07-07 13:28:53'),
5 ('笔记本',6000.0,'笔记本性能好,质量好!',NULL,'2015-07-08 13:22:57'),
6 ('背包',200.0,'名牌背包,容量大质量好!',NULL,'2015-07-010 13:25:02');
7
8 /*Data for the table `orderdetail` */
9
10 INSERT INTO `orderdetail`(`orders_id`,`items_id`,`items_num`) VALUES
11 (1,1,1),
12 (1,2,3),
13 (2,3,4),
14 (3,2,3);
15
16 /*Data for the table `orders` */
17
18 INSERT INTO `orders`(`user_id`,`number`,`createtime`,`note`) VALUES
19 (1,'1000010','2015-06-04 13:22:35',NULL),
20 (1,'1000011','2015-07-08 13:22:41',NULL),
21 (2,'1000012','2015-07-17 14:13:23',NULL),
22 (3,'1000012','2015-07-16 18:13:23',NULL),
23 (4,'1000012','2015-07-15 19:13:23',NULL),
24 (5,'1000012','2015-07-14 17:13:23',NULL),
25 (6,'1000012','2015-07-13 16:13:23',NULL);
26
27 /*Data for the table `user` */
28
29 INSERT INTO `user`(`username`,`birthday`,`sex`,`address`) VALUES
30 ('王五',NULL,'2',NULL),
31 ('张三','2014-07-10','1','北京市'),
32 ('张小明',NULL,'1','河南郑州'),
33 ('陈小明',NULL,'1','河南郑州'),
34 ('张三丰',NULL,'1','河南郑州'),
35 ('陈小明',NULL,'1','河南郑州'),
36 ('王五',NULL,NULL,NULL),
37 ('小A','2015-06-27','2','北京'),
38 ('小B','2015-06-27','2','北京'),
39 ('小C','2015-06-27','1','北京'),
40 ('小D','2015-06-27','2','北京');
实现用户查询:
根据用户id(主键)查询用户信息(单条记录)
#Global logging configuration,建议开发环境中要用debug
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
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root
通过SqlMapConfig.xml加载mybatis运行环境。
DOCTYPEconfiguration
PUBLIC"-//mybatis.org//DTDConfig 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<propertiesresource="db.properties">
properties>
<environmentsdefault="development">
<environmentid="development">
<transactionManagertype="JDBC"/>
<dataSourcetype="POOLED">
<propertyname="driver"value="${jdbc.driver}"/>
<propertyname="url"value="${jdbc.url}"/>
<propertyname="username"value="${jdbc.username}"/>
<propertyname="password"value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapperresource="sqlmap/User.xml"/>
mappers>
configuration>
建议命名规则:表名+mapper.xml
早期ibatis命名规则:表名.xml
xmlversion="1.0"encoding="UTF-8"?>
DOCTYPEmapper
PUBLIC"-//mybatis.org//DTDMapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mappernamespace="firstDemo">
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id= #{id}
select>
mapper>
package com.itcast.test;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
importorg.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
importorg.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import cn.itcast.mybatis.po.User;
public class FirstTest {
//定义一个会话工厂
private SqlSessionFactory sqlSessionFactory;
@Before
publicvoid init() throws IOException {
//加载配置文件
String resource = "sqlMapConfig.xml";
//加载文件到输入流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂
sqlSessionFactory= new SqlSessionFactoryBuilder().build(inputStream);
}
/*
* 测试根据Id查询用户获取单条记录
*/
@Test
publicvoid testFindUserById(){
//通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//第一个参数:statment的位置,等于namespace+statment的id
//第二个参数:传入的参数
User user = null;
try{
user= sqlSession.selectOne("firstDemo.findUserById", 26);
}catch (Exception e) {
e.printStackTrace();
}finally{
//关闭sqlSession
//这里放在try/catch语句的finally确保查询之后能关闭sqlSession
sqlSession.close();
}
System.out.println(user);
}
}
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
解决:在SqlMapConfig.xml中配置数据链接池,使用连接池管理数据库链接。
2、 Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
3、 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。
解决:Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
4、 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。
解决:Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。