一、基础知识:

1.对原生态jdbc程序(单独使用jdbc开发)问题总结

 2.mybatis框架原理 (掌握)

 3.mybatis入门程序

 4.用户的增、删、改、查

 5.SqlMapConfig.xml

 6.输入映射

 7.输出映射

 8.动态sql

1.对原生态jdbc程序中问题总结

1.1 环境

java环境:jdk1.8.0_20

eclipse:luna

mysql:5.1

1.2   创建mysql数据

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脚本

1.3 jdbc程序

使用jdbc查询mysql数据库中用户表的记录。

创建java工程,加入jar包:

数据库驱动包(mysql5.1)

上边的是mysql驱动。

下边的是oracle的驱动。

 程序代码:

package com.dzq.mybatis.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException; /**
* 通过Jdbc程序,总结单独的jdbc程序,总结其中
*
* @author 小强
*
*/
public class JdbcTest {
public static void main(String[] args) {
// 数据库连接
Connection connection = null;
// 预编译的Statement,可以提高数据库的性能
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", "mysql");
// 定义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();
}
} } } }

JdbcTest

1.4  问题总结

1、数据库连接,使用时就创建,不使用立即释放,对数据库进行频繁连接开启和关闭,造成数据库资源浪费,影响 数据库性能。

设想:使用数据库连接池管理数据库连接。

2、将sql语句硬编码到java代码中,如果sql 语句修改,需要重新编译java代码,不利于系统维护。

设想:将sql语句配置在xml配置文件中,即使sql变化,不需要对java代码进行重新编译。

3、向preparedStatement中设置参数,对占位符号位置和设置参数值,硬编码在java代码中,不利于系统维护。

设想:将sql语句及占位符号和参数全部配置在xml中。

4、从resultSet中遍历结果集数据时,存在硬编码,将获取表的字段进行硬编码,,不利于系统维护。

设想:将查询的结果集,自动映射成java对象。

2.mybatis框架

2.1     mybatis是什么?

mybatis是一个持久层的框架,是apache下的顶级项目。

mybatis托管到goolecode下,再后来托管到github下(https://github.com/mybatis/mybatis-3/releases)。

mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。

mybatis可以将向 preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象。(输出映射)

2.2    mybatis框架

3入门程序

3.1 需求

根据用户id(主键)查询用户信息

根据用户名称模糊查询用户信息

添加用户

删除 用户

更新用户

3.2 环境

java环境:jdk1.8.0_20

eclipse:luna

mysql:5.1

jar包:mybatis-3.2.7.jar

lib下:依赖包

mybatis-3.2.7.jar:核心 包

mybatis-3.2.7.pdf,操作指南

加入mysql的驱动包

3.3 log4j.properties

# Global logging configuration
#\u5728\u5f00\u53d1\u73af\u5883\u4e0b\u65e5\u5fd7\u7ea7\u522b\u8981\u8bbe\u7f6e\u6210DEBUG\uff0c\u751f\u4ea7\u73af\u5883\u8bbe\u7f6e\u6210info\u6216error
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

3.4工程结构

3.5 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> <!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理-->
<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> </configuration>

SqlMapConfig.xml

3.6根据用户id(主键)查询用户信息

3.6.1 创建po类

package com.dzq.mybatis.domain;

import java.util.Date;

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;
} }

User.java

3.6.2    映射文件

映射文件命名:

User.xml(原始ibatis命名),mapper代理开发映射文件名称叫XXXMapper.xml,比如:UserMapper.xml、ItemsMapper.xml

在映射文件中配置sql语句。

<?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">
<!--命名空间,对sql进行分类管理,实现sql隔离 注意:使用mapper代理的方法开发,namespace就有特殊重要的作用 -->
<mapper namespace="test">
<!-- 在映射文件中配置很多sql语句 -->
<!-- 通过id查询用户表的记录 -->
<!--通过select执行数据库的查询
id:标识映射文件中的sql,称为statemen的id 将sql语句封装到mappedstatement对象中
#{}:表示占位符
parameterType:指定输入参数类型,这里指定int型
{id}:其中的id表示接收输入参数,如果输入参数是简单类型,#{}中参数名可以任意,可以是value或者其他名称
resultType:指定sql输出结果所映射的java对象类型,select指定resultType将单条记录所映射成的java对象
-->
<select id="findUserById" parameterType="int" resultType="com.dzq.mybatis.domain.User">
select * from user where id=#{id}
</select>
</mapper>

