开发环境
- jdk1.7.0_72
- eclipse:eclipse-3.7-indigo
- mysql:mysql5.1
创建数据库
先导入sql_table.sql,再导入sql_data.sql(记录系统的初始化数据)
通常需要提供初始化数据的数据库脚本。
/* SQLyog v10.2 MySQL - 5.1.72-community : Database - mybatis ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=‘‘*/; /*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @[email protected]@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */; /*!40111 SET @[email protected]@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 [email protected]_SQL_MODE */; /*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */; /*!40014 SET [email protected]_UNIQUE_CHECKS */; /*!40111 SET [email protected]_SQL_NOTES */;
/* SQLyog v10.2 MySQL - 5.1.72-community : Database - mybatis ********************************************************************* */ /*!40101 SET NAMES utf8 */; /*!40101 SET SQL_MODE=‘‘*/; /*!40014 SET @[email protected]@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; /*!40014 SET @[email protected]@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; /*!40101 SET @[email protected]@SQL_MODE, SQL_MODE=‘NO_AUTO_VALUE_ON_ZERO‘ */; /*!40111 SET @[email protected]@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 [email protected]_SQL_MODE */; /*!40014 SET [email protected]_FOREIGN_KEY_CHECKS */; /*!40014 SET [email protected]_UNIQUE_CHECKS */; /*!40111 SET [email protected]_SQL_NOTES */;
jdbc编程中问题
企业开发中,根据项目大小、特点进行技术选型 ,jdbc操作数据库时效率是很高的,jdbc也是技术选型的参考。
jdbc程序
需要数据库的驱动包:
上边是mysql的驱动,下边是oracle的驱动。
1 package cn.itcast.mybatis.jdbc; 2 3 import java.sql.Connection; 4 import java.sql.DriverManager; 5 import java.sql.PreparedStatement; 6 import java.sql.ResultSet; 7 8 public class JDBCTest2 { 9 public static void main(String[] args) { 10 Connection connection = null; 11 PreparedStatement preparedStatement = null; 12 ResultSet resultSet = null; 13 14 try { 15 //1.加载数据库驱动 16 Class.forName("com.mysql.jdbc.Driver"); 17 //2.通过驱动管理类获取数据库连接 18 connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8", "root", "123456"); 19 //3.定义sql语句 20 String sql = "select * from user where username = ?"; 21 //4.获取预处理statement 22 preparedStatement = connection.prepareStatement(sql); 23 //5.设置参数 24 preparedStatement.setString(1, "王五"); 25 //6.向数据库发出sql执行查询,查询出结果集 26 resultSet = preparedStatement.executeQuery(); 27 //7.遍历查询结果集 28 while (resultSet.next()) { 29 System.out.println(resultSet.getString("id")+" "+resultSet.getString("username")); 30 } 31 } catch (Exception e) { 32 e.printStackTrace(); 33 } finally { 34 //8.释放资源 35 if (resultSet != null) { 36 try { 37 resultSet.close(); 38 } catch (Exception e2) { 39 e2.printStackTrace(); 40 } 41 } 42 if (preparedStatement != null) { 43 try { 44 preparedStatement.close(); 45 } catch (Exception e2) { 46 e2.printStackTrace(); 47 } 48 } 49 if (connection != null) { 50 try { 51 connection.close(); 52 } catch (Exception e2) { 53 e2.printStackTrace(); 54 } 55 } 56 } 57 } 58 59 }
jdbc问题总结
1、数据库连接频繁的创建和关闭,缺点浪费数据库的资源,影响操作效率
设想:使用数据库连接池
2、sql语句是硬编码,如果需求变更需要修改sql,就需要修改java代码,需要重新编译,系统不易维护。
设想:将sql语句统一配置在文件中,修改sql不需要修改java代码。
3、通过preparedStatement向占位符设置参数,存在硬编码( 参数位置,参数)问题。系统不易维护。
设想:将sql中的占位符及对应的参数类型配置在配置文件中,能够自动输入 映射。
4、遍历查询结果集存在硬编码(列名)。
设想:自动进行sql查询结果向java对象的映射(输出映射)。
mybatis架构(重点)
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、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
mybatis架构
mybatis入门程序
需求
实现用户查询:
根据用户id(主键)查询用户信息(单条记录)
根据用户名称模糊查询用户信息(多条记录)
用户添加
用户删除
用户修改
导入jar包
从mybatis管网下载(地址:https://github.com/mybatis/mybatis-3/releases)
mybatis-3.2.7.pdf---操作手册
mybatis-3.2.7.jar--核心 jar包
依赖的jar包
工程结构
log4j.properties(公用文件)
# 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
SqlMapConfig.xml(公用文件)
通过SqlMapConfig.xml加载mybatis运行环境。
<?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> <properties resource="db.properties"></properties> <!-- 和spring整合后 environments配置将废除--> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理--> <transactionManager type="JDBC" /> <!-- 数据库连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="sqlmap/User.xml"/> </mappers> </configuration>
db.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/mybatistest jdbc.username=root jdbc.password=123456
根据id查询用户
pojo(User.java)
public class User { private int id; private String username;// 用户姓名 private String sex;// 性别 private Date birthday;// 生日 private String address;// 地址 public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }
User.xml(重点)
建议命名规则:表名+mapper.xml
早期ibatis命名规则:表名.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"> <mapper namespace="test"> <select id="findUserById" parameterType="int" resultType="com.cxz.mybatis.pojo.User"> SELECT * FROM USER WHERE id= #{id} </select> </mapper>
测试程序
配置文件---输入流---SqlSessionFactory---SqlSession---操作数据库---关闭SqlSession
package mybatis02; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import com.cxz.mybatis.pojo.User; public class MyBatisTest { //会话工厂 private SqlSessionFactory sqlSessionFactory; //创建工厂 @Before public void init() throws IOException { //配置文件 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操作数据库 User user = null; try { user = sqlSession.selectOne("test.findUserById", 10); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } System.out.println(user); } }
用户添加
User.xml
<insert id="insertUser" parameterType="com.cxz.mybatis.pojo.User"> INSERT INTO USER (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>
测试程序
/** * 用户添加 */ @Test public void insertUser() { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setUsername("chen"); user.setAddress("Liaoning"); user.setBirthday(new Date()); user.setSex("1"); try { sqlSession.insert("test.insertUser", user); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } System.out.println(user); }
主键返回
<insert id="insertUser" parameterType="com.cxz.mybatis.pojo.User"> <selectKey keyProperty="id" order="AFTER" resultType="int"> select LAST_INSERT_ID() </selectKey> INSERT INTO USER (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>
测试程序
/** * 用户添加 */ @Test public void insertUser() { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setUsername("xiang"); user.setAddress("Liaoning"); user.setBirthday(new Date()); user.setSex("1"); try { sqlSession.insert("test.insertUser", user); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } System.out.println(user.getId()); }
删除用户
<delete id="deleteUser" parameterType="int"> delete from user where id=#{id} </delete>
测试程序
/** * 用户删除 */ @Test public void tsetDeletetUser() { SqlSession sqlSession = sqlSessionFactory.openSession(); try { sqlSession.insert("test.deleteUser", 32); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } }
用户更新
<update id="updateUser" parameterType="com.cxz.mybatis.pojo.User"> UPDATE USER SET username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} WHERE id=#{id} </update>
测试程序
/** * 用户更新 */ @Test public void tsetUpdatetUser() { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = new User(); user.setId(33); user.setUsername("zhen"); user.setAddress("Beijing"); user.setBirthday(new Date()); user.setSex("2"); try { sqlSession.insert("test.updateUser", user); sqlSession.commit(); } catch (Exception e) { e.printStackTrace(); } finally { sqlSession.close(); } }