创建数据库表
/*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 `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;
/*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 `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;
向表中插入数据
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');
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);
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);
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);
创建项目并导包
asm-3.3.1.jar
cglib-2.2.2.jar
commons-logging-1.1.1.jar
javassist-3.17.1-GA.jar
log4j-1.2.17.jar
log4j-api-2.0-rc1.jar
log4j-core-2.0-rc1.jar
mybatis-3.2.7.jar
mysql-connector-java-5.1.7-bin.jar
slf4j-api-1.7.5.jar
slf4j-log4j12-1.7.5.jar
并在src目录下创建log4j.properties文件
# Global logging configuration
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
#日志级别在开发阶段设置成DEBUG
#在生产阶段设置成INFO或者ERROR
开发步骤
创建PO(model)类,根据需求创建;
创建全局配置文件SqlMapConfig.xml
编写映射文件
加载映射文件,在SqlMapConfig.xml中进行加载
编写测试程序,即编写java代码,连接并操作数据库
思路:
创建SqlMapConfig.xml
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/spring_day3?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
configuration>
映射文件
<mapper namespace="test">
<select id="findUserById" parameterType="int" resultType="com.gyf.domain.User">
SELECT * FROM USER WHERE id = #{id}
select>
mapper>
测试类
package test;
import model.User;
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.Test;
import java.io.IOException;
import java.io.InputStream;
public class one {
@Test
public void test() throws IOException {
//获取全局配置文件路径并读取
String resource = "SqlMapConfig.xml";
InputStream is = Resources.getResourceAsStream(resource);
//通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
SqlSessionFactory sessionFactory =
new SqlSessionFactoryBuilder().build(is);
//通过SqlSessionFactory创建SqlSession
SqlSession session = sessionFactory.openSession();
//调用SqlSession的操作数据库方法
User user = session.selectOne("findUserById", 10);
System.out.println(user.toString());
//关闭SqlSession
session.commit();
}
}
注意:增删改后要提交事务
映射文件配置
<mapper namespace="test">
<select id="findUserByName" parameterType="String" resultType="model.User">
SELECT * FROM USER WHERE username like '%${value}%';
select>
mapper>
测试类
//简写
List<User> user = session.selectList("findUserByName", "张");
for (User res : user) {
System.out.println(res.toString());
}
映射文件配置
<insert id="insertUser" parameterType="model.User">
INSERT INTO USER (username,sex,birthday,address)
VALUES(#{username},#{sex},#{birthday},#{address})
insert>
测试类
session.insert("insertUser",
new User("cyh", "男", new Date(), "安徽省合肥市"));
映射文件配置
<delete id="deleteById" parameterType="int">
DELETE FROM USER WHERE id = #{id};
delete>
测试类
session.delete("deleteById",27);
映射文件配置
<update id="updateUser" parameterType="model.User">
UPDATE USER SET username=#{username},sex=#{sex}
WHERE id=#{id};
update>
测试类
User user = new User();
user.setId(1);
user.setUsername("蔡宇浩");
user.setSex("男");
session.update("updateUser",user);
思路:
Mysql自增主键,是指在insert之前Mysql会自动生成一个自增的主键。
我们可以通过Mysql的函数获取到刚插入的自增主键:LAST_INSERT_ID()。
这个函数是在insert语句之后去调用。
映射文件配置
<insert id="autoInsertUser" parameterType="model.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID()
selectKey>
INSERT INTO user (username,sex,birthday,address)
VALUES(#{username},#{sex},#{birthday},#{address});
insert>
parameterType和resultType
parameterType指定输入参数的java类型,可以填写别名或Java类的全限定名。
resultType指定输出结果的java类型,可以填写别名或Java类的全限定名。
#{} 和 ${}
#{}:相当于预处理中的占位符?。
#{}里面的参数表示接收java输入参数的名称。
#{}可以接受 HashMap、POJO类型的参数。
当接受简单类型的参数时,#{}里面可以是 value,也可以是其他。
#{}可以防止 SQL 注入。
${}:相当于拼接SQL串,对传入的值不做任何解释的原样输出。
${}会引起SQL注入所以要谨慎使用。
${}可以接受HashMap、POJO类型的参数。
当接受简单类型的参数时,${}里面只能是 value。
selectOne和selectList
selectOne:只能查询0或1条记录,大于1条记录的话,会报错:
selectList:可以查询0或N条记录。
注意不推荐使用这种方法,MyBatis可以有多种其他实现方式。
dao层
//UserDao(接口)
package dao;
import model.User;
public interface UserDao {
public void save(User user);
public User findUserById(int id);
}
//UserDaoImpl(实现类)
package dao;
import model.User;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
public class UserDaoImpl implements UserDao {
//注入SessionFactory
private SqlSessionFactory ssf;
/**
* 注入SqlSessionFactory
*/
public void setSsf(SqlSessionFactory ssf) {
this.ssf = ssf;
}
public UserDaoImpl(SqlSessionFactory ssf) {
super();
this.ssf = ssf;
}
@Override
public void save(User user) {
SqlSession session = ssf.openSession();
session.insert("insertUser",user);
session.commit();
session.close();
}
@Override
public User findUserById(int id) {
SqlSession session = ssf.openSession();
User user = session.selectOne("findUserById", id);
session.close();
return user;
}
}
测试
package test;
import dao.UserDao;
import dao.UserDaoImpl;
import model.User;
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 java.io.InputStream;
public class two {
SqlSessionFactory ssf;
@Before //在test测试方法前执行setup方法
public void setup() throws Exception{
//1.读取配置文件
InputStream is =
Resources.getResourceAsStream("SqlMapConfig.xml");
//2.通过SqlSessionFactoryBuilder创建
// SqlSessionFactory会话工厂
ssf = new SqlSessionFactoryBuilder().build(is);
}
@Test
public void test(){
UserDao userDao = new UserDaoImpl(ssf);
//保存用户
User user = new User();
user.setId(32);
user.setUsername("辣鸡");
userDao.save(user);
System.out.println(user.toString());
//查找用户
User u = userDao.findUserById(10);
System.out.println(u.toString());
}
}
第一步:编写mapper接口
重新写个 UserMapper 配置文件和定义 mapper 映射文件
UserMapper.xml(内容同 Users.xml, 除了 namespace 的值),
放到新创建的目录 mapper 下。
package mapper;
import model.User;
public interface UserMapper {
public void save(User user);
public User findUserById(int id);
}
<mapper namespace="mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="model.User">
SELECT * FROM USER WHERE id=#{?};
select>
<insert id="save" parameterType="model.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID();
selectKey>
INSERT INTO USER (id,username,sex,birthday,address)
VALUES(#{id},#{username},#{sex},#{birthday},#{address})
insert>
mapper>
第二步:添加映射配置文件
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/spring_day3?useUnicode=true&characterEncoding=utf8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
configuration>
第三步:测试
package test;
import mapper.UserMapper;
import model.User;
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 java.io.InputStream;
import java.util.Date;
public class three {
SqlSessionFactory ssf;
//加载配置文件
@Before
public void setup()throws Exception{
InputStream is =
Resources.getResourceAsStream("SqlMapConfig.xml");
ssf = new SqlSessionFactoryBuilder().build(is);
}
@Test
public void test(){
SqlSession session = ssf.openSession();
//通过session获取代理【JDK实现的代理】
UserMapper mapper = session.getMapper(UserMapper.class);
//保存用户
User user = new User();
user.setUsername("赵佳");
user.setSex("女");
user.setBirthday(new Date());
user.setAddress("上海市");
mapper.save(user);
System.out.println(user.toString());
session.commit();
//查找用户
User u = mapper.findUserById(48);
System.out.println(u.toString());
session.close();
}
}
在src下配置个db.properties文件
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/spring_day3?useUnicode=true&characterEncoding=utf8
username=root
password=123456
修改全局的配置文件
<configuration>
<properties resource="db.properties"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
configuration>
别名的使用时为了在映射文件中,更方便的去指定参数和结果集的类型,不再用写很长的一 段全限定名。
别名 | 映射的类型 | 别名 | 映射的类型 | 别名 | 映射的类型 |
---|---|---|---|---|---|
_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 |
SqlMapConfig.xml中的配置
<configuration>
<properties resource="db.properties"/>
<typeAliases>
<typeAlias type="model.User" alias="user"/>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${driverClass}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/UserMapper.xml"/>
mappers>
configuration>
实际的实现类文件中,resultType和parameterType若用到上述别名,可直接引用,不再需要写全名。
使用相对于类路径的资源
如:
【不用】
使用完全限定路径
使用 mapper 接口的全限定名
如:
也可使用注解开发,把 xml 文件删除
注意 :此种方法要求 mapper 接口和 mapper 映射文件要名称相同,
且放到同一个目录下;
(推荐)
注册指定包下的所有映射文件(只到包名)
如:
注意 :此种方法要求 mapper 接口和 mapper 映射文件要名称相同,
且放到同一个目录下;
指定输入参数的Java类型,可以使用别名或者类的全限定名,它可以接收简单类型,POJO对象,HashMap。