MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装。MyBatis可以使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
MyBatis的特点:
执行效率:JDBC>MyBatis>Hibernate
代码我复杂度:JDBC>MyBatis>Hibernate
执行流程:
1>:加载我们的mybatis.xml文件
2>:加载的是我们的mapper的映射文件
3>:通过你调用的方法 找到我们的mapper的命名空间
4>;通过命名空间调用我们的xml描述的方法(会自动的生成方法的)
5>:调用SQL语句执行操作....
所需要的包:
asm-3.3.1.jar :字节码相关的包
cglib-2.2.2.jar :cglib的代理包
commons-logging-1.1.1.jar :日志相关的包
log4j-1.2.16.jar :也是日志相关的包
mybatis-3.1.1.jar :这个mybatis的核心功能包
mysql-connector-java-5.1.7-bin.jar:数据库的驱动包
给日志添加配置信息: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
在src下面创建mybatis的配置文件:mybatis.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--这个配置文件是不用记住的 只是需要 知道去哪里找就OK了 -->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!-- configuration:这个表示的是整个的配置信息 -->
<configuration>
<!-- environments环境可以配置多个 比如 mySql orale? ... default:默认使用那个环境 后面的值 必须是后面的id
mysql / oracle -->
<environments default="mysql">
<!-- environment:这个表示的是配置的是单个的环境 id:给环境添加唯一的标识符 id可以随便取名 但是一般也要见名之意 -->
<environment id="mysql">
<!--mybatis的事物只能交给JDBC去进行处理 -->
<transactionManager type="JDBC" />
<!--这个表示的是数据库的连接池 type也只能写 pooled -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///iBatis001" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
<environment id="oracle">
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql:///iBatis001" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!--配置的是映射的文件 -->
<mappers>
<mapper resource="com/wc/pojo/UserMapper.xml" />
</mappers>
</configuration>
创建实体对象:User.java
public class User {
private Integer id;//id
private String uName;
private String uPassword;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getuName() {
return uName;
}
public void setuName(String uName) {
this.uName = uName;
}
public String getuPassword() {
return uPassword;
}
public void setuPassword(String uPassword) {
this.uPassword = uPassword;
}
public User(Integer id, String uName, String uPassword) {
super();
this.id = id;
this.uName = uName;
this.uPassword = uPassword;
}
public User() {
super();
}
@Override
public String toString() {
return "User [id=" + id + ", uName=" + uName + ", uPassword=" + uPassword + "]";
}
public User(String uName, String uPassword) {
super();
this.uName = uName;
this.uPassword = uPassword;
}
}
编写映射文件:UserMapper.xml
<?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">
<!--mapper表示的是 :实体的映射
mapper到底在我们的开发能够干什么呢?
1>:编写我们的访问方法的xml文件
2>:将我们的映射文件的结果 绑定到指定的对象
3>:表示的是可以对一对多或者多对一来进行映射
4>:就是我们可以 进行普通的信息配置 取名字 ...
nameSpace:这个的主要功能是给当前的映射文件 添加一个人唯一的标识符(取名字)
这个地方的命名 一般情况下是可以通过 dao的类的全路径来命名 com.qf.helloword.Test_001
这里也可以:直接使用当前的poMapper这样来进行命名
-->
<mapper namespace="com.wc.test.MyTest">
<!--这里面实际上就是 我们的操作数据库的sql语句-->
<!--编写一个向数据库插入内容 id:相当于是我们的方法的名字-->
<select id="getUserById" parameterType="int" resultType="com.wc.pojo.User">
select * from t_user where id = #{id}
</select>
<select id="getAllUser" resultType="com.wc.pojo.User">
select * from t_user
</select>
<!--模糊查询-->
<select id="selectLike" parameterType="string" resultType="com.wc.pojo.User">
select * from t_user where uName like #{value}
</select>
<select id="selectLike2" parameterType="string" resultType="com.wc.pojo.User">
<!--这种模式容易造成sql注入-->
select * from t_user where uName like '%${value}%'
</select>
<!--分页查询完一下-->
<select id="selectPaging" parameterType="map" resultType="com.wc.pojo.User">
select * from t_user limit #{pStart},#{pSize}
</select>
<insert id="addUser" parameterType="com.wc.pojo.User">
insert into t_user(uName,uPassword) values(#{uName},#{uPassword});
</insert>
<!--更新数据的玩法-->
<update id="updateUser" parameterType="com.wc.pojo.User">
update t_user set uName=#{uName},uPassword=#{uPassword} where id=#{id}
</update>
<!--测试下删除的玩法-->
<delete id="deleteById" parameterType="int">
delete from t_user where id=#{value}
</delete>
</mapper>
测试类:MyTest.java(项目中的Dao层)
public class MyTest {
private String path=this.getClass().getName();
@Test
public void test001() {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
User user = (User)sqlSession.selectOne(path+".getUserById",2);
System.out.println(user);
}
@Test
public void test002() {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
List<User> list=sqlSession.selectList(path+".getAllUser");
for (User user : list) {
System.out.println(user);
}
}
@Test
public void test004() {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
List<User> list=sqlSession.selectList(path+".selectLike","%霜%");
System.out.println(list);
}
@Test
public void test005() {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
List<User> list=sqlSession.selectList(path+".selectLike","霜");
System.out.println(list);
}
/**
* 测试的是分页查询
* @throws Exception
*/
@Test
public void test006() throws Exception {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
Map<String,Integer> map=new HashMap<String, Integer>();
map.put("pStart",1);
map.put("pSize",2);
List<User> list=sqlSession.selectList(path+".selectPaging",map);
System.out.println("查询回来的数据是:"+list);
//提交
sqlSession.commit();
sqlSession.close();
}
@Test
public void testUpdate() throws Exception {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
//调用我们的配置
User user=new User();
user.setId(3);
user.setuName("sdfsdf");
user.setuPassword("777");
sqlSession.delete(path+".updateUser",user);
MyBatisUtils.close();
}
/**
* 测试下删除
* @throws Exception
*/
@Test
public void testDelete() throws Exception {
//第一步:加载我们的配置文件 //默认的路径就是我们的src目录下
SqlSession sqlSession=MyBatisUtils.getSqlSession();
//调用我们的配置
sqlSession.delete(path+".deleteById",3);
MyBatisUtils.close();
}
@Test
public void test009() {
SqlSession sqlSession=MyBatisUtils.getSqlSession();
User user =new User("霜雾","shuang");
sqlSession.insert(path+".addUser",user);
MyBatisUtils.close();
}
}
帮助类:MyBatisUtils.java(获取sqlSession)
public class MyBatisUtils {
private static ThreadLocal<SqlSession> threadLocal=null;
private static SqlSessionFactory sessionFactory=null;
static {
threadLocal=new ThreadLocal<SqlSession>();
try {
//加载我们的配置文件 ,默认的路径就是我们的src目录下,创建我们的sqlSessionFactory对象
sessionFactory=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis.xml"));
} catch (IOException e) {
System.out.println("初始化参数出现了异常");
}
}
/**
* 获取我们的session
* @return
*/
public static SqlSession getSqlSession() {
SqlSession sqlSession=threadLocal.get();
if(sqlSession!=null) {
return sqlSession;
}else{
sqlSession=sessionFactory.openSession();
//将对象放入threadLocal
threadLocal.set(sqlSession);
return sqlSession;
}
}
public static void close() {
SqlSession sqlSession = threadLocal.get();
if(sqlSession!=null) {
sqlSession.commit();
sqlSession.close();
threadLocal.remove();
}
}
}
动态的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">
<mapper namespace="userMapper">
<!-- 需求:假设我需要查询所给用户id的所有用户 (必须适使用集合来实现) -->
<!--给定一连串的用户id 然后来 获取用户的对象值-->
<select id="findUserByIds" parameterType="java.util.List" resultType="com.wc.test01.User">
select * from t_user
<!--使用动态的sql来进行拼接
collection:集合对象的名字你记住 list集合对象的对象就是 list
item:每一次遍历出来的对象 名字是可以随便写的 但是 一般要见名之意
open:拼接Sql之前以什么开始 就是在遍历数据之前
close:就是以什么结尾 结束符
separator:遍历出来的数据以什么进行分割
-->
<foreach collection="list" item="id" open="where uId in(" separator="," close=")">
#{id}
</foreach>
</select>
<!-- 需求:假设我需要查询所给用户id的所有用户 (必须适使用集合来实现) 集合可以为null-->
<!--给定一连串的用户id 然后来 获取用户的对象值-->
<select id="findUserByIdsIsNull" parameterType="java.util.List" resultType="com.wc.test01.User">
select * from t_user
<!--使用动态的sql来进行拼接
collection:集合对象的名字你记住 list集合对象的对象就是 list
item:每一次遍历出来的对象 名字是可以随便写的 但是 一般要见名之意
open:拼接Sql之前以什么开始 就是在遍历数据之前
close:就是以什么结尾 结束符
separator:遍历出来的数据以什么进行分割
-->
<!--if条件判断的用法-->
<if test="list!=null">
<foreach collection="list" item="id" open="where uId in(" separator="," close=")">
#{id}
</foreach>
</if>
</select>
<!--多条件的查询,且条件不定-->
<select id="findUserByManyCondition" parameterType="map" resultType="com.wc.test01.User">
select * from t_user
<!--where 条件还可以这样写-->
<include refid="bobo"></include>
</select>
<!--下面定义的是sql的片段-->
<sql id="bobo">
<where>
1=1
</where>
<if test="uName!=null and uName!=''">
and uName=#{uName}
</if>
<if test="uPassWord!=null and uPassWord!=''">
and uPassWord=#{uPassWord}
</if>
</sql>
<!--通过用户的名字来查询用户
如果传递过来的是数组的话那么 接受的时候使用 接受的数据类型使用 list来接受
-->
<select id="findUserbyNames" parameterType="list" resultType="com.wc.test01.User">
select * from t_user where 1=1
<!--如果传递过来是数组的话那么下面的对象的名字 就必须是 array-->
<foreach collection="array" item="name" open="and uName in(" separator="," close=")">
#{name}
</foreach>
</select>
<!-- list结合中是user的这种情况-->
<select id="findUserbyNames1" parameterType="list" resultType="com.wc.test01.User">
select * from t_user where 1=1
<!--如果传递过来是数组的话那么下面的对象的名字 就必须是 array-->
<foreach collection="list" item="user" open="and uName in(" separator="," close=")">
#{user.uName}
</foreach>
</select>
</mapper>
测试类:
public class Test_001 {
/**
* 查找用户 要通过id值
* @throws Exception
*/
@Test
public void testFindUserByIds() throws Exception {
SqlSession sqlSesion = MyBatisUtils.getSqlSession();
List<Integer> list=new ArrayList<Integer>();
list.add(1);
list.add(3);
list.add(5);
list.add(7);
List<User> usList=sqlSesion.selectList("userMapper.findUserByIds",list);
System.out.println("接受到的数据是:"+usList);
MyBatisUtils.close();
}
/**
* 测试为null的情况
* @throws Exception
*/
@Test
public void testFindUserByIdsIsNull() throws Exception {
SqlSession sqlSesion = MyBatisUtils.getSqlSession();
List<User> usList=sqlSesion.selectList("userMapper.findUserByIdsIsNull",null);
System.out.println("接受到的数据是:"+usList);
MyBatisUtils.close();
}
/**
* 测试为null的情况
* @throws Exception
*/
@Test
public void testfindUserByManyCondition() throws Exception {
SqlSession sqlSesion = MyBatisUtils.getSqlSession();
Map<String,Object> map=new HashMap<String, Object>();
map.put("uName","小波波");
//map.put("uPassWord","110");
List<User> usList=sqlSesion.selectList("userMapper.findUserByManyCondition",map);
System.out.println("接受到的数据是:"+usList);
MyBatisUtils.close();
}
/**
* 通过数组的名字来查询用户对象
* @throws Exception
*/
@Test
public void testfindUserByNames() throws Exception {
SqlSession sqlSesion = MyBatisUtils.getSqlSession();
String[] arr={"小波波","110"};
List<User> usList=sqlSesion.selectList("userMapper.findUserbyNames",arr);
System.out.println("接受到的数据是:"+usList);
MyBatisUtils.close();
}
/**
* List结合传递的是类的对象类型
* @throws Exception
*/
@Test
public void testfindUserByNames1() throws Exception {
SqlSession sqlSesion = MyBatisUtils.getSqlSession();
List<User> users=new ArrayList<User>();
users.add(new User(12,"小波波","112"));
users.add(new User(17,"小网资","112"));
users.add(new User(19,"扛把子","112"));
List<User> usList=sqlSesion.selectList("userMapper.findUserbyNames1",users);
System.out.println("接受到的数据是:"+usList);
MyBatisUtils.close();
}
}