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逆向工程
创建数据库
创建数据库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也是结束选型的参考
需要数据库驱动包
上边是MySQL的驱动,下边是oracle的驱动
参考下边一段程序
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();
}
}
}
}
}
实现用户查询:
根据用户的id查询用户的信息(单条记录)
根据用户名模糊查询用户信息(多条记录)
用户添加、用户修改、用删除
从mybatis官网下载地址是: https://github.com/mybatis/mybatis-3/releases
mybatis-3.2.7.pdf —操作手册
mybatis-3.2.7.jar— 核心jar
lib—依赖jar包
建议开发环境中要使用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
public class User {
private int id;
private String username; // 用户姓名
private String sex; // 性别
private Date birthday; // 生日
private String address; // 地址
// 添加对应的setter和getter方法
......
}
// 会话工厂
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);
}
// 测试根据名称模糊查询用户(可能得到多条记录)
@Test
public void testFindUserByName() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
// 第一个参数:statement的位置,等于namespace+statement的id
// 第二个参数:传入的参数
List list = null;
try {
//list = sqlSession.selectList("test.findUserByName", "小明");
list = sqlSession.selectList("test.findUserByName2", "%小明%");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println(list.size());
}
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
@Test
public void testInsertUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//创建插入数据对象
User user = new User();
user.setUsername("一蓑烟雨");
user.setAddress("河南周口");
user.setBirthday(new Date());
user.setSex("1");
try {
sqlSession.insert("test.insertUser", user);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
select LAST_INSERT_ID()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
使用MySQL的uuid机制生成主键:
select uuid()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
如何实现oracle数据库的主键返回?
实现思路:先查询序列得到主键,将主键设置到user对象中,将user对象插入数据库
select 序列.nextval() from dual
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
delete from user where id=#{id}
update user set username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
// 测试删除用户
@Test
public void testDeleteUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
try {
sqlSession.delete("test.deleteUser", 28);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
// 测试根据id更新用户(得到单条记录)
@Test
public void testUpdateUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//创建更新数据库对象,要求必须包括id
User user= new User();
user.setId(28);
user.setUsername("任平生");
//凡是没有设置的属性都被当成了NULL进行赋值
//user.setBirthday(new Date());
user.setSex("1");
try {
sqlSession.delete("test.updateUser", user);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
企业开发进行选型,考虑mybatis和Hibernate适用场景。
Mybatis:入门简单,程序容易上手开发,节省开发成本。Mybatis需要程序员自己编写SQL语句,是一个不完全的ORM框架,对SQL修改和优化非常容易实现。Mybatis适合开发需求变更频繁的系统,比如:互联网项目。
Hibernate:入门门槛高,如果使用Hibernate写出高性能的程序不容易实现。Hibernate不用写SQL语句,是一个完全的ORM框架。Hibernate适合需求固定,对象数据模型稳定,中小型项目,比如:企业OA系统。
总之,企业在技术选型时根据项目实际情况,以降低成本和提高系统可维护性为出发点进行技术选型。
是mybatis全局配置文件,只有一个,名称不固定,主要mapper.xml,mapper.xml中配置SQL语句。
mapper.xml是以statement为单位进行配置。(把一个SQL称为一个statement),statement中配置SQL语句、parameterType输入参数类型(完成输入映射)、resultType输出结果类型(完成输出映射)。
还提供了parameterMap配置输入参数类型(已过期,不推荐使用)
还提供了resultMap配置输出结果类型(完成输出映射)。
#{}表示一个占位符吗,向占位符输入参数,mybatis自动进行Java类型和jdbc类型的转换。程序员不需要考虑参数的类型,比如传入字符串,mybatis最终拼接好的SQL就是参数两边加上单引号。#{} 接收pojo数据,可以使用OGNL解析出pojo的属性值。
表示SQL的拼接,通过${}接收参数,将参数的内容不加任何修饰拼接在SQL中。${}也可以接收pojo的数据,可以使用OGNL解析出pojo的属性值。
缺点:不能防止SQL注入。
selectOne用于查询单条记录,不能用于查询多条记录,否则会抛出异常。而selectList用户查询多条记录,也可用于查询单条记录。
程序员需要编写DAO接口和DAO的实现类
public interface UserDao {
// 根据id查询用户信息
public User findUserById(int id) throws Exception;
}
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
//将SqlSessionFactory注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserById(int id) throws Exception {
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//根据id查询用户信息
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
}
public class UserDaoImplTest {
// 会话工厂
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);
}
@Test
public void testFindUserById() throws Exception{
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(1);
System.out.println(user);
}
}
要想让mybatis自动创建DAO接口实现类的代理对象,必须遵循一些规则:
1.mapper.xml中namespace指定为mapper接口的全限定名。
......
此步骤目的:通过mapper.xml和mapper.java进行关联
2.mapper.xml中statement的id就是mapper.java中的方法名。
3.mapper.xml中statement的parameterType和mapper.java中方法输入参数类型一致。
4.mapper.xml中statement的resultType和mapper.java中方法返回值一致。
mapper映射文件的命名方式建议: 表名Mapper.xml
namespace指定为mapper接口的全限定名
public interface UserMapper {
//根据用户id查询用户信息
public User findUserById(int id) throws Exception;
}
//根据用户id查询用户信息
public User findUserById(int id) throws Exception;
//根据用户姓名查询用户信息
public List findUserByName(String username) throws Exception;
使用mapper代理的方式开发,mapper接口方法输入参数只有一个,可扩展性是否很差?
扩展性没有任何问题,因为DAO层就是通用的,可以通过扩展pojo(定义pojo包装类型)将不同的参数(可以是pojo也可以是简单类型)传入进去。
可以把一些通用的属性值配置在属性文件中,加载到mybatis运行环境内,比如:创建db.properties配置数据库连接参数。
注意:Mybatis将按照下面的顺序加载属性:
建议使用properties,不要在properties中定义属性,只引用定义的properties文件中的属性,并且properties中定义的key要有一些特殊的规则。
settings全局参数配置
mybatis运行时可以调整一些全局参数,根据使用需求进行参数配置。注意:需要小心配置,配置的参数会影响mybatis的执行。
ibatis的全局配置参数中包括很多的性能参数(最大线程数,最大等待时间...),通过调整这些参数使ibatis达到高性能的运行,mybatis没有这些性能参数,由mybatis自行调节。
mybatis中全局参数配置示例如下:
还有许多全局参数,根据需求进行配置,如下表所示:
Setting(设置) Description(描述) Valid Values(验证值组)Default(默认值)
别名 |
映射的类型 |
_byte |
byte |
_long |
long |
_short |
short |
_int |
int |
_integer |
int |
_double |
double |
_float |
float |
_boolean |
boolean |
string |
String |
byte |
Byte |
long |
Long |
short |
Short |
int |
Integer |
integer |
Integer |
double |
Double |
float |
Float |
boolean |
Boolean |
date |
Date |
decimal |
BigDecimal |
bigdecimal |
BigDecimal |
public class UserQueryVo {
//用户信息
private User user;
//自定义User的扩展对象
private UserCustom userCustom;
//提供对应的getter和setter方法
......
}
//自定义查询条件查询用户信息
public List findUserList(UserQueryVo userQueryVo) throws Exception;
//通过包装类型查询用户信息
@Test
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 构造查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
List list = userMapper.findUserList(userQueryVo);
System.out.println(list);
}
mapper.java
//查询用户返回记录个数
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
测试代码
//返回查询记录总数
@Test
public void testFindUserCount() throws Exception{
SqlSession sqlSession =sqlSessionFactory.openSession();
//创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//构建查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
int count = userMapper.findUserCount(userQueryVo);
System.out.println(count);
}
注意:如果查询记录结果集为一条记录且一列 才适合返回简单类型。
//查询用户,使用resultMap进行映射
public List findUserListResultMap(UserQueryVo userQueryVo) throws Exception;
and username like '%${userCustom.username.trim()}%'
and sex = #{userCustom.sex}
and username like '%${userCustom.username.trim()}%'
and sex = #{userCustom.sex}
在查询用户数据总数量中引用
public class UserQueryVo {
//用户信息
private User user;
//自定义User的扩展对象
private UserCustom userCustom;
//用户id集合
private List ids;
//添加对应的setter和getter方法
......
}
#{id}
//id集合
List ids = new ArrayList();
ids.add(16);
ids.add(22);
userQueryVo.setIds(ids);
List list = userMapper.findUserList(userQueryVo);
package test.lx.mybatis.dao;
import java.util.List;
import test.lx.mybatis.po.User;
/**
* 用户DAO
*
* @author lx
*
*/
public interface UserDao {
// 根据id查询用户信息
public User findUserById(int id) throws Exception;
// 根据用户名称模糊查询用户列表
public List findUserByUsername(String username) throws Exception;
// 插入用户
public void insertUser(User user) throws Exception;
}
UserDaoImpl
package test.lx.mybatis.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import test.lx.mybatis.po.User;
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
//将SqlSessionFactory注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
this.sqlSessionFactory = sqlSessionFactory;
}
public User findUserById(int id) throws Exception {
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//根据id查询用户信息
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
public List findUserByUsername(String username) throws Exception {
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
List list = sqlSession.selectList("test.findUserByName", username);
sqlSession.close();
return list;
}
public void insertUser(User user) throws Exception {
//创建SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
MyBatisFirst
package test.lx.mybatis.first;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
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 test.lx.mybatis.po.User;
/**
* mybatis入门程序
*
* @author lx
*
*/
public class MybatisFirst {
// 会话工厂
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);
}
// 测试根据名称模糊查询用户(可能得到多条记录)
@Test
public void testFindUserByName() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通过sqlSession操作数据库
// 第一个参数:statement的位置,等于namespace+statement的id
// 第二个参数:传入的参数
List list = null;
try {
//list = sqlSession.selectList("test.findUserByName", "小明");
list = sqlSession.selectList("test.findUserByName2", "%小明%");
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println(list.size());
}
// 测试插入用户
@Test
public void testInsertUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//创建插入数据对象
User user = new User();
user.setUsername("一蓑烟雨");
user.setAddress("河南周口");
user.setBirthday(new Date());
user.setSex("1");
try {
sqlSession.insert("test.insertUser", user);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
System.out.println(user.getId());
}
// 测试删除用户
@Test
public void testDeleteUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
try {
sqlSession.delete("test.deleteUser", 28);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
// 测试根据id更新用户(得到单条记录)
@Test
public void testUpdateUser() {
// 通过sqlSessionFactory创建sqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlSession操作数据库
//创建更新数据库对象,要求必须包括id
User user= new User();
user.setId(28);
user.setUsername("任平生");
//凡是没有设置的属性都被当成了NULL进行赋值
//user.setBirthday(new Date());
user.setSex("1");
try {
sqlSession.delete("test.updateUser", user);
//需要提交事务
sqlSession.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
// 关闭sqlSession
sqlSession.close();
}
}
}
JdbcTest
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();
}
}
}
}
}
UserMapper.java
package test.lx.mybatis.mapper;
import java.util.List;
import test.lx.mybatis.po.User;
import test.lx.mybatis.po.UserQueryVo;
/**
* 用户mapper
*
* @author lx
*
*/
public interface UserMapper {
// 根据用户id查询用户信息
public User findUserById(int id) throws Exception;
// 根据用户姓名查询用户信息
public List findUserByName(String username) throws Exception;
// 自定义查询条件查询用户信息
public List findUserList(UserQueryVo userQueryVo) throws Exception;
// 查询用户,使用resultMap进行映射
public List findUserListResultMap(UserQueryVo userQueryVo) throws Exception;
// 查询用户返回记录个数
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
// 插入用户
public void insertUser(User user) throws Exception;
// 删除用户
public void deleteUser(int id) throws Exception;
// 修改用户
public void updateUser(User user) throws Exception;
}
UserMapper.xml
and username like '%${userCustom.username.trim()}%'
and sex = #{userCustom.sex}
#{id}
select LAST_INSERT_ID()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
delete from user where id=#{id}
update user set username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
User.java
package test.lx.mybatis.po;
import java.util.Date;
/**
* 用户PO类
*
* @author lx
*
*/
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 + "]";
}
}
UserCustom
package test.lx.mybatis.po;
/**
* User的扩展类型
* @author liuxun
*
*/
public class UserCustom extends User {
//添加一些扩展类型
}
UserQueryVo
package test.lx.mybatis.po;
import java.util.List;
/**
* 包装类型,将来在使用时从页面传递到controller、service、mapper
* @author liuxun
*
*/
public class UserQueryVo {
//用户信息
private User user;
//自定义User的扩展对象
private UserCustom userCustom;
//用户id集合
private List ids;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public UserCustom getUserCustom() {
return userCustom;
}
public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
}
public List getIds() {
return ids;
}
public void setIds(List ids) {
this.ids = ids;
}
}
User.xml
select LAST_INSERT_ID()
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
delete from user where id=#{id}
update user set username = #{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root
log4j.properties
# 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
UserDaoImplTest
package test.lx.mybatis.dao;
import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import test.lx.mybatis.po.User;
public class UserDaoImplTest {
// 会话工厂
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);
}
@Test
public void testFindUserById() throws Exception{
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
User user = userDao.findUserById(1);
System.out.println(user);
}
}
UserMapperTest.java
package test.lx.mybatis.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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 test.lx.mybatis.po.User;
import test.lx.mybatis.po.UserCustom;
import test.lx.mybatis.po.UserQueryVo;
public class UserMapperTest {
// 会话工厂
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);
}
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
sqlSession.close();
}
@Test
public void testFindUserByUsername() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List list = userMapper.findUserByName("小明");
sqlSession.close();
System.out.println(list);
}
@Test
public void testInsertUser() throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//插入对象
User user = new User();
user.setUsername("一蓑烟雨任平生");
userMapper.insertUser(user);
sqlSession.commit();
sqlSession.close();
System.out.println(user);
}
//通过包装类型查询用户信息
@Test
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 构造查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername(" 小明");
userCustom.setSex("1");
userQueryVo.setUserCustom(userCustom);
//id集合
List ids = new ArrayList();
ids.add(16);
ids.add(22);
userQueryVo.setIds(ids);
List list = userMapper.findUserList(userQueryVo);
sqlSession.close();
System.out.println(list);
}
//使用resultMap进行结果映射
@Test
public void testFindUserListResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 构造查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
List list = userMapper.findUserListResultMap(userQueryVo);
sqlSession.close();
System.out.println(list);
}
//返回查询记录总数
@Test
public void testFindUserCount() throws Exception{
SqlSession sqlSession =sqlSessionFactory.openSession();
//创建代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//构建查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
int count = userMapper.findUserCount(userQueryVo);
sqlSession.close();
System.out.println(count);
}
}