User.xml

3.6.3     在SqlMapConfig.xml加载映射文件

在sqlMapConfig.xml中加载User.xml:

<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>

3.6.4     程序编写

package com.dzq.mybatis.first;

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 com.dzq.mybatis.domain.User; public class MybatisFirst {
// 根据id查询用户的信息,得到一条记录结果
public void findUserById(int id) throws IOException {
//mybatis配置文件
String resource="SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件的信息
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//通过工厂得到sqlsession
SqlSession sqlSession=sqlSessionFactory.openSession();
//通过sqlsession操作数据库
//第一个参数:statement,映射文件中statement的id; 等于namespace+"."statement的id
//第二个参数: parameter 指定和映射文件中parameter所匹配的parameterType的类型的 参数
//sqlSession.selectOne结果是与映射文件中所匹配的resultType类型对象
User user=sqlSession.selectOne("test.findUserById", 1);
System.out.println(user);
//释放资源
sqlSession.close();
}
}

MybatisFirst.java

3.7  根据用户名称模糊查询用户信息

3.7.1     映射文件

使用User.xml,添加根据用户名称模糊查询用户信息的sql语句。

<!-- 根据用户名称模糊查询用户信息  -->
<!-- resultType:单条记录所映射的java对象类型
${}:拼接sql串,将接收到的参数不加任何修饰拼接到sql语句中
使用${}拼接sql,会引起sql注入
${value}表示输入参数的内容,如果传入的类型是简单类型${}只能使用value
-->
<select id="findUserByUserName" parameterType="java.lang.String" resultType="com.dzq.mybatis.domain.User">
select * from user where username like '%${value}%'
</select>

3.7.2   程序代码

//根据用户名称模糊查询用户信息
public void findUserByUserName() throws IOException{
//mybatis配置文件
String resource="SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream=Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件的信息
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
//通过工厂得到sqlsession
SqlSession sqlSession=sqlSessionFactory.openSession();
//通过sqlsession操作数据库
//第一个参数:statement,映射文件中statement的id; 等于namespace+"."statement的id
//第二个参数: parameter 指定和映射文件中parameter所匹配的parameterType的类型的 参数
//sqlSession.selectList结果是与映射文件中所匹配的resultType类型对象
List<User> list=sqlSession.selectList("test.findUserByUserName", "小明");
System.out.println(list);
//释放资源
sqlSession.close();
}

3.8添加用户

3.8.1映射文件

在 User.xml中配置添加用户的Statement

