Mybatis学习笔记(二) 之实现数据库的增删改查
开发环境搭建
mybatis 的开发环境搭建,选择: eclipse j2ee 版本,mysql 5.1 ,jdk 1.7,mybatis3.2.0.jar包。这些软件工具均可以到各自的官方网站上下载。
首先建立一个名字为 MyBaits 的 dynamic web project
1. 可以创建maven项目,依赖的包mybatis-3.2.0-SNAPSHOT.jar,mysql-connector-java-5.1.22-bin.jar
<!-- mybatis包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.0</version>
</dependency> <!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.22</version>
</dependency>
2、构建后的项目结构

实现数据的增删改查
需求:
根据id(主键)查询用户信息
根据用户名模糊查询用户信息
添加用户
更新用户
删除用户
在新建一个源代码目录config,在config目录下使用以下的log4j属性文件(可以从mybatis示例程序中拷贝):
编码前的准备
添加log4j
# 开发环境中日志的级别使用DEBUG,生产环境中日志级别为ERROR
log4j.rootLogger=DEBUG, stdout
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 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
1. 设置mybatis 配置文件:Configuration.xml, 在src/main/java目录下建立此文件
注意:这里的typeAlias就相当于起别名,为com.yihaomen.mybatis.model.User包起一个user别名。
内容如下:
<?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>
<typeAliases>
<typeAlias alias="User" type="com.yihaomen.mybatis.model.User"/>
</typeAliases> <!-- spring整合之后,environments配置将废除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制有mybatis -->
<transactionManager type="JDBC"/>
<!-- 数据库连接池 ,有mybatis管理-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://192.168.6.1:3306/test"/>
<property name="username" value="dev"/>
<property name="password" value="123qwe"/>
</dataSource>
</environment>
</environments> <!-- 加载映射文件 -->
<mappers>
<mapper resource="com/yihaomen/mybatis/model/User.xml"/>
</mappers>
</configuration>
2、建立与数据库对应的 java class,以及映射文件.

