持久化和ORM
持久化:代表的数据从瞬时状态转换为持久状态的过程
ORM:对象关系映射,说白了就是程序实体与数据库二维表的字段映射,如果实体属性和表中字段一致,会自动将数据封装,如果不一致也有手动映射的方式
搭建Mybatis开发环境
步骤一:导入Mybatis依赖,数据库依赖
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
步骤二:创建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>
<!--加载配置文件-->
<properties resource="datasource.properties"></properties>
<!--defauilt代表默认情况下-->
<environments default="development">
<!--环境:可以有多套-->
<environment id="development">
<!--事务管理采用JDBC,需要程序员手动提交事务,否则数据会出现脏数据 type还可以取值为managerd 什么都不管-->
<transactionManager type="JDBC"/>
<!--数据源 type取值默认为pooled连接池,还可以采用unpooled 还有 JNDI方式-->
<dataSource type="POOLED">
<!--driver代表数据库驱动-->
<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>
<!--小配置文件映射集合,之前我们采用Dao层实现类编写SQL处理数据,学习了Mybatis就是一个Dao层接口对应一个小配置文件,将SQL放入到配置文件当中-->
<mappers>
<!--单独的小配置文件加载-->
<!--<mapper resource="com/wdksoft/dao/UserMapper.xml"/>-->
<!--小配置文件所在包名-->
<package name="com.wdksoft.dao"/>
</mappers>
</configuration>
步骤三:创建实体
步骤四:创建Dao层接口和小配置文件
public interface INewsUsersDao {
//查询所有用户信息
public List<News_Users> getAllUser() throws Exception;
}
小配置文件需要与Dao层接口相同名称,
<?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代表命名空间,指定小配置文件所关联的Dao层接口位置-->
<mapper namespace="com.wdksoft.dao.INewsUsersDao">
<!--查询所有员工记录 id代表方法名字 resultType代表返回类型 -->
<select id="getAllUser" resultType="com.wdksoft.entity.News_Users">
select * from news_users
</select>
</mapper>
默认情况下不会扫描java下的xml文件,所以解决方案为在pom.xml文件中加入节点扫描
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
步骤五:测试
//加载配置文件,以流的形式
//通过SqlSessionFactoryBuilder来获取工厂.build(is)
//通过工厂获取SqlSession
factory.openSession();
public static void main(String[] args) throws IOException {
//最终终极目的获取到SqlSession对象,因为该对象提供增伤改查方法
//步骤一:创建输入流,加载配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//步骤二:通过SqlSessionFactoryBuilder获取SqlSessionFactory工长
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(is);
//步骤三:通过工厂创建SqlSession对象
SqlSession sqlSession = build.openSession();
//步骤四:执行增删改查
List<News_Users> userList = sqlSession.selectList("getAllUser");
for(News_Users user:userList){
System.out.println(user.toString());
}
//最后一步:关闭资源
sqlSession.close();
}
别名使用
在大配置文件中,添加配置
<!--配置别名-->
<typeAliases>
<!--配置单独别名,默认规则时以实体命名-->
<!-- <typeAlias type="com.wdksoft.entity.News_Users" alias="User"/>-->
<!--全局配置采用实体命名-->
<package name="com.wdksoft.entity"/>
</typeAliases>
小配置使用实体名称即可
集成Log4j
1.将Log4j的配置文件添加到环境当中
2.需要引入log4j依赖
3.在Mybatis大配置文件中引用Log4j
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
GetMapper定位到具体接口
INewsUsersDao mapper = sqlSession.getMapper(INewsUsersDao.class);
List<News_Users> allUser = mapper.getAllUser();
for(News_Users user:allUser){
System.out.println(user.toString());
}
Mybatis添加数据
步骤一:在接口中新建方法
//添加数据
public int addUser(News_Users users) throws Exception;
步骤二:在下配置文件中加入SQL
<!--添加数据-->
<insert id="addUser">
<!--#{}可以获取到基本数据类型的变量名,也可以获取负责数据类型中的属性名-->
insert into news_users(uname,upwd,telephone,email) values(#{uname},#{upwd},#{telephone},#{email})
</insert>
步骤三:测试,手动提交
@Test
public void insert() throws Exception {
//步骤一:将配置文件以流的形式加载
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//步骤二:创建SqlSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//步骤三:获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//步骤四:获取接口类型
INewsUsersDao iNewsUsersDao = sqlSession.getMapper(INewsUsersDao.class);
News_Users users=new News_Users();
users.setUname("chaiyingjie");
users.setUpwd("pwd@123");
users.setTelephone("13888888888");
users.setEmail("123@qq.com");
int count = iNewsUsersDao.addUser(users);
if(count>0){
System.out.println("添加成功~");
}else{
System.out.println("添加失败~");
}
//增伤改需要手动提交,SqlSession底层调用的还是transaction事务对象提交事务
sqlSession.commit(true);
//步骤五:关闭资源
sqlSession.close();
}
提示:
#{}表示一个占位符号 通过#{}可以实现 preparedStatement 向占位符中设置值,自动进行 java 类型和 jdbc 类型 转换, #{}可以有效防止 sql 注入。
#{}可以接收简单类型值或 pojo 属性值。如果 parameterType 传输单个简单类型值,#{}括号中可以是 value 或其它名称。
${}表示拼接 sql 串 通过${}可以将 parameterType 传入的内容拼接在 sql 中且不进行 jdbc 类型转换,可以接 收简单类型值或 pojo 属性值,
如果 parameterType 传输单个简单类型值, {}可以接收简单 类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,可以接收简单类型值或 pojo 属性值,
如果 parameterType 传输单个简单类型值,{}括号中只能是 value。
Mybaits修改案例:
步骤一:在接口中新建方法
//修改数据
public int updateUser(News_Users users) throws Exception;
步骤二:配置小配置文件
<!--修改数据-->
<update id="updateUser">
update news_users set uname=#{uname},upwd=#{upwd} where uid=#{uid}
</update>
步骤三:测试
@Test
public void update() throws Exception {
//步骤一:将配置文件以流的形式加载
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//步骤二:创建SqlSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//步骤三:获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//步骤四:获取接口类型
INewsUsersDao iNewsUsersDao = sqlSession.getMapper(INewsUsersDao.class);
News_Users users=new News_Users();
users.setUname("yiming");
users.setUpwd("123456");
users.setUid(8);
int count = iNewsUsersDao.updateUser(users);
System.out.println(count);
//增伤改需要手动提交,SqlSession底层调用的还是transaction事务对象提交事务
sqlSession.commit(true);
//步骤五:关闭资源
sqlSession.close();
}
Mybatis删除案例
步骤一:在接口中新建方法
//删除数据
public int deleteUser(Integer uid) throws Exception;
步骤二:配置小配置文件
<!--删除数据-->
<delete id="deleteUser">
delete from news_users where uid=#{uid}
</delete>
步骤三:测试
@Test
public void delete() throws Exception {
//步骤一:将配置文件以流的形式加载
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//步骤二:创建SqlSessionFactory工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//步骤三:获取SqlSession对象
SqlSession sqlSession = factory.openSession();
//步骤四:获取接口类型
INewsUsersDao iNewsUsersDao = sqlSession.getMapper(INewsUsersDao.class);
int count = iNewsUsersDao.deleteUser(10);
System.out.println(count);
//增伤改需要手动提交,SqlSession底层调用的还是transaction事务对象提交事务
sqlSession.commit(true);
//步骤五:关闭资源
sqlSession.close();
}
添加数据返回主键三种方案:
第一种在insert标签内加入useGeneratedKeys代表开启JDBC生成主键 keyProperty代表实体主键属性名称
<insert id="addUser" useGeneratedKeys="true" keyProperty="uid">
insert into news_users(uname,upwd,telephone,email) values(#{uname},#{upwd},#{telephone},#{email})
</insert>
第二种在insert语句后查询最后一次添加数据主键的id
<selectKey keyProperty="uid" resultType="java.lang.Integer">
SELECT LAST_INSERT_ID() AS UID
</selectKey>
第三种与第二种类似,查询主键全局变量
<selectKey keyProperty="uid" resultType="java.lang.Integer">
SELECT @@IDENTITY AS UID
</selectKey>
自动映射和ResultMap的使用
Mybatis默认是自动映射的,只要实体的属性和数据库字段一致就可以自动映射
当实体和数据库二维表不一致的情况下,或者是在关联查询的场景下我们使用resultMap
<!--resultMap结果映射,在多表连接查询时,在实体与数据库二维表字段不一致时 id代表resultMap结果的唯一标识 type代表实体的类型-->
<resultMap id="userMap" type="News_Users">
<!--result标签代表普通字段 property代表的是实体中的属性 column代表数据库二维表中字段-->
<result property="phone" column="telephone"/>
</resultMap>
<select id="getAllUser" resultMap="userMap">
select * from news_users
</select>
取消全局映射:在Mybatis大配置文件中settings节点下加入autoMappingBehavior属性 属性值默认取值为PARTIAL代表只映射自己,在关联查询时不会映射其他实体数据
NONE代表取消映射 FULL所有都能映射
取消局部映射,在小配置文件的resultMap节点中加入autoMapping属性值为false,默认为true,关闭了映射之后所有的字段如果没有在resultMap手动映射,则取值为null
MybatisUtil工具类提炼,核心思想,利用静态代码块先创建出工厂,然后再获取SqlSession的方法内通过工厂获取对象
public class MybatisUtil {
static String resourcePath="mybatis-config.xml";
static InputStream is = null;
static SqlSessionFactory factory = null;
static {
try {
is = Resources.getResourceAsStream(resourcePath);
//获取工厂
factory = new SqlSessionFactoryBuilder().build(is);
} catch (IOException e) {
e.printStackTrace();
}
}
//获取SqlSession对象
public static SqlSession getSqlSession(){
return factory.openSession();
}
//关闭SqlSession对象
public static void closeSqlSession(SqlSession session){
session.close();
}
}
调用测试:
public static void main(String[] args) throws Exception {
SqlSession sqlSession = MybatisUtil.getSqlSession();
//步骤四:执行增删改查
INewsUsersDao mapper = sqlSession.getMapper(INewsUsersDao.class);
List<News_Users> allUser = mapper.getAllUser();
for(News_Users user:allUser){
System.out.println(user.toString());
}
MybatisUtil.closeSqlSession(sqlSession);
}