<!-- 添加用户 -->
<!--
parameterType:输入参数类型是pojo(包括用户信息)
#{}:指定pojo的属性名,接收到pojo的属性值,mybatis通过ognl获取属性值
-->
<insert id="addUser" parameterType="com.dzq.mybatis.domain.User">
insert into user(id,username,birthday,sex,address) value(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

3.8.2程序代码

//添加用户信息
@Test
public void addUser() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件的信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 通过工厂得到sqlsession
SqlSession sqlSession = sqlSessionFactory.openSession();
//插入用户对象
User user=new User();
user.setUsername("贱贱");
user.setSex("男");
user.setAddress("山东临沂");
user.setBirthday(new Date());
sqlSession.insert("test.addUser", user);
//提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}

3.8.3    自增主键返回

mysql自增主键,执行insert提交之前自动生成一个自增主键。

通过mysql函数获取到刚插入记录的自增主键:

LAST_INSERT_ID()

是insert之后调用此函数。

修改insertUser定义:

<insert id="addUser" parameterType="com.dzq.mybatis.domain.User">
<!-- insert 插入数据返回到User对象中
select last_insert_id:得到刚插入进去数据的主键值,只适用于自增主键
keyProperty:将要查询到的主键值设置到parameterType对象的那个属性
order:相对于insert语句的执行顺序
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select last_insert_id()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
</insert>

3.8.14    非自增主键返回(使用uuid())

使用mysql的uuid()函数生成主键,需要修改表中id字段类型为string,长度设置成35位。

执行思路:

先通过uuid()查询到主键,将主键输入 到sql语句中。

执行uuid()语句顺序相对于insert语句之前执行。

通过oracle的序列生成主键:

<insert  id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<selectKey resultType="java.lang.Integer" order="BEFORE"
keyProperty="id">
SELECT 自定义序列.NEXTVAL FROM DUAL
</selectKey>
insert into user(id,username,birthday,sex,address)
values(#{id},#{username},#{birthday},#{sex},#{address})
</insert>

注意这里使用的order是“BEFORE”

3.9删除用户

3.9.1映射文件

<!-- 删除用户
根据id删除用户,需要输入id值
-->
<delete id="deleteUser" parameterType="int" >
delete from user where id=#{id}
</delete>

3.9.2程序代码

//删除用户信息
@Test
public void deleteUser() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件的信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 通过工厂得到sqlsession
SqlSession sqlSession = sqlSessionFactory.openSession();
//传入id,根据id删除用户
sqlSession.delete("test.deleteUser", 33);
//提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}

3.10更新用户

3.10.1映射文件

<!-- 更新用户
分析:需要传入用户的id
用户的更新信息
parameterType,指定user对象,包括id和更新信息,注意,id必须存在
#{id}接收user里的属性值
-->
<update id="updateUser" parameterType="com.dzq.mybatis.domain.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>

3.10.2程序代码

// 更新用户信息
@Test
public void updateUser() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件的信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 通过工厂得到sqlsession
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = new User();
user.setId(32);
user.setUsername("贱贱贱");
user.setSex("女");
user.setAddress("山东莱芜");
user.setBirthday(new Date());
// 传入user对象,根据id更新用户
sqlSession.update("test.updateUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}

3.11小结

3.11.1      #{}和${}

#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,#{}中可以写成value或其它名称。

#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。

${}接收输入参数,类型可以是简单类型,pojo、hashmap。

如果接收简单类型,${}中只能写成value。

${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。

3.11.2     parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

3.11.3     selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:

org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3

at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)

selectList可以查询一条或多条记录。

3.12   mybatis和hibernate本质区别和应用场景

hibernate:是一个标准ORM框架(对象关系映射)。入门门槛较高的,不需要程序写sql,sql语句自动生成了。

对sql语句进行优化、修改比较困难的。

应用场景:

适用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa。。

mybatis:专注是sql本身,需要程序员自己编写sql语句,sql修改、优化比较方便。mybatis是一个不完全 的ORM框架,虽然程序员自己写sql,mybatis 也可以实现映射(输入映射、输出映射)。

应用场景:

适用与需求变化较多的项目,比如:互联网项目。

企业进行技术选型,以低成本 高回报作为技术选型的原则,根据项目组的技术力量进行选择。

4     mybatis开发dao的方法

4.1     SqlSession使用范围

4.1.1     SqlSessionFactoryBuilder

通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory

将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。

在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

4.1.2   SqlSessionFactory

通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。

将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

4.1.3    SqlSession

SqlSession是一个面向用户(程序员)的接口。

SqlSession中提供了很多操作数据库的方法:如:selectOne(返回单个对象)、selectList(返回单个或多个对象)、。

SqlSession是线程不安全的,在SqlSesion实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

SqlSession最佳应用场合在方法体内,定义成局部变量使用。

4.2    原始dao开发方法(程序员需要写dao接口和dao实现类)

4.2.1     思路

程序员需要写dao接口和dao实现类。

需要向dao实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession

4.2.2     dao接口

package com.dzq.mybatis.dao;

import com.dzq.mybatis.domain.User;

public interface UserDao {
// 根据id查询用户信息
public User findUserById(int id) throws Exception; // 添加用户
public void addUser(User user) throws Exception; // 删除用户
public void deleteUser(int id) throws Exception; // 修改用户信息
public void updateUser(User user) throws Exception;
}

4.2.2     dao接口实现类

package com.dzq.mybatis.dao.impl;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory; import com.dzq.mybatis.dao.UserDao;
import com.dzq.mybatis.domain.User; public class UserDaoImpl implements UserDao {
// 需要向dao实现类中注入SqlSessionFactory
// 这里通过构造方法注入
private SqlSessionFactory sqlSessionFactory; public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
} @Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById", id);
// 释放资源
sqlSession.close();
return user;
} @Override
public void addUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 执行插入
sqlSession.insert("test.addUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
} @Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser", id);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close(); } @Override
public void updateUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.update("test.updateUser", user);
// 提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
} }

