mybatis简介
mybatis是一个Java持久层框架,Java中操作关系型数据库使用的是jdbc,mybatis是对jdbc的封装。
mybatis的入门需要掌握以下几点:
1、使用jdbc程序使用原生态的jdbc进行开发存在很多弊端,优点是执行效率高,mybatis弥补了jdbc的缺陷。
2、mybatis的架构(重点)。
3、mybatis的入门程序(重点)。
实现数据的查询、添加、修改、删除
4、mybatis开发DAO的两种方法(重点)
原始的DAO开发方式(DAO接口和DAO实现都需要编写)
mapper代理方式(只需要编写DAO接口)
5、输入映射类型和输出映射类型
6、动态SQL
mybatis的高级知识主要包括以下几点:
高级映射查询(一对一、一对多、多对多)(重点)
查询缓存
延迟加载
mybatis和spring整合(重点)
mybatis逆向工程
开发环境(eclipse、MySQL)
创建数据库
创建数据库mybatis
新建表结构:
sql_table.sql
- *
- 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 */;
sql_data.sql
- /*
- 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 */;
jdbc编程中的问题
企业开发中,根据项目大小、特点进行技术选型,jdbc操作数据库时效率时很高的,jdbc也是结束选型的参考
jdbc程序
需要数据库驱动包
参考下边一段程序
- package test.lx.mybatis.jdbc;
- import java.sql.Connection;
- import java.sql.DriverManager;
- import java.sql.PreparedStatement;
- import java.sql.ResultSet;
- import java.sql.SQLException;
- /**
- * jdbc的测试程序
- *
- * @author lx
- *
- */
- public class JdbcTest {
- public static void main(String[] args) {
- Connection connection = null;
- //PreparedStatement是预编译的Statement,通过Statement发起数据库的操作
- //PreparedStatement防止sql注入,执行数据库效率高
- 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", "root");
- //定义sql语句 ?表示占位符
- String sql = "select * from user where username = ?" ;
- //获取预处理statement
- preparedStatement = connection.prepareStatement(sql);
- //设置参数,第一个参数为sql语句中参数的序号(从1开始),第二个参数为设置的参数值
- preparedStatement.setString(1, "王五");
- //向数据库发出sql执行查询,查询出结果集
- resultSet = preparedStatement.executeQuery();
- //遍历查询结果集
- while(resultSet.next()){
- System.out.println(resultSet.getString("id")+" "+resultSet.getString("username"));
- }
- } catch (Exception e) {
- e.printStackTrace();
- }finally{
- //释放资源
- if(resultSet!=null){
- try {
- resultSet.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if(preparedStatement!=null){
- try {
- preparedStatement.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- if(connection!=null){
- try {
- connection.close();
- } catch (SQLException e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }
- }
- }
- }
jdbc问题总结
mybatis架构(重点)
- mybatis本是Apache的一个开源项目ibatis,2010年这个项目由Apache software foundation迁移到了Google code,并且改名为mybatis,实质上mybatis对ibatis进行了一些改进。目前mybatis在GitHub上托管。git(分布式版本控制,当前比较流行)
- mybatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
- mybatis通过xml或注解的方式将要执行的各种statement( statement、PreparedStatement、CallableStatement)配置起来,并通过Java对象和Statement中的SQL进行映射生成最终执行的SQL语句,最后由mybatis框架执行SQL并将结果映射成Java对象并返回。
mybatis入门程序
需求
实现用户查询:
根据用户的id查询用户的信息(单条记录)
根据用户名模糊查询用户信息(多条记录)
用户添加、用户修改、用删除
导入jar包
从mybatis官网下载地址是: https://github.com/mybatis/mybatis-3/releases
mybatis-3.2.7.pdf —操作手册
mybatis-3.2.7.jar— 核心jar
lib—依赖jar包
工程结构
log4j.properties(公用文件)
建议开发环境中要使用debug
- # Global logging configuration\uff0c\u5efa\u8bae\u5f00\u53d1\u73af\u5883\u4e2d\u8981\u7528debug
- 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
SqlMapConfig.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>
- <!-- 和Spring整合后environments配置将废除 -->
- <environments default="development">
- <environment id="development">
- <!-- 使用jdbc事务管理 -->
- <transactionManager type="JDBC" />
- <dataSource type="POOLED">
- <property name="driver" value="com.mysql.jdbc.Driver" />
- <property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
- <property name="username" value="root" />
- <property name="password" value="root" />
- </dataSource>
- </environment>
- </environments>
- <!-- 加載mapper文件 -->
- <mappers>
- <mapper resource="sqlmap/User.xml" />
- </mappers>
- </configuration>
根据id查询用户
pojo (User.java)
- public class User {
- private int id;
- private String username; // 用户姓名
- private String sex; // 性别
- private Date birthday; // 生日
- private String address; // 地址
- // 添加对应的setter和getter方法
- ......
- }
User.xml (重点)
- <?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">
- <!-- namespace命名空间,为了对SQL语句进行隔离,方便管理,mapper可开发dao方式,使用namespace有特殊作用
- mapper代理开发时将namespace指定为mapper接口的全限定名 -->
- <mapper namespace="test">
- <!-- 在mapper.xml文件中配置很多的SQL语句,执行每个SQL语句时,封装为MappedStatement对象
- mapper.xml以statement为单位管理SQL语句
- -->
- <!-- 根据id查询用户信息 -->
- <!--
- id: 唯一标识一个statement
- #{}:表示一个占位符,如果#{} 中传入简单类型的参数,#{}中的名称随意
- parameterType: 输入参数的类型,通过#{}接收parameterType输入的参数
- resultType:输出结果类型,指定单条记录映射的pojo类型
- -->
- <select id="findUserById" parameterType="int" resultType="test.lx.mybatis.po.User">
- SELECT * FROM USER WHERE id=#{id};
- </select>
- </mapper>
编码
- // 会话工厂
- private SqlSessionFactory sqlSessionFactory;
- // 创建工厂
- @Before
- public void init() throws IOException {
- // 配置文件(SqlMapConfig.xml)
- String resource = "SqlMapConfig.xml";
- // 加载配置文件到输入 流
- InputStream inputStream = Resources.getResourceAsStream(resource);
- // 创建会话工厂
- sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- }
- // 测试根据id查询用户(得到单条记录)
- @Test
- public void testFindUserById() {
- // 通过sqlSessionFactory创建sqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 通过sqlSession操作数据库
- // 第一个参数:statement的位置,等于namespace+statement的id
- // 第二个参数:传入的参数
- User user = null;
- try {
- user = sqlSession.selectOne("test.findUserById", 1);
- } catch (Exception e) {
- e.printStackTrace();
- } finally {
- // 关闭sqlSession
- sqlSession.close();
- }
- System.out.println(user);
- }
根据用户名称模糊查询用户信息
User.xml
- <!-- 根据用户名称查询用户信息,可能返回多条
- ${}:表示SQL的拼接,通过${}接收参数,将参数的内容不加任何修饰的拼接在SQL中
- -->
- <select id="findUserByName" parameterType="java.lang.String" resultType="test.lx.mybatis.po.User">
- select * from user where username like '%${value}%'
- </select>
- <select id="findUserByName2" parameterType="java.lang.String" resultType="test.lx.mybatis.po.User">
- select * from user where username like #{username}
- </select>
编码
- // 测试根据名称模糊查询用户(可能得到多条记录)
- @Test
- public void testFindUserByName() {
- // 通过sqlSessionFactory创建sqlSession
- SqlSession sqlSession = sqlSessionFactory.openSession();
- // 通过sqlSession操作数据库