Mybatis初探
寒假组织java高级组件实训,第一次接触了Mybatis,简单学习了Mybatis连接数据库的增删查改
步骤如下
- 先要设置MyBatis的环境,即jar包,这个可以在网上搜一搜
- 其次是配置数据源,一共配置两个数据员源,一个是Mysql,一个是Oracle,我们现在用的是Mysql,所以default属性配置的mysql
- 完成数据库sql语句的映射,虽然这也不是太懂,我的理解就是用标记语言添加sql语句
- 创建类,这里的类就是你所要操作的表转变而来的
- 在代码里,通过Sqlsession去调用
在本例中,数据库中只有user_c一张表,id,name,age,address这四个属性
- User类的实现如下
package pojo;
/**
* 这个类是对User_c表的抽象
* @author apple
*
*/
public class User {
private String id;
private String name;
private int age;
private String address;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
- User的映射文件代码如下
- 注意:映射的namespace必须指定,并且是唯一的,如果有两个映射文件的namespace相同,启动时会报错,所谓的启动时在后期和Spring进行整合的时候,启动报错
<?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必须指定,并且是唯一的,如果有两个映射文件的namespace相同,启动时会报错,
所谓的启动时在后期和Spring进行整合的时候,启动报错 -->
<mapper namespace="pojo.User">
<!-- 1.查询所有 -->
<select id="findAll" resultType="pojo.User">
select * from user_c
</select>
<!-- 2.根据id查询 -->
<select id="findById" resultType="pojo.User">
select * from user_c where id='3';
</select>
<!-- 3.更新 -->
<update id="updateById" >
update user_c set name='wang' where id='2';
</update>
<!-- 4.插入 -->
<insert id="insertInfo">
insert into user_c(id,name,age,address) values('6','Rod Jhonson',10000,'American');
</insert>
<!-- 5.删除 -->
<delete id="deleteInfo">
delete from user_c where id = '6';
</delete>
<!--6.通过传参,实现查询
parameterType指定的是传递参数的类型,常见的有:string,int,long,map -->
<select id="findUserByParam" parameterType="map" resultType="pojo.User">
select * from user_c where id=#{userid};
</select>
<!-- 通过传参,实现更新 -->
<select id="updataNameById" parameterType="map">
update user_c set name=#{name} where id=#{userid};
</select>
<!--8.通过传参,实现新增
对于取值的问题,Mybatis底层是通过反射机制来做的,比如,当传参类型是User的时候,mybatis首先会根据反射拿到
User的私有属性名,id,name,age,address。接下来,MyBatis通过调用getXxx()得到对应的值。所以需要注意的是
#{取值名}要和对象的私有属性名保持一致
#{}取值的工作原理,#{}会拿到参数类型,如果是string类型,就会自动''。如果是整型,则不处理
#{}底层调用的是JDBC的PrepareStatement,具备预编译的功能,好处是提高sql的执行效率。此外,可以防止
sql注入攻击,防止单撇注入攻击。Statement的好处是可以执行批处理。Mybatis默认的用的是PrepareStatement来做,
可以在sql标签里,通过statementType="STATEMENT"来指定
-->
<insert id="insertParam" parameterType="pojo.User">
insert into user_c(id,name,age,address) values(#{id},#{name},#{age},#{address});
</insert>
<!-- 9.通过传参,实现条件排序,遇到的问题是#{}取值表达式,因为#{}会为string参数加''
导致查询结果是错误的,应该用${},他不会做''的处理
但是注意,${}的传值类型是map
-->
<select id="findByOrder" parameterType="map" resultType="pojo.User">
select * from user_c order by ${param};
</select>
<!-- 10.通过传参,实现年龄段查询, 注意,<在xml需要转义,
如果不处理,当做没有闭合的标签来做
第一种方式,用< 表示<
第二种方式,<![CDATA[想转义的字符]]>-->
<select id="findByAgeRange" parameterType="map" resultType="pojo.User">
select * from user_c where 1=1
<if test="minAge!=null">age>#{minAge}</if>
<if test="maxAge!=null">and age <![CDATA[<]]> #{maxAge};</if>
</select>
</mapper>
- 数据层代码实现如下
package dao;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;
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 pojo.User;
public class SqlDao {
private SqlSessionFactory factory;
@Before //这个注解的作用是在所有的@Test测试执行前执行
public void initSqlSessionFactory() throws IOException{
/*
* 注意Resources用的是org.apache.ibatis.io.Resources
*/
InputStream in=Resources.getResourceAsStream("sqlMapConfig.xml");
/*
*创建工厂类的目的是通过工厂创建SqlSession对象,重点是拿到这个SqlSession来增删查改
*/
factory=new SqlSessionFactoryBuilder().build(in);
}
/*实现步骤
*
* 1.把mybatis的环境搭好
* 2.数据库建表
* 3.根据表去抽象对应的java类,本列中是User
* 4.在映射文件中写sql语句
* 5.在代码里,通过Sqlsession去调用
*
*
*/
@Test
public void testFindAll(){
SqlSession sql=factory.openSession();
//根据sql语句,返回值应该是一个List所以调用selecList()
List<User> dataList=sql.selectList("pojo.User.findAll");
for(User u:dataList){
System.out.println(u.getId()+":"+u.getName()+":"+u.getAge()+":"+u.getAddress());
}
}
/*
* 实现思路:写sql语句,包括id名字自己定,指定resultType
* 2.在代码里通过API,执行你写的sql语句
* 3.用合适的数据结构去接这个结果,并且将结果打印处理
*/
@Test
public void testFindById(){
SqlSession sql=factory.openSession();
/*
* sql.selectList查询结果是一个集合
* sql.selectOne查询结果是单一
*/
User user =sql.selectOne("pojo.User.findById");
//可以在User对象里添加tostring方法,方便测试
System.out.println(user);
}
@Test
public void testUpdateById(){
SqlSession sql=factory.openSession();
sql.update("pojo.User.updateById");
//对于更新、插入、删除操作,别忘了提交事务
sql.commit();
}
/*
* 利用Mybatis实现数据的新增
*
*/
@Test
public void testInsert(){
SqlSession sql=factory.openSession();
sql.insert("pojo.User.insertInfo");
sql.commit();
}
@Test
public void testDelete(){
SqlSession sql=factory.openSession();
sql.delete("pojo.User.deleteInfo");
sql.commit();
}
/*
* 通过传入String参数实现查询
*/
@Test
public void testFindByParam(){
SqlSession sql=factory.openSession();
String id="3";
User user=sql.selectOne("pojo.User.findUserByParam",id);
System.out.println(user);
}
/*
* 通过传入map参数实现查询
*/
@Test
public void testFindByParamMap(){
SqlSession sql=factory.openSession();
Map<String, String> map=new HashMap<>();
map.put("userid", "3");
User user=sql.selectOne("pojo.User.findUserByParam",map);
System.out.println(user);
}
/**
* 把id=5的人的name改成zhang,
*/
@Test
public void testUpdateParam(){
SqlSession sql=factory.openSession();
Map<String, String> map=new HashMap<>();
map.put("userid", "5");
map.put("name", "zhang");
sql.update("pojo.User.updataNameById", map);
sql.commit();
}
//"6","Swan",20,"China"
@Test
public void testInsertParam(){
SqlSession sql=factory.openSession();
User user=new User();
user.setId("6");
user.setName("swan");
user.setAge(20);
user.setAddress("China");
sql.insert("pojo.User.insertParam", user);
sql.commit();
}
/**
* 这个例子需要掌握${}的取值方式
* 但是注意,最常用的还是#{}来做。所以具体情况是${}
*/
@Test
public void testFindByOrder(){
SqlSession sql=factory.openSession();
Map map=new HashMap<>();
map.put("param", "age");
List<User> dataList=sql.selectList("pojo.User.findByOrder", map);
for(User u:dataList){
System.out.println(u);
}
}
/**
* 针对动态sql的查询,需要掌握的是:
* 1.<if test>的使用
* 2.多余and的处理问题,常用的技巧是where 1=1
* 3.掌握mybatis<where>标签的使用,也可以实现where 1=1的效果
* 4:补充说明:<if test="minAge!=null">里,条件要怎么写,指的是传递参数的key值,本例中是map,
* 所以写的是map的key值
* 5.要明确动态sql的引入给开发人员带来的好处,那本例子来说,如果不用动态sql,需要写三个sql语句
* 分别是:select * from user_c where age> minAge and age<maxAge
* select * from user_c where age> minAge
* select * from user_c where age<maxAge
*/
@Test
public void testFindByAgeRange(){
SqlSession sql=factory.openSession();
Map<String,Integer> map=new HashMap<>();
//map.put("minAge", 60);
map.put("maxAge", 80);
List<User> dataList=sql.selectList("pojo.User.findByAgeRange", map);
for(User u:dataList){
System.out.println(u);
}
}
}
以上今天实训的大概内容