4.2.4  测试代码:

package com.dzq.mybatis.test;

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 com.dzq.mybatis.dao.UserDao;
import com.dzq.mybatis.dao.impl.UserDaoImpl;
import com.dzq.mybatis.domain.User; public class UserDaoImplTest { private SqlSessionFactory sqlSessionFactory; @Before
public void setUp() throws Exception {
// 创建sqlSessionFactory
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件的信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} @Test
public void testFindUserById() throws Exception {
// 创建UserDao对象
UserDao userdao = new UserDaoImpl(sqlSessionFactory);
// 调用userDao方法
User user=userdao.findUserById(1);
System.out.println(user.getUsername());
} }

4.2.5     总结原始 dao开发问题

1、dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statement的id硬编码了

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误,在编译阶段也不报错,不利于程序员开发。

4.3    mapper代理方法(程序员只需要mapper接口(相当 于dao接口))

4.3.1     思路(mapper代理开发规范)

程序员还需要编写mapper.xml映射文件

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

开发规范:

1、在mapper.xml中namespace等于mapper接口地址

<!--命名空间,对sql进行分类管理,实现sql隔离 注意:使用mapper代理的方法开发,namespace就有特殊重要的作用
namespace等于mapper接口地址
-->
<mapper namespace="com.dzq.mybatis.mapper.UserMapper">

2、mapper.java接口中的方法名和mapper.xml中statement的id一致

3、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

4、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

<select id="findUserById" parameterType="int" resultType="com.dzq.mybatis.domain.User">
select * from user where id=#{id}
</select>
// 根据id查询用户信息
public User findUserById(int id) throws Exception;

总结:

以上开发规范主要是对下边的代码进行统一生成:

User user = sqlSession.selectOne("test.findUserById", id);

sqlSession.insert("test.insertUser", user);

。。。。

4.3.2     mapper.java

package com.dzq.mybatis.mapper;

import java.util.List;

import com.dzq.mybatis.domain.User;

public interface UserMapper {

    public User findUserById(int id) throws Exception;
}

4.3.3 mapper.xml

<select id="findUserById" parameterType="int" resultType="com.dzq.mybatis.domain.User">
select * from user where id=#{id}
</select>

4.3.4     在SqlMapConfig.xml中加载mapper.xml

<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
<mapper resource="mapper/UserMapper.xml"/>
</mappers>

4.3.5    测试

package com.dzq.mybatis.test;

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.dzq.mybatis.domain.User;
import com.dzq.mybatis.mapper.UserMapper; public class UserMapperTest {
private SqlSessionFactory sqlSessionFactory;
@Before
public void setUp() throws Exception {
// 创建sqlSessionFactory
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 创建会话工厂,传入mybatis的配置文件的信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} @Test
public void testFindUserById() throws Exception { SqlSession sqlSession=sqlSessionFactory.openSession();
//创建一个usermapper的对象
UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
//调用userMapper方法
User user=userMapper.findUserById(1);
System.out.println(user.getUsername()); } }

4.3.6    整个接口

package com.dzq.mybatis.mapper;

import java.util.List;

import com.dzq.mybatis.domain.User;

public interface UserMapper {

    // 根据id查询用户信息
public User findUserById(int id) throws Exception; // 添加用户
public void addUser(User user) throws Exception; // 删除用户
public void deleteUser(int id) throws Exception; // 根据用户名称查询用户列表
public List<User> findUserByUserName(String username) throws Exception;
}

4.3.7     一些问题总结

4.3.7.1              代理对象内部调用selectOne或selectList

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。

如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

4.3.7.2              mapper接口方法参数只能有一个是否影响系统 开发

mapper接口方法参数只能有一个,系统是否不利于扩展维护。

