20160522--20160526----mybatis入门基础
一、基础知识:
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入门基础的更多相关文章
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
- MyBatis入门基础(一)
一:对原生态JDBC问题的总结 新项目要使用mybatis作为持久层框架,由于本人之前一直使用的Hibernate,对mybatis的用法实在欠缺,最近几天计划把mybatis学习一哈,特将学习笔记记 ...
- MyBatis入门基础
转自http://www.cnblogs.com/selene/p/4604605.html 话不多说,先看看原始的JDBC程序代码,看看这样的代码存在什么样子的问题. package com.uti ...
- mybatis 入门基础
一.Mybatis介绍 MyBatis是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架.MyBatis几乎消除了所有的JDBC代码,也基本不需要手工去设置参数和获取检索结果.MyBatis ...
- mybatis入门基础(六)----高级映射(一对一,一对多,多对多)
一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id INT NOT NULL AUTO_INCREMENT, itemsname ) NOT ...
- mybatis入门基础----高级映射(一对一,一对多,多对多)
阅读目录 一:订单商品数据模型 二.一对一查询 三.一对多查询 四.多对多查询 回到顶部 一:订单商品数据模型 1.数据库执行脚本 创建数据库表代码: CREATE TABLE items ( id ...
- 【入门详解】MyBatis入门基础详解
什么是mybatis? MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XM ...
- Mybatis入门——基础方式的增删该查、mapper动态代理方式的CRUD、类型转换器
一.基础方式的增删该查: 1.mybatis约定:输入参数parameterType和输出参数resulrType在形式上只能有一个. 2.如果输入/输出参数:是简单类型(8个基本类型加String) ...
- mybatis入门基础(九)----逆向工程
一.什么是逆向工程 mybaits需要程序员自己编写sql语句,mybatis官方提供逆向工程 可以针对单表自动生成mybatis执行所需要的代码(mapper.java,mapper.xml.po. ...
- mybatis入门基础(八)-----查询缓存
一.什么是查询缓存 mybatis提供查询缓存,用于减轻数据压力,提高数据库性能. mybaits提供一级缓存,和二级缓存. 1.1. 一级缓存是sqlSession级别的缓存.在操作数据库时需要构造 ...
随机推荐
- 拉格朗日对偶(Lagrange duality)
拉格朗日对偶(Lagrange duality) 存在等式约束的极值问题求法,比如下面的最优化问题: 目标函数是f(w),下面是等式约束.通常解法是引入拉格朗日算子,这里使用 ...
- HW6.13
import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...
- Win7 NFS 设置详解 | X-Space
Win7 NFS 设置详解 | X-Space Win7 NFS 设置详解
- [iOS基础控件 - 4.3] APP列表 xib的使用
A.storyboard和xib 1.storyboard: 相对xib较重量级,控制整个应用的所有界面 2.xib: 轻量级,一般用来描述局部界面 B.使用 1.新建xib文件 New File ...
- 幻灯片(jquery实现)
html代码: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www ...
- 阿里巴巴笔试整理系列 Session2 高级篇
阿里一面:1. 入场就是红黑树,B数2. apache和nginx源码看过多少,平时看过什么技术论坛,还有没有看过更多的开源代码3. pthread 到自旋锁4. hadoop源码看过没5. 为什么选 ...
- cocos2d-x Menu、MenuItem
转自:http://codingnow.cn/cocos2d-x/832.html 学习cocos2d-x中的菜单主要需要了解:菜单(CCMenu)和菜单项(CCMenuItem)以及CCMenuIt ...
- Lync安装随笔
使用域管理员权限扩展架构 1.iis角色安装 2.net3.5,消息队列服务器.目录服务集成.桌面体验.AD DS和AD LDS工具(远程服务管理工具中),启用WindowsFirewall服务 3. ...
- android学习日记10--裁剪区域
裁剪区域 裁剪是画布的一个函数,区域可以是矩形和圆形,也可以通过设置 path 或Region来显示自定义区域,通过不同组合,Android几乎可以支持任意现状的裁剪区域.android.graphi ...
- 学习笔记之SQL Programming DB2
http://publib.boulder.ibm.com/infocenter/iseries/v5r4/index.jsp If you intend to update a column or ...