package com.yihaomen.mybatis.model;
public class User {
private int id;
private String userName;
private int userAge;
private String userAddress;
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 int getUserAge() {
return userAge;
}
public void setUserAge(int userAge) {
this.userAge = userAge;
}
public String getUserAddress() {
return userAddress;
}
public void setUserAddress(String userAddress) {
this.userAddress = userAddress;
}
}
3、同时建立这个User 的映射文件 User.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"> <!-- namespace命名空间,作用就是对sql进行分类化管理,注意:使用mapper代理方法开发,namespace有特殊重要作用 -->
<mapper namespace="com.yihaomen.mybatis.dao.IUserOperation">
<!-- 在映射文件中配置很多sql -->
<!-- id标识映射文件的sql,称为statement的id ,将sql语句封装到mappedStatement对象中,所以将id称为statement的id
parameterType:指定输入类型 resultType:指定sql输出结果的所映射的java对象,select指定resultType表示将单挑记录
映射成java对象-->
<select id="selectUserByID" parameterType="int" resultType="User">
select * from `user` where id = #{id}
</select> <insert id="addUser" parameterType="User"
useGeneratedKeys="true" keyProperty="id">
insert into user(userName,userAge,userAddress) values(#{userName},#{userAge},#{userAddress})
</insert> <update id="updateUser" parameterType="User">
update user set userName=#{userName},userAge=#{userAge},userAddress=#{userAddress} where id=#{id}
</update> <delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete> <select id="list" resultType="User">
select * from `user`
</select> <!-- ${}表示拼接sql串,指定就是单挑记录所映射的java对象类型,使用${}拼接,容易导致sql注入
${value}:拼接输入参数的内容,如果传入类型是简单类型,${}中只能使用value -->
<select id="findUserByName" parameterType="String" resultType="User">
select * from `user` where username like '%${value}%'
</select>
</mapper>
下面对这几个配置文件解释下:
1.Configuration.xml 是 mybatis 用来建立 sessionFactory 用的,里面主要包含了数据库连接相关东西,还有 java 类所对应的别名,比如 <typeAlias alias="User" type="com.yihaomen.mybatis.model.User"/> 这个别名非常重要,你在 具体的类的映射中,比如User.xml 中 resultType 就是对应这里的。要保持一致,当然这里的 resultType 还有另外单独的定义方式,后面再说。
2. Configuration.xml 里面 的<mapper resource="com/yihaomen/mybatis/model/User.xml"/>是包含要映射的类的xml配置文件。
3. 在User.xml 文件里面 主要是定义各种SQL 语句,以及这些语句的参数,以及要返回的类型等.
4、为了以接口方式编程,而且是更好的方法,使用合理描述参数和SQL语句返回值的接口(比如IUserOperation.class),这样现在就可以至此那个更简单,更安全的代码,没有容易发生的字符串文字和转换的错误.下面是详细过程:
在目录下建立 com.yihaomen.mybatis.dao 这个包,并建立接口类 IUserOperation , 内容如下
package com.yihaomen.mybatis.dao; import java.util.List; import com.yihaomen.mybatis.model.Article;
import com.yihaomen.mybatis.model.User; //注意:接口名字必须与 xml中的namespace名字一样 2、接口实现方法每个名字 与xml中的id对应
public interface IUserOperation {
//查询数据
public User selectUserByID(int id);
//增加数据
public void addUser(User user);
//更新数据
public void updateUser(User user);
//删除数据
public void deleteUser(int id);
//联合查询
public List<Article> getUserArticles(int id);
//list获取
public List<User> list();
//模糊查询
public List<User> findUserByName(String name); }
5、开始测试,测试类:
package com.yihaomen.mybatis.ui; import java.io.Reader;
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 com.yihaomen.mybatis.dao.IUserOperation;
import com.yihaomen.mybatis.model.User; public class Test {
private static SqlSessionFactory sqlSessionFactory;
private static Reader reader; //创建会话工厂,传入mybatis的配置文件信息
static{
try{
//得到配置文件流
reader = Resources.getResourceAsReader("Configuration.xml");
//创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
}catch(Exception e){
e.printStackTrace();
}
}
//公共方法,返回初始化的sqlSessionFactory对象
public static SqlSessionFactory getSession(){
return sqlSessionFactory;
} //查询数据
public void select() {
//通过工厂得到sqlsession
SqlSession session = sqlSessionFactory.openSession();
try {
//通过SqlSession操作数据库
//第一个参数:映射文件中statement的id
//第二个参数:指定和映射文件所匹配的parameterType类型参数
User user = (User) session.selectOne("com.yihaomen.mybatis.model.User.selectUserByID", 1);
System.out.println(user.getUserAddress());
System.out.println(user.getUserName());
} finally {
session.close();
}
} //增加数据
public void addUser(String address,String name){
//创建user对象
User user=new User();
user.setUserAddress(address);
user.setUserName(name);
user.setUserAge(80); //通过工厂得到SqlSession
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation=session.getMapper(IUserOperation.class);
//添加数据
userOperation.addUser(user);
//提交
session.commit();
//System.out.println("当前增加的用户 id为:"+user.getId());
} finally {
session.close();
}
} //更新数据
public void updateUser(int id,String address){
//先得到用户,然后修改,提交。
SqlSession session = sqlSessionFactory.openSession();
try {
IUserOperation userOperation = session.getMapper(IUserOperation.class);
User user = userOperation.selectUserByID(id);
user.setUserAddress(address);
userOperation.updateUser(user);
session.commit();
System.out.println("更新成功!!");
} finally {
session.close();
}
} //删除数据
public void deleteUser(int id) {
SqlSession session = sqlSessionFactory.openSession(); try{
IUserOperation userOperation = session.getMapper(IUserOperation.class);
userOperation.deleteUser(id);
session.commit();
System.out.println("删除数据:id= "+id);
}finally {
session.close();
} } //list获取
public void getList() {
SqlSession session = sqlSessionFactory.openSession(); try{
IUserOperation userOperation = session.getMapper(IUserOperation.class);
List<User> us = userOperation.list();
session.commit();
//System.out.println("生成list: "+us.size());
}finally {
session.close();
} } //模糊查询
public void geFindUserByName(String name) {
SqlSession session = sqlSessionFactory.openSession(); try{
IUserOperation userOperation = session.getMapper(IUserOperation.class);
List<User> us = userOperation.findUserByName(name);
System.out.println(us.size());
session.commit(); }finally {
session.close();
}
} public static void main(String[] args) {
Test test = new Test();
test.getList();
test.geFindUserByName("小");
//test.addUser("杭州","小江");
}
}
结果日志:
[2017-01-10 20:22:33] DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
[2017-01-10 20:22:33] DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
[2017-01-10 20:22:33] DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
[2017-01-10 20:22:33] DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
[2017-01-10 20:22:33] DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
[2017-01-10 20:22:33] DEBUG [main] - Opening JDBC Connection
[2017-01-10 20:22:34] DEBUG [main] - Created connection 238157928.
[2017-01-10 20:22:34] DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e320068]
[2017-01-10 20:22:34] DEBUG [main] - ==> Preparing: select * from `user` where username like '%小%'
[2017-01-10 20:22:34] DEBUG [main] - ==> Parameters:
[2017-01-10 20:22:34] DEBUG [main] - <== Total: 7
7
[2017-01-10 20:22:34] DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@e320068]
[2017-01-10 20:22:34] DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@e320068]
[2017-01-10 20:22:34] DEBUG [main] - Returned connection 238157928 to pool.
总结
parameterType在映射文件中通过parameterType指定输入参数的类型。
resultType在映射文件中通过resultType指定输出结果的类型。
#{}和${}
#{}表示一个占位符号,#{}接收输入参数,类型可以是简单类型,pojo、hashmap。如果接收简单类型,#{}中可以写成value或其它名称。#{}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。${}表示一个拼接符号,会引用sql注入,所以不建议使用${}。
${}接收输入参数,类型可以是简单类型,pojo、hashmap。如果接收简单类型,${}中只能写成value。
${}接收pojo对象值,通过OGNL读取对象中的属性值,通过属性.属性.属性...的方式获取对象属性值。
selectOne和selectList
selectOne表示查询出一条记录进行映射。如果使用selectOne可以实现使用selectList也可以实现(list中只有一个对象)。
selectList表示查询出一个列表(多条记录)进行映射。如果使用selectList查询多条记录,不能使用selectOne。
如果使用selectOne报错:
org.apache.ibatis.exceptions.TooManyResultsException: Expected oneresult (or null) to be returned by selectOne(), but found: 4
参考
1、mybatis学习笔记(一)--基本crud操作:https://segmentfault.com/a/1190000003771372
2、mybatis学习笔记入门:http://www.cnblogs.com/hellokitty1/p/5216025.html
3、mybatis实战教程:http://blog.csdn.net/techbirds_bao/article/details/9233599/
4、深入理解mybatis原理:http://blog.csdn.net/column/details/mybatis-principle.html?page=1
5、Mybatis系列学习:http://blog.csdn.net/chris_mao/article/details/48827961
Mybatis学习笔记(二) 之实现数据库的增删改查的更多相关文章
- MyBatis学习(二)MyBatis-Statement方式的增删改查
1.前期准备 项目骨架图如下所示 1.配置conf.xml <?xml version="1.0" encoding="UTF-8" ?> < ...
- mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
最后更新时间:2017-07-13 11:10:49 原始文章链接:http://www.lovebxm.com/2017/07/13/mongodb_primer/ MongoDB - 简介 官网: ...
- 【转】mongoDB 学习笔记纯干货(mongoose、增删改查、聚合、索引、连接、备份与恢复、监控等等)
mongoDB 学习笔记纯干货(mongoose.增删改查.聚合.索引.连接.备份与恢复.监控等等) http://www.cnblogs.com/bxm0927/p/7159556.html
- MySQL数据库(二)-数据库的增删改查
简介: 以下是MySQL最基本的增删改查语句.在进行“增删改查”的操作之前,先建立一个包含数据表student的数据库,新建表grade(具体操作可以见上一篇). 一."增"-添加数据 1.1 为表中 ...
- SQL学习(二)SQL基础的增删改查
在测试时使用数据库时,用的比较多的就是增删改查SQL了. 一.增加(insert into ...values) 用于向表中插入新记录 1.不指定列(表示:依次插入所有列的值) insert into ...
- Mybatis学习(3)实现数据的增删改查
前面已经讲到用接口的方式编程.这种方式,要注意的一个地方就是.在User.xml 的配置文件中,mapper namespace="com.yihaomen.mybatis.inter.I ...
- Spring学习笔记:声明式事务管理增删改查业务
一.关于是事务 以方法为单位,进行事务控制:抛出异常,事务回滚. 最小的执行单位为方法.决定执行成败是通过是否抛出异常来判断的,抛出异常即执行失败 二.声明式事务: 声明式事务(declarative ...
- Java学习笔记34(sql基础 :增删改查1)
create database qy97;/*创建数据库*/ use qy97; /*使用数据库 use 数据库名*/ show tables; /*查看所有的表*/ select database( ...
- C#学习笔记(6)——大项目增删改查
说明(2017-5-28 11:35:39): 1. 需要注意的地方很多 2. 首先是连接字符串str要直接写在类里面,不然每个按钮里面都要写一遍. 3. 查询用到sqlDataReader等三个方法 ...
随机推荐
- MySQL之查询优化方式(笔记)
1.COUNT() 对COUNT的优化可以通过下面的SQL实现 mysql> select count(gnp<10000 or null) as '<<<<',c ...
- 确保Zend Studio最佳性能的10点建议
作为一个PHP开发人员,你需要知道使用Zend Studio时,什么应该做,什么要避免.就像Roy Ganor说的那样“你必须掌握的你IDE”.从IDE角度来看,建立PHP项目时,了解Zend Stu ...
- WindowsService开发遇到的问题
1.Windows服务安装 通过cmd运行指令安装Windows服务: 安装方法:运行cmd,以InstallUtil.exe 来运行 Windows服务程序. 如果是Release模式的话,直接在c ...
- 【jar包】Android——eclipse共享library以及导出jar包
android的apk在在eclipse上进行开发的时候,有时候需要import其它包中的一些class,正常的方法就是在java build path中library 中添加 jar 包! 转载注明 ...
- 【AngularJS】 2.0 版本发布
[AngularJS] 2.0 版本发布 w5cValidator[AngularJS] 2.0 版本发布 w5cValidator 插件基于angular原有的表单验证,在原有的基础上扩展了一些 ...
- attr与prop的区别
我们在获取checked属性值的时候,如果被选中则值为"checked"没选中获取值就是undefined. (引述他人)因为在有些浏览器中比如说只要写disabled,check ...
- VS2013全攻略(安装,技巧,快捷键,插件)!
工欲善其事,必先利其器.VS2013全攻略(安装,技巧,快捷键,插件)! 之前一篇<c++的性能, c#的产能?!鱼和熊掌可以兼得,.NET NATIVE初窥>承蒙大家喜爱和编辑推荐,在此 ...
- Glue4Net简单部署基于win服务的Socket程序
smark 专注于高并发网络和大型网站架规划设计,提供.NET平台下高吞吐的网络通讯应用技术咨询和支持 Glue4Net简单部署基于win服务的Socket程序 在写一些服务应用的时候经常把要它部署到 ...
- 一致性hash和虚拟节点
consistent hashing 算法的原理 consistent hashing 是一种 hash 算法,简单的说,在移除 / 添加一个 cache 时,它能够尽可能小的改变已存在key 映射关 ...
- Python 用POP接收邮件
一.简介 POP(Post Office Protocal)最长用的POP版本是POP3,因此本文是以POP3为主.POP3非常简单,可以用来从邮件服务器上下载邮件,然后删除这些邮件.功能非常有限,后 ...