系统 框架中,dao层的代码是被业务层公用的。

即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。

5     SqlMapConfig.xml

mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:

properties(属性)

settings(全局配置参数)

typeAliases(类型别名)

typeHandlers(类型处理器)

objectFactory(对象工厂)

plugins(插件)

environments(环境集合属性对象)

environment(环境子属性对象)

transactionManager(事务管理)

dataSource(数据源)

mappers(映射器)

5.1     properties属性

需求:

将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties的属性值。

在SqlMapConfig.xml中就不需要对数据库连接参数硬编码。

将数据库连接参数只配置在db.properties中,原因:方便对参数进行统一管理,其它xml可以引用该db.properties。

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=
<!-- 加载属性文件 -->
<properties resource="db.properties">
<!--properties中还可以配置一些属性名和属性值 -->
<!-- <property name="jdbc.driver" value=""/> -->
</properties>

properties特性:

注意: MyBatis 将按照下面的顺序来加载属性:

在 properties 元素体内定义的属性首先被读取。

然后会读取properties 元素中resource或 url 加载的属性,它会覆盖已读取的同名属性。

最后读取parameterType传递的属性,它会覆盖已读取的同名属性。

建议:

不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中。

在properties文件中定义属性名要有一定的特殊性,如:XXXXX.XXXXX.XXXX

5.2   settings全局参数配置

mybatis框架在运行时可以调整一些运行参数。

比如:开启二级缓存、开启延迟加载。。

全局参数将会影响mybatis的运行行为。

5.3     typeAliases(别名)重点

5.3.1     需求

在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型、需要resultType指定输出结果的映射类型。

如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发。

5.3.2   mybatis默认支持别名

5.3.3     自定义别名

5.3.3.1              单个别名定义

<!-- 别名定义 -->
<typeAliases>
<!-- 针对单个别名的定义
type:类型路径
alias:别名
-->
<typeAlias type="com.dzq.mybatis.domain.User" alias="user"/>
</typeAliases>

引用别名:

<select id="findUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>

5.3.3.2  批量定义别名(常用)

<!-- 批量别名定义
指定包名,mybatis自动扫描domain类,自动定义别名,别名就是类名
-->
<package name="com.dzq.mybatis.domain"/>

5.4    typeHandlers(类型处理器)

mybatis中通过typeHandlers完成jdbc类型和java类型的转换。

通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义.

mybatis支持类型处理器:

5.5  mappers(映射配置)

5.5.1     通过resource加载单个映射文件

<!-- 加载 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml" />
<mapper resource="mapper/UserMapper.xml" />
</mappers>

5.5.2   通过mapper接口加载单个mapper

<!--通过mapper接口加载单个mapper
遵循一些规范:需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录
上边规范的前提是:你使用的是mapper代理的方法
-->
<mapper class="com.dzq.mybatis.mapper.UserMapper"/>

需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录

5.5.3  批量加载mapper(推荐使用)

<!--批量加载mapper(推荐使用)
指定mapper接口的包名,mybatis自动扫描包下所有mapper接口进行加载
遵循一些规范:需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录
上边规范的前提是:你使用的是mapper代理的方法
-->
<package name="com.dzq.mybatis.mapper"/>

6    输入映射

通过parameterType指定输入参数的类型,类型可以是简单类型、hashmap、pojo的包装类型。

6.1     传递pojo的包装对象

6.1.1     需求

完成用户信息的综合查询,需要传入查询条件很复杂(可能包括用户信息、其它信息,比如商品、订单的)

6.1.2     定义包装类型pojo

针对上边需求,建议使用自定义的包装类型的pojo。

在包装类型的pojo中将复杂的查询条件包装进去。

package com.dzq.mybatis.domain;

public class UserQueryVo {
//这里包装所需要的查询条件
//用户查询条件
private UserCustom userCustom;
//还可以包装其他的查询条件 商品、订单 public UserCustom getUserCustom() {
return userCustom;
} public void setUserCustom(UserCustom userCustom) {
this.userCustom = userCustom;
} }

6.1.3    mapper.xml

在UserMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂关联查询)。

 <!-- 用户信息的综合查询
#{userCustom.sex}:取出包装类型的性别信息
${userCustom.username}:取出包装类中的用户名
-->
<select id="findUserList" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="com.dzq.mybatis.domain.UserCustom">
select * from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>

6.1.4     mapper.java

//用户信息综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;

6.1.5    测试代码

 @Test
public void testFindUserList() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建一个usermapper的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
// 调用userMapper方法 List<UserCustom> list = userMapper.findUserList(userQueryVo);
//sqlSession.close();
System.out.println(list); }

7     输出映射

7.1     resultType

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。

如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象。

只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象,不一致的属性的值为null。

7.1.1     输出简单类型

7.1.1.1              需求

用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。

7.1.1.2              mapper.xml

<!-- 用户信息综合查询总数
parameterType:输入类型和findUserList一致
resultType:输出结果类型为整型
-->
<select id="findUserCount" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="int">
select count(*) from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>

7.1.1.3              mapper.java

//用户信息综合查询总数
public int findUserCount(UserQueryVo userQueryVo) throws Exception;

7.1.1.4             测试代码

 @Test
public void testFindUserCount() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建一个usermapper的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom();
userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
// 调用userMapper方法 int count = userMapper.findUserCount(userQueryVo);
System.out.println(count); }

7.1.1.5             小结

查询出来的结果集只有一行且一列,可以使用简单类型进行输出映射。

7.1.2   输出pojo对象和pojo列表

不管是输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的。

在mapper.java指定的方法返回值类型不一样:

1、输出单个pojo对象,方法返回值是单个对象类型

    // 根据id查询用户信息
public User findUserById(int id) throws Exception;

2、输出pojo对象list,方法返回值是List<Pojo>

    // 根据用户名称查询用户列表
public List<User> findUserByUserName(String username) throws Exception;

生成的动态代理对象中是根据mapper方法的返回值类型确定是调用selectOne(返回单个对象调用)还是selectList (返回集合对象调用 ).

7.2     resultMap

mybatis中使用resultMap完成高级输出结果映射。(一对一、一对多、多对多)(小入门)

7.2.1     resultMap使用方法

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

1、定义resultMap

2、使用resultMap作为statement的输出映射类型

7.2.2     将下边的sql使用User完成映射

SELECT id id_,username username_ FROM USER WHERE id=#{value}

User类中属性名和上边查询列名不一致。

7.2.2.1              定义reusltMap

 <!-- 定义resultMap
将 select id id_,username username_ from user where id=#{id}查询和User做一个映射
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="user" id="userResultMap">
<!-- id表示查询结果集中唯一的标识
column:查询出来的列名
property:type中指定的pojo中的属性名
最终resultMap对column和property做一个映射关系(对应关系)
-->
<id column="id_" property="id"/>
<!-- 对普通列的定义
column:查询出来的列名
property:type中指定的pojo中的属性名
最终resultMap对column和property做一个映射关系(对应关系)
-->
<result column="username_" property="username"/> </resultMap>

7.2.2.2       使用resultMap作为statement的输出映射类型

 <!-- 使用resultMap来进行输出的映射
resultMap:指定定义的resultMap的id,如果resultMap在其他映射文件中,前边需要加上namespace -->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
select id id_,username username_ from user where id=#{id}
</select>

7.2.2.3            mapper.java

//根据id查询用户信息,使用resultMap输出
public User findUserByIdResultMap(int id)throws Exception;

7.2.2.4            测试

@Test
public void testFindUserByIdResultMap() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建一个usermapper的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 调用userMapper方法
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user.getUsername()); }

7.3    小结

使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。

如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap对列名和pojo属性名之间作一个映射关系。

8      动态sql

8.1     什么是动态sql

mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装。

8.2     需求

用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql。

对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。

8.3     mapper.xml

 <!-- 用户信息的综合查询
#{userCustom.sex}:取出包装类型的性别信息
${userCustom.username}:取出包装类中的用户名
-->
<select id="findUserList" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="com.dzq.mybatis.domain.UserCustom">
select * from user
<!-- where 可以自动的去掉条件中的第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</where> </select> <!-- 用户信息综合查询总数
parameterType:输入类型和findUserList一致
resultType:输出结果类型为整型
-->
<select id="findUserCount" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="int">
select count(*) from user
<!-- where 可以自动的去掉条件中的第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>

8.4   测试代码

 public void testFindUserList() throws Exception {

        SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建一个usermapper的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom(); //由于使用了动态sql,如果不设置某个值,这个条件不会拼接到sql中
//userCustom.setSex("1");
userCustom.setUsername("小明");
userQueryVo.setUserCustom(userCustom);
// 调用userMapper方法 List<UserCustom> list = userMapper.findUserList(userQueryVo);
//sqlSession.close();
System.out.println(list); }

8.5    sql片段

8.5.1     需求

将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其它的statement中就可以引用sql片段。

方便程序员进行开发。

8.5.2     定义sql片段

!--定义sql片段
id:sql片段的唯一标识
经验:基于单表定义sql片段,这样可重用性才高
sql片段中不要包括where
-->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and user.sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and user.username like '%${userCustom.username}%'
</if>
</if>
</sql>

8.5.3    引用sql片段

在mapper.xml中定义的statement中引用sql片段:

 <!-- 用户信息的综合查询
#{userCustom.sex}:取出包装类型的性别信息
${userCustom.username}:取出包装类中的用户名
-->
<select id="findUserList" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="com.dzq.mybatis.domain.UserCustom">
select * from user
<!-- where 可以自动的去掉条件中的第一个and -->
<where>
<!-- 这就是引用sql片段的id 如果refid不在本mapper中,需要加上namespace-->
<include refid="query_user_where"> </include>
<!-- 在这里还会引用其他sql片段,商品等 -->
</where> </select>
  <!-- 用户信息综合查询总数
parameterType:输入类型和findUserList一致
resultType:输出结果类型为整型
-->
<select id="findUserCount" parameterType="com.dzq.mybatis.domain.UserQueryVo" resultType="int">
select count(*) from user
<!-- where 可以自动的去掉条件中的第一个and -->
<where>
<!-- 这就是引用sql片段的id 如果refid不在本mapper中,需要加上namespace-->
<include refid="query_user_where"> </include>
<!-- 在这里还会引用其他sql片段,商品等 -->
</where>
</select>

8.6    foreach

向sql传递数组或List,mybatis使用foreach解析

8.6.1     需求

在用户查询列表和查询总数的statement中增加多个id输入查询。

sql语句如下:

两种方法:

SELECT * FROM USER WHERE id=1 OR id=10 OR id=16

SELECT * FROM USER WHERE id IN(1,10,16)

8.6.2    在输入参数类型中添加List<Integer> ids传入多个id

    //传入多个id
private List<Integer> ids; public List<Integer> getIds() {
return ids;
} public void setIds(List<Integer> ids) {
this.ids = ids;
}

8.6.3     修改mapper.xml

WHERE id=1 OR id=10 OR id=16

在查询条件中,查询条件定义成一个sql片段,需要修改sql片段。

 <if test="ids!=null">
<!-- 使用foreach遍历我们传入的ids
collection:指定输入对象中集合属性
item:每次遍历生成对象名
open:开始遍历时要拼接的串
close:结束遍历时拼接的串
separator:遍历的两个对象中间所要拼接的串
-->
<!-- 使用实现下边的sql拼接
and (id=1 or id=10 or id=16)
-->
<foreach collection="ids" item="user_id" open="and (" close=")" separator="or">
<!-- 每次遍历所需要拼接的串-->
id=#{user_id}
</foreach>
</if>

8.6.4     测试代码

 @Test
public void testFindUserList() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建一个usermapper的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo=new UserQueryVo();
UserCustom userCustom=new UserCustom(); //由于使用了动态sql,如果不设置某个值,这个条件不会拼接到sql中
userCustom.setSex("1");
userCustom.setUsername("小明");
//传入多个id
List <Integer> ids=new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
userQueryVo.setUserCustom(userCustom);
//将ids传入statement中
userQueryVo.setIds(ids); // 调用userMapper方法 List<UserCustom> list = userMapper.findUserList(userQueryVo);
//sqlSession.close();
System.out.println(list.get(0).getUsername()); }

8.6.5  另外一个sql的实现:

<!--实现  and id in(1,10,16)拼接  -->
<foreach collection="ids" item="user_id" open=" and id in(" close=")" separator=",">
<!-- 每次遍历所需要拼接的串-->
#{user_id}
</foreach>

20160522--20160526----mybatis入门基础的更多相关文章

  1. mybatis入门基础(二)----原始dao的开发和mapper代理开发

    承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...

  2. MyBatis入门基础(一)

    一:对原生态JDBC问题的总结 新项目要使用mybatis作为持久层框架,由于本人之前一直使用的Hibernate,对mybatis的用法实在欠缺,最近几天计划把mybatis学习一哈,特将学习笔记记 ...

  3. MyBatis入门基础

    转自http://www.cnblogs.com/selene/p/4604605.html 话不多说,先看看原始的JDBC程序代码,看看这样的代码存在什么样子的问题. package com.uti ...

  4. mybatis 入门基础

    一.Mybatis介绍 MyBatis是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架.MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去设置参数和获取检索结果.MyBatis ...

  5. mybatis入门基础(六)----高级映射(一对一,一对多,多对多)

    一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT, itemsname ) NOT ...

  6. mybatis入门基础----高级映射(一对一,一对多,多对多)

    阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id ...

  7. 【入门详解】MyBatis入门基础详解

    什么是mybatis? MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XM ...

  8. Mybatis入门——基础方式的增删该查、mapper动态代理方式的CRUD、类型转换器

    一.基础方式的增删该查: 1.mybatis约定:输入参数parameterType和输出参数resulrType在形式上只能有一个. 2.如果输入/输出参数:是简单类型(8个基本类型加String) ...

  9. mybatis入门基础(九)----逆向工程

    一.什么是逆向工程 mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml.po. ...

  10. mybatis入门基础(八)-----查询缓存

    一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 1.1. 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造 ...

随机推荐

  1. 10行Java代码实现最近被使用(LRU)缓存

    在最近的面试中,我曾被多次问到,怎么实现一个最近最少使用(LRU)的缓存.缓存可以通过哈希表来实现,然而为这个缓存增加大小限制会变成另一个有意思的问题.现在我们看一下怎么实现. 最近最少使用缓存的回收 ...

  2. spring框架中一个跟String的trim方法一样的方法

    @Test public void testTrimWhitespace() throws Exception { assertEquals(null, StringUtils.trimWhitesp ...

  3. Java字节码(.class文件)格式详解(一)

    原文链接:http://www.blogjava.net/DLevin/archive/2011/09/05/358033.html 小介:去年在读<深入解析JVM>的时候写的,记得当时还 ...

  4. MySQL 常用语句 (汇集)

    原文地址:MySql常用语句作者:wuyanle 一.mysql常用语句 创建,删除和最基本查询: 显示数据库  mysql->show databases; 创建数据库  mysql-> ...

  5. matlab s变换

    A4=readdata('E:\mydata.TXT');[st,t,f] = st(A4(1:1000,2)); surf(t,f,10*log10(abs(st)),'EdgeColor','no ...

  6. Android最新锁屏病毒分析及解锁

    一.情况简介   从去年开始PC端的敲诈者类病毒在不断的爆发,今年年初的时候手机上也开始出现了敲诈者之类的病毒,对这类病毒很无语也是趋势,因为很多时候病毒的产生是和金钱利益相关的.前天去吾爱破解论坛病 ...

  7. readonly disabled 区别

    readonly 提交表单时包含该属性的内容 控件 disabled 不包含该属性

  8. 【转】rvm安装ruby,gem,rails,之后仍然无法找到rails命令

    转自:http://chinacheng.iteye.com/blog/1738036 rvm安装ruby和rails之后,ruby -v好使,gem -v好使.但是rails -v不好使,提示没有安 ...

  9. HDU 5433 Xiao Ming climbing dp

    Xiao Ming climbing Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://bestcoder.hdu.edu.cn/contests/ ...

  10. STL之Map的运用

    Map是c++的一个标准容器,她提供了非常好一对一的关系,在一些程序中建立一个map能够起到事半功倍的效果,总结了一些map基本简单有用的操作! 1. map最主要的构造函数:    map<s ...